From 06c30ea209f7a6a683a33bef737559a0631a5dd4 Mon Sep 17 00:00:00 2001 From: Zachary Burnett Date: Mon, 14 Jun 2021 11:46:58 -0400 Subject: [PATCH] add python script for ensemble vortex generation (#21) * add python script for ensemble vortex generation * Fix code style issues with oitnb * write perturber class * Fix code style issues with oitnb * store variable information in classes * add random test (ignore until stochastic) * Fix code style issues with oitnb * use `pint` for unit conversion and storage (#22) * use `pint` for unit conversion and storage * move perturbations into class implementations * Fix code style issues with oitnb * rename validation time property * re-enable test with deterministic run * add windows to tests * remove environment.yml * use CRS and transformer from `pyproj` * update reference files * Removing dependence on adcircpy (#23) * Removing dependence on adcircpy - [for now] copying over besttrackforcing from adcircpy into tropicalcyclone.atcf module - removed NWS, BLAdh, geo, and time interval properties as they are related to adcirc inputs - add test/output folders to .gitignore * adding some help info for atcf tracks and adding __init__.py to subdirectories to find them * Fix code style issues with oitnb * remove unused imports * refactor / fix plotting * Fix code style issues with oitnb * use inverse geodetic calc to get distance and bearing * update dependencies * update dependencies * explicitly add GDAL * remove GDAL * Fix code style issues with oitnb * update reference files * fix configuration caching * Fix code style issues with oitnb Co-authored-by: William Pringle Co-authored-by: Lint Action --- .github/workflows/tests.yml | 4 +- .gitignore | 1 + ensembleperturbation/parsing/adcirc.py | 4 +- ensembleperturbation/parsing/comparison.py | 8 +- .../perturbation/__init__.py | 0 .../perturbation/make_storm_ensemble.py | 990 ++++++++++++++++++ ensembleperturbation/plotting.py | 308 +++--- .../tropicalcyclone/__init__.py | 0 ensembleperturbation/tropicalcyclone/atcf.py | 726 +++++++++++++ ensembleperturbation/utilities.py | 5 + environment.yml | 21 - setup.py | 5 +- tests/__init__.py | 48 + .../test_besttrack_ensemble/along_track_1.22 | 70 ++ .../test_besttrack_ensemble/along_track_2.22 | 70 ++ .../test_besttrack_ensemble/along_track_3.22 | 70 ++ .../test_besttrack_ensemble/cross_track_1.22 | 70 ++ .../test_besttrack_ensemble/cross_track_2.22 | 70 ++ .../test_besttrack_ensemble/cross_track_3.22 | 70 ++ .../max_sustained_wind_speed_1.22 | 70 ++ .../max_sustained_wind_speed_2.22 | 70 ++ .../max_sustained_wind_speed_3.22 | 70 ++ .../test_besttrack_ensemble/original.22 | 70 ++ .../radius_of_maximum_winds_1.22 | 70 ++ .../radius_of_maximum_winds_2.22 | 70 ++ .../radius_of_maximum_winds_3.22 | 70 ++ .../test_parse_adcirc_output}/fort.14 | 0 .../test_parse_adcirc_output}/fort.15 | 0 .../test_parse_adcirc_output}/fort.16 | 0 .../test_parse_adcirc_output/fort.33 | 0 .../test_parse_adcirc_output}/fort.63.nc | Bin .../test_parse_adcirc_output}/fort.64.nc | Bin .../test_parse_adcirc_output}/fort.67.nc | Bin .../test_parse_adcirc_output}/fort.68.nc | Bin .../test_parse_adcirc_output}/maxele.63.nc | Bin .../test_parse_adcirc_output}/maxvel.63.nc | Bin tests/test_base.py | 2 - tests/test_besttrack_ensemble.py | 32 + tests/test_parser.py | 21 +- 39 files changed, 2915 insertions(+), 170 deletions(-) rename tests/data/Shinnecock_Inlet_NetCDF_output/fort.33 => ensembleperturbation/perturbation/__init__.py (100%) create mode 100644 ensembleperturbation/perturbation/make_storm_ensemble.py create mode 100644 ensembleperturbation/tropicalcyclone/__init__.py create mode 100644 ensembleperturbation/tropicalcyclone/atcf.py delete mode 100644 environment.yml create mode 100644 tests/__init__.py create mode 100644 tests/data/reference/test_besttrack_ensemble/along_track_1.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/along_track_2.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/along_track_3.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/cross_track_1.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/cross_track_2.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/cross_track_3.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_1.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_2.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_3.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/original.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_1.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_2.22 create mode 100644 tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_3.22 rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/fort.14 (100%) rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/fort.15 (100%) rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/fort.16 (100%) create mode 100644 tests/data/reference/test_parse_adcirc_output/fort.33 rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/fort.63.nc (100%) rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/fort.64.nc (100%) rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/fort.67.nc (100%) rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/fort.68.nc (100%) rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/maxele.63.nc (100%) rename tests/data/{Shinnecock_Inlet_NetCDF_output => reference/test_parse_adcirc_output}/maxvel.63.nc (100%) delete mode 100644 tests/test_base.py create mode 100644 tests/test_besttrack_ensemble.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 29ed72f5..145914e3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: true matrix: - os: [ ubuntu-latest ] + os: [ ubuntu-latest, windows-latest ] python-version: [ 3.8, 3.9 ] steps: - name: Checkout repository @@ -41,7 +41,7 @@ jobs: # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Run tests with coverage - run: pytest --cov=ensembleperturbation --numprocesses auto --ignore=tests/test_parser.py + run: pytest --cov=ensembleperturbation --numprocesses auto - name: Upload coverage to Codecov if: matrix.python-version == 3.9 uses: codecov/codecov-action@v1 diff --git a/.gitignore b/.gitignore index 4881cbbd..ca86d6cb 100644 --- a/.gitignore +++ b/.gitignore @@ -141,3 +141,4 @@ cython_debug/ .idea/ /examples/data/* +/tests/data/output diff --git a/ensembleperturbation/parsing/adcirc.py b/ensembleperturbation/parsing/adcirc.py index eb52433a..e7229ea3 100644 --- a/ensembleperturbation/parsing/adcirc.py +++ b/ensembleperturbation/parsing/adcirc.py @@ -10,8 +10,8 @@ from pandas import DataFrame from shapely.geometry import Point -from ..utilities import get_logger -from .utilities import decode_time +from ensembleperturbation.parsing.utilities import decode_time +from ensembleperturbation.utilities import get_logger LOGGER = get_logger('parsing.adcirc') diff --git a/ensembleperturbation/parsing/comparison.py b/ensembleperturbation/parsing/comparison.py index 724f343c..1942ce32 100644 --- a/ensembleperturbation/parsing/comparison.py +++ b/ensembleperturbation/parsing/comparison.py @@ -12,8 +12,12 @@ from pyproj import CRS, Geod import shapely -from ..utilities import get_logger -from .adcirc import fort61_stations_zeta, fort62_stations_uv, parse_adcirc_outputs +from ensembleperturbation.parsing.adcirc import ( + fort61_stations_zeta, + fort62_stations_uv, + parse_adcirc_outputs, +) +from ensembleperturbation.utilities import get_logger LOGGER = get_logger('parsing.comparison') diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.33 b/ensembleperturbation/perturbation/__init__.py similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.33 rename to ensembleperturbation/perturbation/__init__.py diff --git a/ensembleperturbation/perturbation/make_storm_ensemble.py b/ensembleperturbation/perturbation/make_storm_ensemble.py new file mode 100644 index 00000000..38491807 --- /dev/null +++ b/ensembleperturbation/perturbation/make_storm_ensemble.py @@ -0,0 +1,990 @@ +#! /usr/bin/env python3 +""" +Script to: +(1) extract an ATCF best track dataset; +(2) randomly perturb different parameters (e.g., intensity, +size, track coordinates) to generate an ensemble; and +(3) write out each ensemble member to the fort.22 ATCF +tropical cyclone vortex format file. + +Variables that can be perturbed: +- "max_sustained_wind_speed" (Vmax) is made weaker/stronger + based on random gaussian distribution with sigma scaled by + historical mean absolute errors. central_pressure (pc) + is then changed proportionally based on Holland B + +- "radius_of_maximum_winds" (Rmax) is made small/larger + based on random number in a range bounded by the 15th and + 85th percentile CDF of historical forecast errors. + +- "along_track" variable is used to offset the coordinate of + the tropical cyclone center at each forecast time forward or + backward along the given track based on a random gaussian + distribution with sigma scaled by historical mean absolute + errors. + +- "cross_track" variable is used to offset the coordinate of + the tropical cyclone center at each forecast time a certain + perpendicular distance from the given track based on a + random gaussian distribution with sigma scaled by historical + mean absolute errors. + +By William Pringle, Argonne National Laboratory, Mar-May 2021 + Zach Burnett, NOS/NOAA + Saeed Moghimi, NOS/NOAA +""" + +from abc import ABC +from argparse import ArgumentParser +from datetime import datetime, timedelta +from enum import Enum +from math import exp, inf, sqrt +from os import PathLike +from pathlib import Path +from random import gauss, random +from typing import Union + +from dateutil.parser import parse as parse_date +import numpy +from numpy import floor, interp, sign +from pandas import DataFrame, Series +import pint +from pint_pandas import PintType +from pyproj import CRS, Transformer +from pyproj.enums import TransformDirection +from shapely.geometry import LineString + +from ensembleperturbation.tropicalcyclone.atcf import BestTrackForcing +from ensembleperturbation.utilities import units + +AIR_DENSITY = 1.15 * units.kilogram / units.meters ** 3 + +E1 = exp(1.0) # e + +# Index of absolute errors (forecast times [hrs)] +ERROR_INDICES_NO_60H = [0, 12, 24, 36, 48, 72, 96, 120] # no 60-hr data +ERROR_INDICES_60HR = [0, 12, 24, 36, 48, 60, 72, 96, 120] # has 60-hr data (for Rmax) + + +class PerturbationType(Enum): + GAUSSIAN = 'gaussian' + LINEAR = 'linear' + + +class BestTrackPerturbedVariable(ABC): + name: str + perturbation_type: PerturbationType + + def __init__( + self, + lower_bound: float = None, + upper_bound: float = None, + historical_forecast_errors: {str: DataFrame} = None, + default: float = None, + unit: pint.Unit = None, + ): + self.__unit = None + self.__lower_bound = None + self.__upper_bound = None + self.__historical_forecast_errors = None + self.__default = None + + self.unit = unit + + self.lower_bound = lower_bound + self.upper_bound = upper_bound + self.historical_forecast_errors = historical_forecast_errors + self.default = default + + @property + def unit(self) -> pint.Unit: + return self.__unit + + @unit.setter + def unit(self, unit: Union[str, pint.Unit]): + if not isinstance(unit, pint.Unit): + if unit is None: + unit = '' + unit = units.Unit(unit) + self.__unit = unit + + @property + def lower_bound(self) -> pint.Quantity: + if self.__lower_bound.units != self.unit: + self.__lower_bound.ito(self.unit) + return self.__lower_bound + + @lower_bound.setter + def lower_bound(self, lower_bound: float): + if isinstance(lower_bound, pint.Quantity): + if lower_bound.units != self.unit: + lower_bound = lower_bound.to(self.unit) + elif lower_bound is not None: + lower_bound *= self.unit + self.__lower_bound = lower_bound + + @property + def upper_bound(self) -> pint.Quantity: + if self.__upper_bound.units != self.unit: + self.__upper_bound.ito(self.unit) + return self.__upper_bound + + @upper_bound.setter + def upper_bound(self, upper_bound: float): + if isinstance(upper_bound, pint.Quantity): + if upper_bound.units != self.unit: + upper_bound = upper_bound.to(self.unit) + elif upper_bound is not None: + upper_bound *= self.unit + self.__upper_bound = upper_bound + + @property + def historical_forecast_errors(self) -> {str: DataFrame}: + for classification, dataframe in self.__historical_forecast_errors.items(): + for column in dataframe: + pint_type = PintType(self.unit) + if ( + not isinstance(dataframe[column].dtype, PintType) + or dataframe[column].dtype != pint_type + ): + if ( + isinstance(dataframe[column].dtype, PintType) + and dataframe[column].dtype != pint_type + ): + dataframe[column].pint.ito(self.unit) + dataframe[column].astype(pint_type, copy=False) + return self.__historical_forecast_errors + + @historical_forecast_errors.setter + def historical_forecast_errors(self, historical_forecast_errors: {str: DataFrame}): + for classification, dataframe in historical_forecast_errors.items(): + for column in dataframe: + pint_type = PintType(self.unit) + if ( + not isinstance(dataframe[column].dtype, PintType) + or dataframe[column].dtype != pint_type + ): + if ( + isinstance(dataframe[column].dtype, PintType) + and dataframe[column].dtype != pint_type + ): + dataframe[column].pint.ito(self.unit) + dataframe[column].astype(pint_type, copy=False) + self.__historical_forecast_errors = historical_forecast_errors + + @property + def default(self) -> pint.Quantity: + if self.__default is not None and self.__default.units != self.unit: + self.__default.ito(self.unit) + return self.__default + + @default.setter + def default(self, default: float): + if isinstance(default, pint.Quantity): + if default.units != self.unit: + default = default.to(self.unit) + elif default is not None: + default *= self.unit + self.__default = default + + def perturb( + self, besttrack_dataframe: DataFrame, values: [float], times: [datetime], + ) -> DataFrame: + """ + perturb the variable within physical bounds + + :param besttrack_dataframe: ATCF dataframe containing track info + :param values: values for each forecast time (VT) + :param times: forecast times (VT) + :return: updated ATCF dataframe with perturbed values + """ + + all_values = besttrack_dataframe[self.name].values + values + besttrack_dataframe[self.name] = [ + min(self.upper_bound, max(value, self.lower_bound)).magnitude + for value in all_values + ] * self.unit + + return besttrack_dataframe + + def __repr__(self) -> str: + return f'{self.__class__.__name__}(lower_bound={repr(self.lower_bound)}, upper_bound={repr(self.upper_bound)}, historical_forecast_errors={repr(self.historical_forecast_errors)}, default={repr(self.default)}, unit={repr(self.unit)})' + + +class CentralPressure(BestTrackPerturbedVariable): + name = 'central_pressure' + + +class BackgroundPressure(BestTrackPerturbedVariable): + name = 'background_pressure' + + def __init__(self): + super().__init__( + default=1013.0, unit=units.millibar, + ) + + +class MaximumSustainedWindSpeed(BestTrackPerturbedVariable): + name = 'max_sustained_wind_speed' + perturbation_type = PerturbationType.GAUSSIAN + + def __init__(self): + super().__init__( + lower_bound=25, + upper_bound=165, + historical_forecast_errors={ + '<50kt': DataFrame( + {'mean error [kt]': [1.45, 4.01, 6.17, 8.42, 10.46, 14.28, 18.26, 19.91]}, + index=ERROR_INDICES_NO_60H, + ), + '50-95kt': DataFrame( + {'mean error [kt]': [2.26, 5.75, 8.54, 9.97, 11.28, 13.11, 13.46, 12.62]}, + index=ERROR_INDICES_NO_60H, + ), + '>95kt': DataFrame( + { + 'mean error [kt]': [ + 2.80, + 7.94, + 11.53, + 13.27, + 12.66, + 13.41, + 13.46, + 13.55, + ] + }, + index=ERROR_INDICES_NO_60H, + ), + }, + unit=units.knot, + ) + + +class RadiusOfMaximumWinds(BestTrackPerturbedVariable): + name = 'radius_of_maximum_winds' + perturbation_type = PerturbationType.LINEAR + + def __init__(self): + super().__init__( + lower_bound=5, + upper_bound=200, + historical_forecast_errors={ + '<15sm': DataFrame( + { + 'minimum error [nm]': Series( + [ + 0.0, + -13.82, + -19.67, + -21.37, + -26.31, + -32.71, + -39.12, + -46.80, + -52.68, + ], + dtype=PintType(units.us_statute_mile), + ), + 'maximum error [nm]': Series( + [0.0, 1.27, 0.22, 1.02, 0.00, -2.59, -5.18, -7.15, -12.91], + dtype=PintType(units.us_statute_mile), + ), + }, + index=ERROR_INDICES_60HR, + ), + '15-25sm': DataFrame( + { + 'minimum error [nm]': Series( + [ + 0.0, + -10.47, + -14.54, + -20.35, + -23.88, + -21.78, + -19.68, + -24.24, + -28.30, + ], + dtype=PintType(units.us_statute_mile), + ), + 'maximum error [nm]': Series( + [0.0, 4.17, 6.70, 6.13, 6.54, 6.93, 7.32, 9.33, 8.03], + dtype=PintType(units.us_statute_mile), + ), + }, + index=ERROR_INDICES_60HR, + ), + '25-35sm': DataFrame( + { + 'minimum error [nm]': Series( + [0.0, -8.57, -13.41, -10.87, -9.26, -9.34, -9.42, -7.41, -7.40], + dtype=PintType(units.us_statute_mile), + ), + 'maximum error [nm]': Series( + [0.0, 8.21, 10.62, 13.93, 15.62, 16.04, 16.46, 16.51, 16.70], + dtype=PintType(units.us_statute_mile), + ), + }, + index=ERROR_INDICES_60HR, + ), + '35-45sm': DataFrame( + { + 'minimum error [nm]': Series( + [0.0, -10.66, -7.64, -5.68, -3.25, -1.72, -0.19, 3.65, 2.59], + index=ERROR_INDICES_60HR, + dtype=PintType(units.us_statute_mile), + ), + 'maximum error [nm]': Series( + [0.0, 14.77, 17.85, 22.07, 27.60, 27.08, 26.56, 26.80, 28.30], + index=ERROR_INDICES_60HR, + dtype=PintType(units.us_statute_mile), + ), + }, + ), + '>45sm': DataFrame( + { + 'minimum error [nm]': Series( + [0.0, -15.36, -10.37, 3.14, 12.10, 12.21, 12.33, 6.66, 7.19], + dtype=PintType(units.us_statute_mile), + ), + 'maximum error [nm]': Series( + [0.0, 21.43, 29.96, 37.22, 39.27, 39.10, 38.93, 34.40, 35.93], + dtype=PintType(units.us_statute_mile), + ), + }, + index=ERROR_INDICES_60HR, + ), + }, + unit=units.nautical_mile, + ) + + +class CrossTrack(BestTrackPerturbedVariable): + name = 'cross_track' + perturbation_type = PerturbationType.GAUSSIAN + + def __init__(self): + super().__init__( + lower_bound=-inf, + upper_bound=+inf, + historical_forecast_errors={ + '<50kt': DataFrame( + {'mean error [nm]': [1.45, 4.01, 6.17, 8.42, 10.46, 14.28, 18.26, 19.91]}, + index=ERROR_INDICES_NO_60H, + ), + '50-95kt': DataFrame( + {'mean error [nm]': [2.26, 5.75, 8.54, 9.97, 11.28, 13.11, 13.46, 12.62]}, + index=ERROR_INDICES_NO_60H, + ), + '>95kt': DataFrame( + { + 'mean error [nm]': [ + 2.80, + 7.94, + 11.53, + 13.27, + 12.66, + 13.41, + 13.46, + 13.55, + ] + }, + index=ERROR_INDICES_NO_60H, + ), + }, + unit=units.nautical_mile, + ) + + def perturb( + self, besttrack_dataframe: DataFrame, values: [float], times: [datetime], + ) -> DataFrame: + """ + offset_track(df_,VT,cross_track_errors) + - Offsets points by a given perpendicular error/distance from the original track + + :param besttrack_dataframe: ATCF dataframe containing track info + :param values: cross-track errors [nm] for each forecast time (VT) + :param times: forecast times (VT) + :return: updated ATCF dataframe with different longitude latitude locations based on perpendicular offsets set by the cross_track_errors + """ + + # Get the coordinates of the track + track_coords = besttrack_dataframe[['longitude', 'latitude']].values.tolist() + + # get the utm projection for the reference coordinate + utm_crs = utm_crs_from_longitude(numpy.mean(track_coords[0])) + wgs84 = CRS.from_epsg(4326) + transformer = Transformer.from_crs(wgs84, utm_crs) + + times = (times / timedelta(hours=1)).values * units.hours + + # loop over all coordinates + new_coordinates = [] + for track_coord_index in range(0, len(track_coords)): + # get the current cross_track_error + cross_track_error = values[track_coord_index].to(units.meter) + + # get the location of the original reference coordinate + x_ref, y_ref = ( + transformer.transform( + track_coords[track_coord_index][0], track_coords[track_coord_index][1], + ) + * units.meter + ) + + # get the index of the previous forecasted coordinate + idx_p = track_coord_index - 1 + while idx_p >= 0: + if times[idx_p] < times[track_coord_index]: + break + idx_p = idx_p - 1 + if idx_p < 0: # beginning of track + idx_p = track_coord_index + + # get previous projected coordinate + x_p, y_p = ( + transformer.transform(track_coords[idx_p][0], track_coords[idx_p][1]) + * units.meter + ) + + # get the perpendicular offset based on the line connecting from the previous coordinate to the current coordinate + dx_p, dy_p = get_offset(x_p, y_p, x_ref, y_ref, cross_track_error) + + # get the index of the next forecasted coordinate + idx_n = track_coord_index + 1 + while idx_n < len(track_coords): + if times[idx_n] > times[track_coord_index]: + break + idx_n = idx_n + 1 + if idx_n == len(track_coords): # end of track + idx_n = track_coord_index + + # get previous projected coordinate + x_n, y_n = ( + transformer.transform(track_coords[idx_n][0], track_coords[idx_n][1]) + * units.meter + ) + + # get the perpendicular offset based on the line connecting from the current coordinate to the next coordinate + dx_n, dy_n = get_offset(x_ref, y_ref, x_n, y_n, cross_track_error) + + # get the perpendicular offset based on the average of the forward and backward piecewise track lines adjusted so that the distance matches the actual cross_error + dx = 0.5 * (dx_p + dx_n) + dy = 0.5 * (dy_p + dy_n) + alpha = (abs(cross_track_error) / numpy.sqrt(dx ** 2 + dy ** 2)).magnitude + + # compute the next point and retrieve back the lat-lon geographic coordinate + new_coordinates.append( + transformer.transform( + (x_ref + alpha * dx).magnitude, + (y_ref + alpha * dy).magnitude, + direction=TransformDirection.INVERSE, + ) + ) + + degree = PintType(units.degree) + besttrack_dataframe['longitude'], besttrack_dataframe['latitude'] = zip( + *new_coordinates + ) + besttrack_dataframe['longitude'] = besttrack_dataframe['longitude'].astype( + degree, copy=False + ) + besttrack_dataframe['latitude'] = besttrack_dataframe['latitude'].astype( + degree, copy=False + ) + + return besttrack_dataframe + + +class AlongTrack(BestTrackPerturbedVariable): + name = 'along_track' + perturbation_type = PerturbationType.GAUSSIAN + + def __init__(self): + super().__init__( + lower_bound=-inf, + upper_bound=+inf, + historical_forecast_errors={ + '<50kt': DataFrame( + {'mean error [nm]': [1.45, 4.01, 6.17, 8.42, 10.46, 14.28, 18.26, 19.91]}, + index=ERROR_INDICES_NO_60H, + ), + '50-95kt': DataFrame( + {'mean error [nm]': [2.26, 5.75, 8.54, 9.97, 11.28, 13.11, 13.46, 12.62]}, + index=ERROR_INDICES_NO_60H, + ), + '>95kt': DataFrame( + { + 'mean error [nm]': [ + 2.80, + 7.94, + 11.53, + 13.27, + 12.66, + 13.41, + 13.46, + 13.55, + ] + }, + index=ERROR_INDICES_NO_60H, + ), + }, + unit=units.nautical_mile, + ) + + def perturb( + self, besttrack_dataframe: DataFrame, values: [float], times: [datetime], + ) -> DataFrame: + """ + interpolate_along_track(df_,VT,along_track_errros) + Offsets points by a given error/distance by interpolating along the track + + :param besttrack_dataframe: ATCF dataframe containing track info + :param values: along-track errors for each forecast time (VT) + :param times: forecast timed (VT) + :return: updated ATCF dataframe with different longitude latitude locations based on interpolated errors along track + """ + + max_interpolated_points = 5 # maximum number of pts along line for each interpolation + + # Get the coordinates of the track + coordinates = besttrack_dataframe[['longitude', 'latitude']].values + + # get the utm projection for the reference coordinate + utm_crs = utm_crs_from_longitude(numpy.mean(coordinates[:, 0])) + wgs84 = CRS.from_epsg(4326) + transformer = Transformer.from_crs(wgs84, utm_crs) + + hours = (times / timedelta(hours=1)).values + + unique_points, unique_indices = numpy.unique(coordinates, axis=0, return_index=True) + unique_points = unique_points[numpy.argsort(unique_indices)] + unique_times, unique_indices = numpy.unique(hours, axis=0, return_index=True) + unique_times = unique_times[numpy.argsort(unique_indices)] + + # Extrapolating the track for negative errors at beginning and positive errors at end of track + previous_diffs = numpy.flip( + numpy.repeat( + [unique_points[1] - unique_points[0]], max_interpolated_points, axis=0 + ) + * numpy.expand_dims(numpy.arange(1, max_interpolated_points + 1), axis=1) + ) + after_diffs = numpy.repeat( + [unique_points[-1] - unique_points[-2]], max_interpolated_points, axis=0 + ) * numpy.expand_dims(numpy.arange(1, max_interpolated_points + 1), axis=1) + coordinates = numpy.concatenate( + [coordinates[0] - previous_diffs, coordinates, coordinates[-1] + after_diffs,] + ) + + # adding pseudo-VT times to the ends + previous_diffs = numpy.flip( + numpy.repeat([unique_times[1] - unique_times[0]], max_interpolated_points) + * numpy.arange(1, max_interpolated_points + 1) + ) + after_diffs = numpy.repeat( + [unique_times[-1] - unique_times[-2]], max_interpolated_points + ) * numpy.arange(1, max_interpolated_points + 1) + hours = numpy.concatenate((hours[0] - previous_diffs, hours, hours[-1] + after_diffs)) + + # loop over all coordinates + new_coordinates = [] + for index in range(len(values)): + along_error = values[index - 1].to(units.meter) + along_sign = int(sign(along_error)) + + projected_points = [] + track_index = index + while len(projected_points) < max_interpolated_points: + if track_index < 0 or track_index > len(coordinates) - 1: + break # reached end of line + if ( + track_index == index + or hours[track_index] != hours[track_index - along_sign] + ): + # get the x,y utm coordinate for this line string + projected_points.append( + transformer.transform( + coordinates[track_index][0], coordinates[track_index][1], + ) + ) + track_index = track_index + along_sign + + # make the temporary line segment + line_segment = LineString(projected_points) + + # interpolate a distance "along_error" along the line + projected_coordinate = line_segment.interpolate(abs(along_error.magnitude)) + + # get back lat-lon + new_coordinates.append( + transformer.transform( + projected_coordinate.coords[0][0], + projected_coordinate.coords[0][1], + direction=TransformDirection.INVERSE, + ) + ) + + degree = PintType(units.degree) + besttrack_dataframe['longitude'], besttrack_dataframe['latitude'] = zip( + *new_coordinates + ) + besttrack_dataframe['longitude'] = besttrack_dataframe['longitude'].astype( + degree, copy=False + ) + besttrack_dataframe['latitude'] = besttrack_dataframe['latitude'].astype( + degree, copy=False + ) + + return besttrack_dataframe + + +class BestTrackPerturber: + def __init__( + self, storm: str, start_date: datetime = None, end_date: datetime = None, + ): + """ + build storm perturber + + :param storm: NHC storm code, for instance `al062018` + :param start_date: start time of ensemble + :param end_date: end time of ensemble + """ + + self.storm = storm + self.start_date = start_date + self.end_date = end_date + + self.__forcing = None + self.__previous_configuration = None + + @property + def storm(self) -> str: + return self.__storm + + @storm.setter + def storm(self, storm: str): + self.__storm = storm + + @property + def start_date(self) -> datetime: + return self.__start_date + + @start_date.setter + def start_date(self, start_date: datetime): + if start_date is not None and not isinstance(start_date, datetime): + start_date = parse_date(start_date) + self.__start_date = start_date + + @property + def end_date(self) -> datetime: + return self.__end_date + + @end_date.setter + def end_date(self, end_date: datetime): + if end_date is not None and not isinstance(end_date, datetime): + end_date = parse_date(end_date) + self.__end_date = end_date + + @property + def forcing(self) -> BestTrackForcing: + + configuration = { + 'storm': self.storm, + 'start_date': self.start_date, + 'end_date': self.end_date, + } + + if configuration != self.__previous_configuration: + self.__forcing = BestTrackForcing(**configuration) + self.__previous_configuration = configuration + + self.__storm = self.__forcing.storm_id + + return self.__forcing + + def write( + self, + number_of_perturbations: int, + variables: [BestTrackPerturbedVariable], + directory: PathLike = None, + alpha: float = None, + ): + """ + :param number_of_perturbations: number of perturbations to create + :param variables: list of variable names, any combination of `["max_sustained_wind_speed", "radius_of_maximum_winds", "along_track", "cross_track"]` + :param directory: directory to which to write + :param alpha: value between [0, 1) with which to multiply error for perturbation; leave None for random + """ + + if number_of_perturbations is not None: + number_of_perturbations = int(number_of_perturbations) + + for index, variable in enumerate(variables): + if isinstance(variable, type): + variables[index] = variable() + + if directory is None: + directory = Path.cwd() + elif not isinstance(directory, Path): + directory = Path(directory) + + # write out original fort.22 + self.forcing.write(directory / 'original.22', overwrite=True) + + # Get the initial intensity and size + storm_strength = storm_intensity_class( + self.compute_initial(MaximumSustainedWindSpeed.name), + ) + storm_size = storm_size_class(self.compute_initial(RadiusOfMaximumWinds.name)) + + print(f'Initial storm strength: {storm_strength}') + print(f'Initial storm size: {storm_size}') + + # extracting original dataframe + original_data = self.forcing.data + + # add units to data frame + original_data = original_data.astype( + { + variable.name: PintType(variable.unit) + for variable in variables + if variable.name in original_data + }, + copy=False, + ) + + # for each variable, perturb the values and write each to a new `fort.22` + for variable in variables: + print(f'writing perturbations for "{variable.name}"') + # Make the random pertubations based on the historical forecast errors + # Interpolate from the given VT to the storm_VT + if isinstance(variable, RadiusOfMaximumWinds): + storm_classification = storm_size + else: + storm_classification = storm_strength + + historical_forecast_errors = variable.historical_forecast_errors[ + storm_classification + ] + for column in historical_forecast_errors: + if isinstance(historical_forecast_errors[column].dtype, PintType): + historical_forecast_errors[column] = historical_forecast_errors[ + column + ].pint.magnitude + + xp = historical_forecast_errors.index + fp = historical_forecast_errors.values + base_errors = [ + interp(self.validation_times / timedelta(hours=1), xp, fp[:, ncol]) + for ncol in range(len(fp[0])) + ] + + for perturbation_index in range(1, number_of_perturbations + 1): + # make a deepcopy to preserve the original dataframe + perturbed_data = original_data.copy(deep=True) + perturbed_data = perturbed_data.astype( + { + variable.name: PintType(variable.unit) + for variable in variables + if variable.name in original_data + }, + copy=False, + ) + + # get the random perturbation sample + if variable.perturbation_type == PerturbationType.GAUSSIAN: + if alpha is None: + alpha = gauss(0, 1) / 0.7979 + + print(f'Random gaussian variable = {alpha}') + perturbation = base_errors[0] * alpha + if variable.unit is not None and variable.unit != units.dimensionless: + perturbation *= variable.unit + + # add the error to the variable with bounds to some physical constraints + perturbed_data = variable.perturb( + perturbed_data, values=perturbation, times=self.validation_times, + ) + elif variable.perturbation_type == PerturbationType.LINEAR: + if alpha is None: + alpha = random() + + print(f'Random number in [0,1) = {alpha}') + perturbation = -(base_errors[0] * (1.0 - alpha) + base_errors[1] * alpha) + if variable.unit is not None and variable.unit != units.dimensionless: + perturbation *= variable.unit + + # subtract the error from the variable with physical constraint bounds + perturbed_data = variable.perturb( + perturbed_data, values=perturbation, times=self.validation_times, + ) + + if isinstance(variable, MaximumSustainedWindSpeed): + # In case of Vmax need to change the central pressure incongruence with it (obeying Holland B relationship) + perturbed_data[CentralPressure.name] = self.compute_pc_from_Vmax( + perturbed_data + ) + + # remove units from data frame + for column in perturbed_data: + if isinstance(perturbed_data[column].dtype, PintType): + perturbed_data[column] = perturbed_data[column].pint.magnitude + + # reset the dataframe + self.forcing._df = perturbed_data + + # write out the modified fort.22 + self.forcing.write( + directory / f'{variable.name}_{perturbation_index}.22', overwrite=True, + ) + + @property + def validation_times(self) -> [timedelta]: + """ get the validation time of storm """ + return self.forcing.datetime - self.forcing.start_date + + def compute_initial(self, var: str) -> float: + """ the initial value of the input variable var (Vmax or Rmax) """ + return self.forcing.data[var].iloc[0] + + @property + def holland_B(self) -> float: + """ Compute Holland B at each time snap """ + dataframe = self.forcing.data + Vmax = dataframe[MaximumSustainedWindSpeed.name] + DelP = dataframe[BackgroundPressure.name] - dataframe[CentralPressure.name] + B = Vmax * Vmax * AIR_DENSITY * E1 / DelP + return B + + def compute_pc_from_Vmax(self, dataframe: DataFrame) -> float: + """ Compute central pressure from Vmax based on Holland B """ + Vmax = dataframe[MaximumSustainedWindSpeed.name] + DelP = Vmax ** 2 * AIR_DENSITY * E1 / self.holland_B + pc = dataframe[BackgroundPressure.name] - DelP + return pc + + +def storm_intensity_class(max_sustained_wind_speed: float) -> str: + """ + Category for Vmax based intensity + + :param max_sustained_wind_speed: maximum sustained wind speed, in knots + :return: intensity classification + """ + + if not isinstance(max_sustained_wind_speed, pint.Quantity): + max_sustained_wind_speed *= units.knot + + if max_sustained_wind_speed < 50 * units.knot: + return '<50kt' # weak + elif max_sustained_wind_speed <= 95 * units.knot: + return '50-95kt' # medium + else: + return '>95kt' # strong + + +def storm_size_class(radius_of_maximum_winds: float) -> str: + """ + Category for Rmax based size + + :param radius_of_maximum_winds: radius of maximum winds, in nautical miles + :return: size classification + """ + + if not isinstance(radius_of_maximum_winds, pint.Quantity): + radius_of_maximum_winds *= units.nautical_mile + + if radius_of_maximum_winds < 15 * units.us_statute_mile: + return '<15sm' # very small + elif radius_of_maximum_winds < 25 * units.us_statute_mile: + return '15-25sm' # small + elif radius_of_maximum_winds < 35 * units.us_statute_mile: + return '25-35sm' # medium + elif radius_of_maximum_winds <= 45 * units.us_statute_mile: + return '35-45sm' # large + else: + return '>45sm' # very large + + +def utm_crs_from_longitude(longitude: float) -> CRS: + """ + utm_from_lon - UTM zone for a longitude + Not right for some polar regions (Norway, Svalbard, Antartica) + + :param longitude: longitude + :return: coordinate reference system + """ + + return CRS.from_epsg(32600 + int(floor((longitude + 180) / 6) + 1)) + + +def get_offset(x1: float, y1: float, x2: float, y2: float, d: float) -> (float, float): + """ + get_offset(x1,y1,x2,y2,d) + - get the perpendicular offset to the line (x1,y1) -> (x2,y2) by a distance of d + """ + + if x1 == x2: + dx = d + dy = 0 + elif y1 == y2: + dy = d + dx = 0 + else: + # if z is the distance to your parallel curve, + # then your delta-x and delta-y calculations are: + # z**2 = x**2 + y**2 + # y = pslope * x + # z**2 = x**2 + (pslope * x)**2 + # z**2 = x**2 + pslope**2 * x**2 + # z**2 = (1 + pslope**2) * x**2 + # z**2 / (1 + pslope**2) = x**2 + # z / (1 + pslope**2)**0.5 = x + + # tangential slope approximation + slope = (y2 - y1) / (x2 - x1) + + # normal slope + pslope = -1 / slope # (might be 1/slope depending on direction of travel) + psign = ((pslope > 0) == (x1 > x2)) * 2 - 1 + + dx = psign * d / sqrt(1 + pslope ** 2) + dy = pslope * dx + + return dx, dy + + +if __name__ == '__main__': + ################################## + # Example calls from command line for 2018 Hurricane Florence: + # - python3 make_storm_ensemble.py 3 al062018 2018-09-11-06 2018-09-17-06 + # - python3 make_storm_ensemble.py 5 Florence2018 2018-09-11-06 + ################################## + + # Implement argument parsing + argument_parser = ArgumentParser() + argument_parser.add_argument('number_of_perturbations', help='number of perturbations') + argument_parser.add_argument('storm_code', help='storm name/code') + argument_parser.add_argument('start_date', nargs='?', help='start date') + argument_parser.add_argument('end_date', nargs='?', help='end date') + arguments = argument_parser.parse_args() + + # hardcoding variable list for now + variables = [ + MaximumSustainedWindSpeed, + RadiusOfMaximumWinds, + AlongTrack, + CrossTrack, + ] + + perturber = BestTrackPerturber( + storm=arguments.storm_code, + start_date=arguments.start_date, + end_date=arguments.end_date, + ) + + perturber.write( + number_of_perturbations=arguments.number_of_perturbations, variables=variables, + ) diff --git a/ensembleperturbation/plotting.py b/ensembleperturbation/plotting.py index d31319ce..61635846 100644 --- a/ensembleperturbation/plotting.py +++ b/ensembleperturbation/plotting.py @@ -1,122 +1,131 @@ +import io +from os import PathLike +import pathlib from typing import Union +import zipfile # from affine import Affine +import appdirs + +# import gdal +import geopandas from matplotlib import pyplot +from matplotlib.axes import Axes from matplotlib.cm import get_cmap import numpy -from osgeo import gdal +import requests from shapely.geometry import MultiPoint, MultiPolygon, Polygon from shapely.geometry import shape as shapely_shape -from .utilities import get_logger +from ensembleperturbation.utilities import get_logger LOGGER = get_logger('plotting') -def geoarray_to_xyz( - data: numpy.array, origin: (float, float), resolution: (float, float), nodata: float = None -) -> numpy.array: - """ - Extract XYZ points from an array of data using the given raster-like - georeference (origin and resolution). - - Parameters - ---------- - data - 2D array of gridded data - origin - X, Y coordinates of northwest corner - resolution - cell size - nodata - value to exclude from point creation from the input grid - - Returns - ------- - numpy.array - N x 3 array of XYZ points - """ - - if nodata is None: - if data.dtype == float: - nodata = numpy.nan - elif data.dtype == int: - nodata = -2147483648 - if data.dtype == bool: - nodata = False - - data_coverage = where_not_nodata(data, nodata) - x_values, y_values = numpy.meshgrid( - numpy.linspace(origin[0], origin[0] + resolution[0] * data.shape[1], data.shape[1]), - numpy.linspace(origin[1], origin[1] + resolution[1] * data.shape[0], data.shape[0]), - ) - - return numpy.stack( - (x_values[data_coverage], y_values[data_coverage], data[data_coverage]), axis=1 - ) - - -def gdal_to_xyz(dataset: gdal.Dataset, nodata: float = None) -> numpy.array: - """ - Extract XYZ points from a GDAL dataset. - - Parameters - ---------- - dataset - GDAL dataset (point cloud or raster) - nodata - value to exclude from point creation - - Returns - ------- - numpy.array - N x M array of XYZ points - """ - - coordinates = None - layers_data = [] - if dataset.RasterCount > 0: - for index in range(1, dataset.RasterCount + 1): - raster_band = dataset.GetRasterBand(index) - geotransform = dataset.GetGeoTransform() - - if nodata is None: - nodata = raster_band.GetNoDataValue() - - points = geoarray_to_xyz( - raster_band.ReadAsArray(), - origin=(geotransform[0], geotransform[3]), - resolution=(geotransform[1], geotransform[5]), - nodata=nodata, - ) - if coordinates is None: - coordinates = points[:, :2] - layers_data.append(points[:, 2]) - else: - for index in range(dataset.GetLayerCount()): - point_layer = dataset.GetLayerByIndex(index) - num_features = point_layer.GetFeatureCount() - - for feature_index in range(num_features): - feature = point_layer.GetFeature(feature_index) - feature_geometry = feature.geometry() - num_points = feature_geometry.GetGeometryCount() - # TODO this assumes points in all layers are in the same order - points = numpy.array( - [ - feature_geometry.GetGeometryRef(point_index).GetPoint() - for point_index in range(num_points) - if feature_geometry.GetGeometryRef(point_index).GetPoint()[2] != nodata - ] - ) - - if coordinates is None: - coordinates = points[:, :2] - layers_data.append(points[:, 2]) - - return numpy.concatenate( - [coordinates] + [numpy.expand_dims(data, axis=1) for data in layers_data], axis=1 - ) +# def geoarray_to_xyz( +# data: numpy.array, origin: (float, float), resolution: (float, float), nodata: float = None +# ) -> numpy.array: +# """ +# Extract XYZ points from an array of data using the given raster-like +# georeference (origin and resolution). +# +# Parameters +# ---------- +# data +# 2D array of gridded data +# origin +# X, Y coordinates of northwest corner +# resolution +# cell size +# nodata +# value to exclude from point creation from the input grid +# +# Returns +# ------- +# numpy.array +# N x 3 array of XYZ points +# """ +# +# if nodata is None: +# if data.dtype == float: +# nodata = numpy.nan +# elif data.dtype == int: +# nodata = -2147483648 +# if data.dtype == bool: +# nodata = False +# +# data_coverage = where_not_nodata(data, nodata) +# x_values, y_values = numpy.meshgrid( +# numpy.linspace(origin[0], origin[0] + resolution[0] * data.shape[1], data.shape[1]), +# numpy.linspace(origin[1], origin[1] + resolution[1] * data.shape[0], data.shape[0]), +# ) +# +# return numpy.stack( +# (x_values[data_coverage], y_values[data_coverage], data[data_coverage]), axis=1 +# ) +# +# +# def gdal_to_xyz(dataset: gdal.Dataset, nodata: float = None) -> numpy.array: +# """ +# Extract XYZ points from a GDAL dataset. +# +# Parameters +# ---------- +# dataset +# GDAL dataset (point cloud or raster) +# nodata +# value to exclude from point creation +# +# Returns +# ------- +# numpy.array +# N x M array of XYZ points +# """ +# +# coordinates = None +# layers_data = [] +# if dataset.RasterCount > 0: +# for index in range(1, dataset.RasterCount + 1): +# raster_band = dataset.GetRasterBand(index) +# geotransform = dataset.GetGeoTransform() +# +# if nodata is None: +# nodata = raster_band.GetNoDataValue() +# +# points = geoarray_to_xyz( +# raster_band.ReadAsArray(), +# origin=(geotransform[0], geotransform[3]), +# resolution=(geotransform[1], geotransform[5]), +# nodata=nodata, +# ) +# if coordinates is None: +# coordinates = points[:, :2] +# layers_data.append(points[:, 2]) +# else: +# for index in range(dataset.GetLayerCount()): +# point_layer = dataset.GetLayerByIndex(index) +# num_features = point_layer.GetFeatureCount() +# +# for feature_index in range(num_features): +# feature = point_layer.GetFeature(feature_index) +# feature_geometry = feature.geometry() +# num_points = feature_geometry.GetGeometryCount() +# # TODO this assumes points in all layers are in the same order +# points = numpy.array( +# [ +# feature_geometry.GetGeometryRef(point_index).GetPoint() +# for point_index in range(num_points) +# if feature_geometry.GetGeometryRef(point_index).GetPoint()[2] != nodata +# ] +# ) +# +# if coordinates is None: +# coordinates = points[:, :2] +# layers_data.append(points[:, 2]) +# +# return numpy.concatenate( +# [coordinates] + [numpy.expand_dims(data, axis=1) for data in layers_data], axis=1 +# ) def bounds_from_opposite_corners( @@ -141,31 +150,31 @@ def bounds_from_opposite_corners( return numpy.ravel(numpy.sort(numpy.stack((corner_1, corner_2), axis=0), axis=0)) -def gdal_raster_bounds(raster: gdal.Dataset) -> (float, float, float, float): - """ - Get the bounds (grouped by dimension) of the given unrotated raster. - - Parameters - ---------- - raster - GDAL raster dataset - - Returns - ------- - float, float, float, float - min X, min Y, max X, max Y - """ - - geotransform = raster.GetGeoTransform() - origin = numpy.array((geotransform[0], geotransform[3])) - resolution = numpy.array((geotransform[1], geotransform[5])) - rotation = numpy.array((geotransform[2], geotransform[4])) - shape = raster.RasterYSize, raster.RasterXSize - - if numpy.any(rotation != 0): - raise NotImplementedError('rotated rasters not supported') - - return bounds_from_opposite_corners(origin, origin + numpy.flip(shape) * resolution) +# def gdal_raster_bounds(raster: gdal.Dataset) -> (float, float, float, float): +# """ +# Get the bounds (grouped by dimension) of the given unrotated raster. +# +# Parameters +# ---------- +# raster +# GDAL raster dataset +# +# Returns +# ------- +# float, float, float, float +# min X, min Y, max X, max Y +# """ +# +# geotransform = raster.GetGeoTransform() +# origin = numpy.array((geotransform[0], geotransform[3])) +# resolution = numpy.array((geotransform[1], geotransform[5])) +# rotation = numpy.array((geotransform[2], geotransform[4])) +# shape = raster.RasterYSize, raster.RasterXSize +# +# if numpy.any(rotation != 0): +# raise NotImplementedError('rotated rasters not supported') +# +# return bounds_from_opposite_corners(origin, origin + numpy.flip(shape) * resolution) def where_not_nodata(array: numpy.array, nodata: float = None) -> numpy.array: @@ -529,3 +538,40 @@ def plot_points( # nums, counts = numpy.unique(arr, return_counts=True) # index = numpy.where(counts == numpy.amax(counts)) # return int(nums[index]) + + +def download_coastline(overwrite: bool = False) -> pathlib.Path: + data_directory = pathlib.Path(appdirs.user_data_dir('ne_coastline')) + if not data_directory.exists(): + data_directory.mkdir(exist_ok=True, parents=True) + + coastline_filename = data_directory / 'ne_110m_coastline.shp' + + if not coastline_filename.exists() or overwrite: + # download and save if not present + url = 'http://naciscdn.org/naturalearth/110m/physical/ne_110m_coastline.zip' + response = requests.get(url, stream=True) + with zipfile.ZipFile(io.BytesIO(response.content)) as zip_file: + for member_filename in zip_file.namelist(): + file_data = zip_file.read(member_filename) + with open(data_directory / member_filename, 'wb') as output_file: + output_file.write(file_data) + assert coastline_filename.exists(), 'coastline file not downloaded' + + return coastline_filename + + +def plot_coastline(axis: Axes = None, show: bool = False, save_filename: PathLike = None): + if axis is None: + figure = pyplot.figure() + axis = figure.add_subplot(1, 1, 1) + + coastline_filename = download_coastline() + dataframe = geopandas.read_file(coastline_filename) + dataframe.plot(ax=axis) + + if save_filename is not None: + pyplot.savefig(save_filename) + + if show: + pyplot.show() diff --git a/ensembleperturbation/tropicalcyclone/__init__.py b/ensembleperturbation/tropicalcyclone/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ensembleperturbation/tropicalcyclone/atcf.py b/ensembleperturbation/tropicalcyclone/atcf.py new file mode 100644 index 00000000..c3b04e4f --- /dev/null +++ b/ensembleperturbation/tropicalcyclone/atcf.py @@ -0,0 +1,726 @@ +from collections.abc import Collection +from datetime import datetime, timedelta +from functools import wraps +import gzip +import io +import logging +import os +from os import PathLike +import pathlib +import time +from typing import Any, Union +import urllib.request + +from dateutil.parser import parse as parse_date +from matplotlib import pyplot +from matplotlib.axes import Axes +from matplotlib.transforms import Bbox +import numpy as numpy +from pandas import DataFrame, read_csv +from pyproj import CRS, Geod, Transformer +from shapely import ops +from shapely.geometry import Point, Polygon +import utm + +from ensembleperturbation.plotting import plot_coastline +from ensembleperturbation.utilities import units + +logger = logging.getLogger(__name__) + + +class BestTrackForcing: + def __init__( + self, + storm: Union[str, PathLike, DataFrame, io.BytesIO], + start_date: datetime = None, + end_date: datetime = None, + ): + self.__dataframe = None + self.__atcf = None + self.__storm_id = None + self.__start_date = None + self.__end_date = None + + if isinstance(storm, DataFrame): + self.__dataframe = storm + elif isinstance(storm, io.BytesIO): + self.__atcf = storm + elif isinstance(storm, (str, PathLike, pathlib.Path)): + if os.path.exists(storm): + self.__atcf = io.open(storm, 'rb') + else: + self.storm_id = storm + + self.start_date = start_date + self.end_date = end_date + + self.__previous_configuration = None + + @property + def storm_id(self) -> str: + return self.__storm_id + + @storm_id.setter + def storm_id(self, storm_id: str): + if storm_id is not None: + digits = sum([1 for character in storm_id if character.isdigit()]) + + if digits == 4: + atcf_id = get_atcf_id(storm_id) + if atcf_id is None: + raise ValueError(f'No storm with id: {storm_id}') + storm_id = atcf_id + self.__storm_id = storm_id + + @property + def data(self): + start_date_mask = self.dataframe['datetime'] >= self.start_date + if self.end_date is None: + return self.dataframe[start_date_mask] + else: + return self.dataframe[ + start_date_mask & (self.dataframe['datetime'] <= self.__file_end_date) + ] + + @data.setter + def data(self, dataframe: DataFrame): + self.__dataframe = dataframe + + @property + def atcf(self) -> io.BytesIO: + configuration = {'storm_id': self.storm_id} + if self.__atcf is None or configuration != self.__previous_configuration: + storm_id = configuration['storm_id'] + + url = f'ftp://ftp.nhc.noaa.gov/atcf/archive/{storm_id[4:]}/b{storm_id[0:2].lower()}{storm_id[2:]}.dat.gz' + + try: + logger.info(f'Downloading storm data from {url}') + response = urllib.request.urlopen(url) + except urllib.error.URLError as e: + if '550' in e.reason: + raise NameError(f'storm with id {storm_id} not found at {url}') + else: + + @retry(urllib.error.URLError, tries=4, delay=3, backoff=2) + def make_request(): + logger.info(f'Downloading storm data from {url} failed, retrying...') + return urllib.request.urlopen(url) + + response = make_request() + + self.__atcf = io.BytesIO(response.read()) + self.__previous_configuration = configuration + + return self.__atcf + + @property + def dataframe(self): + configuration = {'storm_id': self.__storm_id} + if ( + self.__dataframe is None + or len(self.__dataframe) == 0 + or configuration != self.__previous_configuration + ): + # https://www.nrlmry.navy.mil/atcf_web/docs/database/new/abdeck.txt + + columns = [ + 'basin', + 'storm_number', + 'datetime', + 'record_type', + 'latitude', + 'longitude', + 'max_sustained_wind_speed', + 'central_pressure', + 'development_level', + 'isotach', + 'quadrant', + 'radius_for_NEQ', + 'radius_for_SEQ', + 'radius_for_SWQ', + 'radius_for_NWQ', + 'background_pressure', + 'radius_of_last_closed_isobar', + 'radius_of_maximum_winds', + 'name', + 'direction', + 'speed', + ] + + if isinstance(self.atcf, io.BytesIO): + lines = gzip.GzipFile(fileobj=self.atcf) + else: + lines = self.atcf + + records = [] + for line_index, line in enumerate(lines): + line = line.decode('UTF-8').split(',') + + record = { + 'basin': line[0], + 'storm_number': line[1].strip(' '), + } + + minutes = line[3].strip(' ') + if minutes == "": + minutes = '00' + record['datetime'] = parse_date(line[2].strip(' ') + minutes) + + record['record_type'] = line[4].strip(' ') + + latitude = line[6] + if 'N' in latitude: + latitude = float(latitude.strip('N ')) + elif 'S' in latitude: + latitude = float(latitude.strip('S ')) * -1 + latitude *= 0.1 + record['latitude'] = latitude + + longitude = line[7] + if 'E' in longitude: + longitude = float(longitude.strip('E ')) * 0.1 + elif 'W' in longitude: + longitude = float(longitude.strip('W ')) * -0.1 + record['longitude'] = longitude + + record.update( + { + 'max_sustained_wind_speed': float(line[8].strip(' ')), + 'central_pressure': float(line[9].strip(' ')), + 'development_level': line[10].strip(' '), + } + ) + + try: + record['isotach'] = int(line[11].strip(' ')) + except ValueError: + raise Exception( + 'Error: No radial wind information for this storm; ' + 'parametric wind model cannot be built.' + ) + + record.update( + { + 'quadrant': line[12].strip(' '), + 'radius_for_NEQ': int(line[13].strip(' ')), + 'radius_for_SEQ': int(line[14].strip(' ')), + 'radius_for_SWQ': int(line[15].strip(' ')), + 'radius_for_NWQ': int(line[16].strip(' ')), + } + ) + + if len(line) > 18: + record.update( + { + 'background_pressure': int(line[17].strip(' ')), + 'radius_of_last_closed_isobar': int(line[18].strip(' ')), + 'radius_of_maximum_winds': int(line[19].strip(' ')), + } + ) + + if len(line) > 23: + record['name'] = line[27].strip(' ') + else: + record['name'] = '' + else: + record.update( + { + 'background_pressure': record['background_pressure'][-1], + 'radius_of_last_closed_isobar': record[ + 'radius_of_last_closed_isobar' + ][-1], + 'radius_of_maximum_winds': record['radius_of_maximum_winds'][-1], + 'name': '', + } + ) + + records.append(record) + + self.__dataframe = self.__compute_velocity( + DataFrame.from_records(data=records, columns=columns) + ) + self.__previous_configuration = configuration + + return self.__dataframe + + @property + def start_date(self) -> datetime: + return self.__start_date + + @start_date.setter + def start_date(self, start_date: datetime): + if start_date is None: + start_date = self.dataframe['datetime'][0] + else: + if not isinstance(start_date, datetime): + start_date = parse_date(start_date) + if ( + start_date < self.dataframe['datetime'].iloc[0] + or start_date > self.dataframe['datetime'].iloc[-1] + ): + raise ValueError( + f'given start date is outside of data bounds ({self.dataframe["datetime"].iloc[0]} - {self.dataframe["datetime"].iloc[-1]})' + ) + self.__start_date = start_date + + @property + def end_date(self) -> datetime: + return self.__end_date + + @end_date.setter + def end_date(self, end_date: datetime): + if end_date is None: + end_date = self.dataframe['datetime'].iloc[-1] + else: + if not isinstance(end_date, datetime): + end_date = parse_date(end_date) + if ( + end_date < self.dataframe['datetime'].iloc[0] + or end_date > self.dataframe['datetime'].iloc[-1] + ): + raise ValueError( + f'given end date is outside of data bounds ({self.dataframe["datetime"].iloc[0]} - {self.dataframe["datetime"].iloc[-1]})' + ) + if end_date <= self.start_date: + raise ValueError(f'end date must be after start date ({self.start_date})') + self.__end_date = end_date + + @property + def name(self) -> str: + return self.data['name'].value_counts()[:].index.tolist()[0] + + @property + def basin(self) -> str: + return self.data['basin'].iloc[0] + + @property + def storm_number(self) -> str: + return self.data['storm_number'].iloc[0] + + @property + def year(self) -> int: + return self.data['datetime'].iloc[0].year + + @property + def datetime(self): + return self.data['datetime'] + + @property + def speed(self): + return self.data['speed'] + + @property + def direction(self): + return self.data['direction'] + + @property + def longitude(self): + return self.data['longitude'] + + @property + def latitude(self): + return self.data['latitude'] + + def clip_to_bbox(self, bbox, bbox_crs): + msg = f'bbox must be a {Bbox} instance.' + assert isinstance(bbox, Bbox), msg + bbox_pol = Polygon( + [ + [bbox.xmin, bbox.ymin], + [bbox.xmax, bbox.ymin], + [bbox.xmax, bbox.ymax], + [bbox.xmin, bbox.ymax], + [bbox.xmin, bbox.ymin], + ] + ) + _switch = True + unique_dates = numpy.unique(self.dataframe['datetime']) + _found_start_date = False + for _datetime in unique_dates: + records = self.dataframe[self.dataframe['datetime'] == _datetime] + radii = records['radius_of_last_closed_isobar'].iloc[0] + radii = 1852.0 * radii # convert to meters + lon = records['longitude'].iloc[0] + lat = records['latitude'].iloc[0] + _, _, number, letter = utm.from_latlon(lat, lon) + df_crs = CRS.from_epsg(4326) + utm_crs = CRS( + proj='utm', + zone=f'{number}{letter}', + ellps={'GRS 1980': 'GRS80', 'WGS 84': 'WGS84'}[df_crs.ellipsoid.name], + ) + transformer = Transformer.from_crs(df_crs, utm_crs, always_xy=True) + p = Point(*transformer.transform(lon, lat)) + pol = p.buffer(radii) + transformer = Transformer.from_crs(utm_crs, bbox_crs, always_xy=True) + pol = ops.transform(transformer.transform, pol) + if _switch is True: + if not pol.intersects(bbox_pol): + continue + else: + self.start_date = records['datetime'].iloc[0] + _found_start_date = True + _switch = False + continue + + else: + if pol.intersects(bbox_pol): + continue + else: + self.end_date = records['datetime'].iloc[0] + break + + if _found_start_date is False: + raise Exception(f'No data within mesh bounding box for storm {self.storm_id}.') + + def plot_track(self, axis: Axes = None, show: bool = False, color: str = 'k', **kwargs): + kwargs.update({'color': color}) + if axis is None: + fig = pyplot.figure() + axis = fig.add_subplot(111) + for i in range(len(self.speed)): + # when dealing with nautical degrees, U is sine and V is cosine. + U = self.speed.iloc[i] * numpy.sin(numpy.deg2rad(self.direction.iloc[i])) + V = self.speed.iloc[i] * numpy.cos(numpy.deg2rad(self.direction.iloc[i])) + axis.quiver(self.longitude.iloc[i], self.latitude.iloc[i], U, V, **kwargs) + if i % 6 == 0: + axis.annotate( + self.data['datetime'].iloc[i], + (self.longitude.iloc[i], self.latitude.iloc[i]), + ) + if show: + axis.axis('scaled') + plot_coastline(axis, show) + + def __generate_record_numbers(self): + record_number = [1] + for i in range(1, len(self.datetime)): + if self.datetime.iloc[i] == self.datetime.iloc[i - 1]: + record_number.append(record_number[-1]) + else: + record_number.append(record_number[-1] + 1) + return record_number + + @property + def __file_end_date(self): + unique_dates = numpy.unique(self.dataframe['datetime']) + for date in unique_dates: + if date >= numpy.datetime64(self.end_date): + return date + + def __str__(self): + record_number = self.__generate_record_numbers() + lines = [] + for i, (_, row) in enumerate(self.data.iterrows()): + line = [] + + line.extend( + [ + f'{row["basin"]:<2}', + f'{row["storm_number"]:>3}', + f'{row["datetime"]:%Y%m%d%H}'.rjust(11), + f'{"":3}', + f'{row["record_type"]:>5}', + f'{convert_value((row["datetime"] - self.start_date) / timedelta(hours=1), to_type=int):>4}', + ] + ) + + latitude = convert_value(row['latitude'] / 0.1, to_type=int, round_digits=1) + if latitude >= 0: + line.append(f'{latitude:>4}N') + else: + line.append(f'{latitude * -.1:>4}S') + + longitude = convert_value(row['longitude'] / 0.1, to_type=int, round_digits=1) + if longitude >= 0: + line.append(f'{longitude:>5}E') + else: + line.append(f'{longitude * -1:>5}W') + + line.extend( + [ + f'{convert_value(row["max_sustained_wind_speed"], to_type=int, round_digits=0):>4}', + f'{convert_value(row["central_pressure"], to_type=int, round_digits=0):>5}', + f'{row["development_level"]:>3}', + f'{convert_value(row["isotach"], to_type=int, round_digits=0):>4}', + f'{row["quadrant"]:>4}', + f'{convert_value(row["radius_for_NEQ"], to_type=int, round_digits=0):>5}', + f'{convert_value(row["radius_for_SEQ"], to_type=int, round_digits=0):>5}', + f'{convert_value(row["radius_for_SWQ"], to_type=int, round_digits=0):>5}', + f'{convert_value(row["radius_for_NWQ"], to_type=int, round_digits=0):>5}', + ] + ) + + if row['background_pressure'] is None: + row['background_pressure'] = self.data['background_pressure'].iloc[i - 1] + if ( + row['background_pressure'] <= row['central_pressure'] + and 1013 > row['central_pressure'] + ): + background_pressure = 1013 + elif ( + row['background_pressure'] <= row['central_pressure'] + and 1013 <= row['central_pressure'] + ): + background_pressure = convert_value( + row['central_pressure'] + 1, to_type=int, round_digits=0, + ) + else: + background_pressure = convert_value( + row['background_pressure'], to_type=int, round_digits=0, + ) + line.append(f'{background_pressure:>5}') + + line.extend( + [ + f'{convert_value(row["radius_of_last_closed_isobar"], to_type=int, round_digits=0):>5}', + f'{convert_value(row["radius_of_maximum_winds"], to_type=int, round_digits=0):>4}', + f'{"":>5}', # gust + f'{"":>4}', # eye + f'{"":>4}', # subregion + f'{"":>4}', # maxseas + f'{"":>4}', # initials + f'{row["direction"]:>3}', + f'{row["speed"]:>4}', + f'{row["name"]:^12}', + ] + ) + + # from this point forwards it's all aswip + line.append(f'{record_number[i]:>4}') + + lines.append(','.join(line)) + + return '\n'.join(lines) + + def write(self, path: PathLike, overwrite: bool = False): + if not isinstance(path, pathlib.Path): + path = pathlib.Path(path) + if path.exists() and overwrite is False: + raise Exception('File exist, set overwrite=True to allow overwrite.') + with open(path, 'w') as f: + f.write(str(self)) + + @staticmethod + def __compute_velocity(data: DataFrame) -> DataFrame: + """ Output has units of meters per second. """ + + geodetic = Geod(ellps='WGS84') + + unique_datetimes = numpy.unique(data['datetime']) + for datetime_index, unique_datetime in enumerate(unique_datetimes): + unique_datetime_indices = numpy.where( + numpy.asarray(data['datetime']) == unique_datetime + )[0] + for unique_datetime_index in unique_datetime_indices: + if unique_datetime_indices[-1] + 1 < len(data['datetime']): + dt = ( + data['datetime'][unique_datetime_indices[-1] + 1] + - data['datetime'][unique_datetime_index] + ) + forward_azimuth, inverse_azimuth, distance = geodetic.inv( + data['longitude'][unique_datetime_indices[-1] + 1], + data['latitude'][unique_datetime_index], + data['longitude'][unique_datetime_index], + data['latitude'][unique_datetime_index], + ) + else: + dt = ( + data['datetime'][unique_datetime_index] + - data['datetime'][unique_datetime_indices[0] - 1] + ) + forward_azimuth, inverse_azimuth, distance = geodetic.inv( + data['longitude'][unique_datetime_indices[0] - 1], + data['latitude'][unique_datetime_index], + data['longitude'][unique_datetime_index], + data['latitude'][unique_datetime_index], + ) + + speed = distance / (dt / timedelta(seconds=1)) * units.meter / units.second + speed = speed.to(units.nautical_mile / units.hour) + bearing = inverse_azimuth % 360 * units.degree + + data['speed'][unique_datetime_index] = int(numpy.around(speed.magnitude, 0)) + data['direction'][unique_datetime_index] = int( + numpy.around(bearing.magnitude, 0) + ) + return data + + @classmethod + def from_fort22( + cls, fort22: PathLike, start_date: datetime = None, end_date: datetime = None, + ) -> 'BestTrackForcing': + + data = read_atcf(fort22) + + storm_id = f'{data["name"][0]}{data["datetime"][0]:%Y}' + + if start_date is None: + start_date = min(data['datetime']) + if end_date is None: + end_date = max(data['datetime']) + + instance = cls(storm=storm_id, start_date=start_date, end_date=end_date) + + instance.__dataframe = data + + return instance + + @classmethod + def from_atcf_file( + cls, atcf: PathLike, start_date: datetime = None, end_date: datetime = None, + ) -> 'BestTrackForcing': + return cls(storm=atcf, start_date=start_date, end_date=end_date) + + +def convert_value(value: Any, to_type: type, round_digits: int = None) -> Any: + if value is not None and value != "": + if round_digits is not None and issubclass(to_type, (int, float)): + if isinstance(value, str): + value = float(value) + value = round(value, round_digits) + value = to_type(value) + return value + + +def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None): + """Retry calling the decorated function using an exponential backoff. + + http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/ + original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry + + :param ExceptionToCheck: the exception to check. may be a tuple of + exceptions to check + :type ExceptionToCheck: Exception or tuple + :param tries: number of times to try (not retry) before giving up + :type tries: int + :param delay: initial delay between retries in seconds + :type delay: int + :param backoff: backoff multiplier e.g. value of 2 will double the delay + each retry + :type backoff: int + :param logger: logger to use. If None, print + :type logger: logging.Logger instance + """ + + def deco_retry(f): + @wraps(f) + def f_retry(*args, **kwargs): + mtries, mdelay = tries, delay + while mtries > 1: + try: + return f(*args, **kwargs) + except ExceptionToCheck as e: + msg = '%s, Retrying in %d seconds...' % (str(e), mdelay) + if logger: + logger.warning(msg) + # else: + # print(msg) + time.sleep(mdelay) + mtries -= 1 + mdelay *= backoff + return f(*args, **kwargs) + + return f_retry # true decorator + + return deco_retry + + +def get_atcf_id(storm_id: str): + url = 'ftp://ftp.nhc.noaa.gov/atcf/archive/storm.table' + + dataframe = read_csv(url, header=None) + name = storm_id[:-4] + year = storm_id[-4:] + entry = dataframe[(dataframe[0] == name.upper().rjust(10)) & (dataframe[8] == int(year))] + if len(entry) == 0: + return None + else: + return entry[20].tolist()[0].strip() + + +def read_atcf(track: PathLike) -> DataFrame: + try: + with open(track) as track_file: + track = track_file.readlines() + except: + track = str(track).splitlines() + + data = { + 'basin': [], + 'storm_number': [], + 'datetime': [], + 'record_type': [], + 'latitude': [], + 'longitude': [], + 'max_sustained_wind_speed': [], + 'central_pressure': [], + 'development_level': [], + 'isotach': [], + 'quadrant': [], + 'radius_for_NEQ': [], + 'radius_for_SEQ': [], + 'radius_for_SWQ': [], + 'radius_for_NWQ': [], + 'background_pressure': [], + 'radius_of_last_closed_isobar': [], + 'radius_of_maximum_winds': [], + 'name': [], + 'direction': [], + 'speed': [], + } + + for index, row in enumerate(track): + row = [value.strip() for value in row.split(',')] + + row_data = {key: None for key in data} + + row_data['basin'] = row[0] + row_data['storm_number'] = row[1] + row_data['datetime'] = datetime.strptime(row[2], '%Y%m%d%H') + row_data['record_type'] = row[4] + + latitude = row[6] + if 'N' in latitude: + latitude = float(latitude[:-1]) * 0.1 + elif 'S' in latitude: + latitude = float(latitude[:-1]) * -0.1 + row_data['latitude'] = latitude + + longitude = row[7] + if 'E' in longitude: + longitude = float(longitude[:-1]) * 0.1 + elif 'W' in longitude: + longitude = float(longitude[:-1]) * -0.1 + row_data['longitude'] = longitude + + row_data['max_sustained_wind_speed'] = convert_value( + row[8], to_type=int, round_digits=0, + ) + row_data['central_pressure'] = convert_value(row[9], to_type=int, round_digits=0) + row_data['development_level'] = row[10] + row_data['isotach'] = convert_value(row[11], to_type=int, round_digits=0) + row_data['quadrant'] = row[12] + row_data['radius_for_NEQ'] = convert_value(row[13], to_type=int, round_digits=0) + row_data['radius_for_SEQ'] = convert_value(row[14], to_type=int, round_digits=0) + row_data['radius_for_SWQ'] = convert_value(row[15], to_type=int, round_digits=0) + row_data['radius_for_NWQ'] = convert_value(row[16], to_type=int, round_digits=0) + row_data['background_pressure'] = convert_value(row[17], to_type=int, round_digits=0) + row_data['radius_of_last_closed_isobar'] = convert_value( + row[18], to_type=int, round_digits=0, + ) + row_data['radius_of_maximum_winds'] = convert_value( + row[19], to_type=int, round_digits=0, + ) + row_data['direction'] = row[25] + row_data['speed'] = row[26] + row_data['name'] = row[27] + + for key, value in row_data.items(): + if isinstance(data[key], Collection): + data[key].append(value) + elif data[key] is None: + data[key] = value + + return DataFrame(data=data) diff --git a/ensembleperturbation/utilities.py b/ensembleperturbation/utilities.py index db3825f5..7c34eb2d 100644 --- a/ensembleperturbation/utilities.py +++ b/ensembleperturbation/utilities.py @@ -4,9 +4,14 @@ import sys import numpy +import pint +from pint_pandas import PintType from pyproj import CRS, Geod, Transformer from shapely.geometry import Point +units = pint.UnitRegistry() +PintType.ureg = units + def repository_root(path: PathLike = None) -> Path: if path is None: diff --git a/environment.yml b/environment.yml deleted file mode 100644 index e501e950..00000000 --- a/environment.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: ensemble_perturbation -dependencies: - - bs4 - - fiona - - geopandas - - matplotlib - - netcdf4 - - numpy - - pandas - - pip - - pyproj>=2.6 - - python==3.7.9 - - requests - - shapely - - pip: - - adcircpy>=1.0.16 - - dunamai - - flake8 - - pytest - - pytest-cov - - requests_futures diff --git a/setup.py b/setup.py index c4f3aafe..c7c2029e 100644 --- a/setup.py +++ b/setup.py @@ -79,7 +79,7 @@ python_requires='>=3.6', setup_requires=['dunamai', 'setuptools>=41.2'], install_requires=[ - 'adcircpy>=1.0.32', + 'appdirs', 'bs4', 'coupledmodeldriver', 'fiona', @@ -89,7 +89,10 @@ 'netcdf4', 'numpy', 'pandas', + 'pint', + 'pint-pandas', 'pyproj>=2.6', + 'python-dateutil', 'requests', 'requests_futures', 'shapely', diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..a502459b --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,48 @@ +from difflib import Differ +from os import PathLike +from pathlib import Path +import re + +DATA_DIRECTORY = Path(__file__).parent / 'data' + + +def check_reference_directory( + test_directory: PathLike, reference_directory: PathLike, skip_lines: {str: [int]} = None +): + if not isinstance(test_directory, Path): + test_directory = Path(test_directory) + if not isinstance(reference_directory, Path): + reference_directory = Path(reference_directory) + if skip_lines is None: + skip_lines = {} + + for reference_filename in reference_directory.iterdir(): + if reference_filename.is_dir(): + check_reference_directory( + test_directory / reference_filename.name, reference_filename, skip_lines + ) + else: + test_filename = test_directory / reference_filename.name + + with open(test_filename) as test_file, open(reference_filename) as reference_file: + test_lines = list(test_file.readlines()) + reference_lines = list(reference_file.readlines()) + + diff = '\n'.join(Differ().compare(test_lines, reference_lines)) + message = f'"{test_filename}" != "{reference_filename}"\n{diff}' + + assert len(test_lines) == len(reference_lines), message + + lines_to_skip = set() + for file_mask, line_indices in skip_lines.items(): + if file_mask in str(test_filename) or re.match( + file_mask, str(test_filename) + ): + lines_to_skip.update( + line_index % len(test_lines) for line_index in line_indices + ) + + for line_index in sorted(lines_to_skip, reverse=True): + del test_lines[line_index], reference_lines[line_index] + + assert '\n'.join(test_lines) == '\n'.join(reference_lines), message diff --git a/tests/data/reference/test_besttrack_ensemble/along_track_1.22 b/tests/data/reference/test_besttrack_ensemble/along_track_1.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/along_track_1.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/along_track_2.22 b/tests/data/reference/test_besttrack_ensemble/along_track_2.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/along_track_2.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/along_track_3.22 b/tests/data/reference/test_besttrack_ensemble/along_track_3.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/along_track_3.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/cross_track_1.22 b/tests/data/reference/test_besttrack_ensemble/cross_track_1.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/cross_track_1.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/cross_track_2.22 b/tests/data/reference/test_besttrack_ensemble/cross_track_2.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/cross_track_2.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/cross_track_3.22 b/tests/data/reference/test_besttrack_ensemble/cross_track_3.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/cross_track_3.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_1.22 b/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_1.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_1.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_2.22 b/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_2.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_2.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_3.22 b/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_3.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/max_sustained_wind_speed_3.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/original.22 b/tests/data/reference/test_besttrack_ensemble/original.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/original.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_1.22 b/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_1.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_1.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_2.22 b/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_2.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_2.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_3.22 b/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_3.22 new file mode 100644 index 00000000..2338663b --- /dev/null +++ b/tests/data/reference/test_besttrack_ensemble/radius_of_maximum_winds_3.22 @@ -0,0 +1,70 @@ +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 34, NEQ, 130, 130, 90, 130, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091100, , BEST, 0, 256N, 618W, 115, 944, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 10, , , , , ,270.0,13.0, FLORENCE , 1 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 34, NEQ, 130, 130, 90, 140, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 50, NEQ, 60, 60, 50, 60, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091106, , BEST, 6, 260N, 632W, 115, 950, HU, 64, NEQ, 35, 30, 25, 35, 1010, 200, 15, , , , , ,270.0,14.0, FLORENCE , 2 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 34, NEQ, 140, 130, 90, 120, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 50, NEQ, 70, 60, 50, 70, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091112, , BEST, 12, 265N, 647W, 125, 947, HU, 64, NEQ, 40, 35, 35, 40, 1010, 200, 15, , , , , ,270.0,15.0, FLORENCE , 3 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091118, , BEST, 18, 272N, 664W, 130, 937, HU, 64, NEQ, 50, 40, 40, 45, 1010, 200, 10, , , , , ,270.0,15.0, FLORENCE , 4 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 34, NEQ, 150, 130, 100, 140, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 50, NEQ, 80, 60, 50, 70, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091200, , BEST, 24, 279N, 681W, 120, 943, HU, 64, NEQ, 50, 45, 40, 45, 1010, 200, 10, , , , , ,270.0,12.0, FLORENCE , 5 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 34, NEQ, 150, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 50, NEQ, 80, 65, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091206, , BEST, 30, 287N, 695W, 115, 945, HU, 64, NEQ, 60, 50, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 6 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 34, NEQ, 150, 140, 110, 130, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091212, , BEST, 36, 294N, 707W, 115, 945, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,10.0, FLORENCE , 7 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 50, NEQ, 90, 80, 60, 70, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091218, , BEST, 42, 304N, 719W, 110, 949, HU, 64, NEQ, 60, 60, 40, 50, 1010, 200, 15, , , , , ,270.0,11.0, FLORENCE , 8 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 34, NEQ, 170, 140, 110, 140, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 50, NEQ, 110, 80, 70, 80, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091300, , BEST, 48, 315N, 732W, 105, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 9.0, FLORENCE , 9 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 34, NEQ, 170, 150, 110, 140, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 50, NEQ, 100, 90, 70, 80, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091306, , BEST, 54, 324N, 742W, 100, 955, HU, 64, NEQ, 70, 60, 50, 60, 1010, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 10 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091312, , BEST, 60, 331N, 751W, 95, 954, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 8.0, FLORENCE , 11 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 34, NEQ, 170, 150, 120, 140, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 50, NEQ, 100, 90, 80, 80, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091318, , BEST, 66, 336N, 760W, 90, 953, HU, 64, NEQ, 70, 60, 50, 60, 1011, 200, 20, , , , , ,270.0, 4.0, FLORENCE , 12 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091400, , BEST, 72, 340N, 765W, 90, 952, HU, 64, NEQ, 70, 60, 50, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 13 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 34, NEQ, 170, 150, 130, 100, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 50, NEQ, 100, 80, 80, 70, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091406, , BEST, 78, 342N, 772W, 85, 952, HU, 64, NEQ, 70, 60, 60, 50, 1012, 200, 20, , , , , ,270.0, 6.0, FLORENCE , 14 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 34, NEQ, 170, 150, 140, 90, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 50, NEQ, 100, 80, 80, 60, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091411, , BEST, 83, 342N, 778W, 80, 956, HU, 64, NEQ, 70, 60, 60, 40, 1012, 200, 25, , , , , ,270.0, 7.0, FLORENCE , 15 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 34, NEQ, 170, 150, 140, 80, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 50, NEQ, 100, 80, 80, 40, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091412, , BEST, 84, 341N, 779W, 80, 957, HU, 64, NEQ, 60, 60, 60, 20, 1012, 200, 25, , , , , ,270.0, 4.0, FLORENCE , 16 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 34, NEQ, 150, 130, 120, 70, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 50, NEQ, 90, 70, 60, 30, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091418, , BEST, 90, 340N, 784W, 65, 969, HU, 64, NEQ, 0, 30, 30, 0, 1012, 200, 30, , , , , ,270.0, 3.0, FLORENCE , 17 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 34, NEQ, 150, 150, 100, 60, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091500, , BEST, 96, 339N, 788W, 60, 978, TS, 50, NEQ, 70, 70, 50, 30, 1013, 210, 30, , , , , ,270.0, 4.0, FLORENCE , 18 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 34, NEQ, 150, 150, 90, 50, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091506, , BEST, 102, 337N, 793W, 55, 986, TS, 50, NEQ, 70, 70, 0, 0, 1013, 210, 50, , , , , ,270.0, 2.0, FLORENCE , 19 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 34, NEQ, 150, 130, 80, 40, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091512, , BEST, 108, 336N, 795W, 55, 992, TS, 50, NEQ, 60, 100, 0, 0, 1013, 220, 60, , , , , ,270.0, 3.0, FLORENCE , 20 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 34, NEQ, 140, 130, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091518, , BEST, 114, 336N, 798W, 50, 997, TS, 50, NEQ, 0, 110, 0, 0, 1013, 220, 110, , , , , ,270.0, 3.0, FLORENCE , 21 +AL, 06, 2018091600, , BEST, 120, 336N, 802W, 45, 998, TS, 34, NEQ, 130, 130, 0, 0, 1013, 240, 110, , , , , ,270.0, 5.0, FLORENCE , 22 +AL, 06, 2018091606, , BEST, 126, 336N, 808W, 40, 999, TS, 34, NEQ, 130, 130, 0, 0, 1013, 260, 110, , , , , ,270.0, 6.0, FLORENCE , 23 +AL, 06, 2018091612, , BEST, 132, 336N, 815W, 35, 1002, TS, 34, NEQ, 0, 140, 0, 0, 1013, 280, 140, , , , , ,270.0, 5.0, FLORENCE , 24 +AL, 06, 2018091618, , BEST, 138, 341N, 821W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1013, 300, 140, , , , , ,270.0, 1.0, FLORENCE , 25 +AL, 06, 2018091700, , BEST, 144, 350N, 822W, 25, 1007, TD, 0, , 0, 0, 0, 0, 1013, 320, 150, , , , , ,270.0, 3.0, FLORENCE , 26 +AL, 06, 2018091706, , BEST, 150, 364N, 826W, 25, 1008, TD, 0, , 0, 0, 0, 0, 1013, 340, 160, , , , , ,90.0, 3.0, FLORENCE , 27 +AL, 06, 2018091712, , BEST, 156, 378N, 822W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0, 2.0, FLORENCE , 28 +AL, 06, 2018091718, , BEST, 162, 388N, 820W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,90.0,12.0, FLORENCE , 29 +AL, 06, 2018091800, , BEST, 168, 395N, 805W, 25, 1008, EX, 0, , 0, 0, 0, 0, 1013, 360, 160, , , , , ,89.0,29.0, FLORENCE , 30 +AL, 06, 2018091806, , BEST, 174, 413N, 768W, 25, 1007, EX, 0, , 0, 0, 0, 0, 1013, 360, 170, , , , , ,89.0,26.0, FLORENCE , 31 +AL, 06, 2018091812, , BEST, 180, 422N, 733W, 25, 1006, EX, 34, NEQ, 0, 0, 0, 0, 1013, 360, 180, , , , , ,271.0,26.0, FLORENCE , 32 \ No newline at end of file diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.14 b/tests/data/reference/test_parse_adcirc_output/fort.14 similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.14 rename to tests/data/reference/test_parse_adcirc_output/fort.14 diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.15 b/tests/data/reference/test_parse_adcirc_output/fort.15 similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.15 rename to tests/data/reference/test_parse_adcirc_output/fort.15 diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.16 b/tests/data/reference/test_parse_adcirc_output/fort.16 similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.16 rename to tests/data/reference/test_parse_adcirc_output/fort.16 diff --git a/tests/data/reference/test_parse_adcirc_output/fort.33 b/tests/data/reference/test_parse_adcirc_output/fort.33 new file mode 100644 index 00000000..e69de29b diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.63.nc b/tests/data/reference/test_parse_adcirc_output/fort.63.nc similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.63.nc rename to tests/data/reference/test_parse_adcirc_output/fort.63.nc diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.64.nc b/tests/data/reference/test_parse_adcirc_output/fort.64.nc similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.64.nc rename to tests/data/reference/test_parse_adcirc_output/fort.64.nc diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.67.nc b/tests/data/reference/test_parse_adcirc_output/fort.67.nc similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.67.nc rename to tests/data/reference/test_parse_adcirc_output/fort.67.nc diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/fort.68.nc b/tests/data/reference/test_parse_adcirc_output/fort.68.nc similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/fort.68.nc rename to tests/data/reference/test_parse_adcirc_output/fort.68.nc diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/maxele.63.nc b/tests/data/reference/test_parse_adcirc_output/maxele.63.nc similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/maxele.63.nc rename to tests/data/reference/test_parse_adcirc_output/maxele.63.nc diff --git a/tests/data/Shinnecock_Inlet_NetCDF_output/maxvel.63.nc b/tests/data/reference/test_parse_adcirc_output/maxvel.63.nc similarity index 100% rename from tests/data/Shinnecock_Inlet_NetCDF_output/maxvel.63.nc rename to tests/data/reference/test_parse_adcirc_output/maxvel.63.nc diff --git a/tests/test_base.py b/tests/test_base.py deleted file mode 100644 index 1796bf92..00000000 --- a/tests/test_base.py +++ /dev/null @@ -1,2 +0,0 @@ -def test_base(): - assert True diff --git a/tests/test_besttrack_ensemble.py b/tests/test_besttrack_ensemble.py new file mode 100644 index 00000000..4db57530 --- /dev/null +++ b/tests/test_besttrack_ensemble.py @@ -0,0 +1,32 @@ +from ensembleperturbation.perturbation.make_storm_ensemble import ( + AlongTrack, + BestTrackPerturber, + CrossTrack, + MaximumSustainedWindSpeed, + RadiusOfMaximumWinds, +) +from tests import check_reference_directory, DATA_DIRECTORY + + +def test_besttrack_ensemble(): + output_directory = DATA_DIRECTORY / 'output' / 'test_besttrack_ensemble' + reference_directory = DATA_DIRECTORY / 'reference' / 'test_besttrack_ensemble' + + if not output_directory.exists(): + output_directory.mkdir(parents=True, exist_ok=True) + + # hardcoding variable list for now + variables = [ + MaximumSustainedWindSpeed, + RadiusOfMaximumWinds, + AlongTrack, + CrossTrack, + ] + + perturber = BestTrackPerturber(storm='al062018', start_date='20180911', end_date=None) + + perturber.write( + number_of_perturbations=3, variables=variables, directory=output_directory, alpha=0.5, + ) + + check_reference_directory(output_directory, reference_directory) diff --git a/tests/test_parser.py b/tests/test_parser.py index 9f984e7c..2625dc7b 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,14 +1,17 @@ -from pathlib import Path +import re -from ensembleperturbation.parsing.adcirc import ( - ADCIRC_OUTPUT_DATA_VARIABLES, - parse_adcirc_output, -) - -ADCIRC_OUTPUT_DIRECTORY = Path(__file__).parent / 'data/Shinnecock_Inlet_NetCDF_output' +from ensembleperturbation.parsing.adcirc import parse_adcirc_output +from tests import DATA_DIRECTORY def test_parse_adcirc_output(): - output_data = parse_adcirc_output(ADCIRC_OUTPUT_DIRECTORY) - for data_variable in ADCIRC_OUTPUT_DATA_VARIABLES: + reference_directory = DATA_DIRECTORY / 'reference' / 'test_parse_adcirc_output' + output_filenames = [ + filename.name + for filename in reference_directory.iterdir() + if re.match('\.6(0-9)?\.nc', str(filename)) + ] + + output_data = parse_adcirc_output(reference_directory) + for data_variable in output_filenames: assert data_variable in output_data