Perturbation

storm vortex tracks (ATCF)

This module provides functionality to

  1. extract an ATCF best track dataset (fort.22)

  2. randomly perturb different parameters (intensity, size, track coordinates) to generate an ensemble of tracks

  3. write out each ensemble member to the ATCF tropical cyclone vortex file (fort.22)

authors:

  • William Pringle, Argonne National Laboratory, Mar-May 2021

  • Zach Burnett, NOS/NOAA

  • Saeed Moghimi, NOS/NOAA

perturbed variables

class ensembleperturbation.perturbation.atcf.MaximumSustainedWindSpeed

Bases: VortexPerturbedVariable

max_sustained_wind_speed (Vmax) represents the maximum wind speed sustained by the storm. It is perturbed along a random gaussian distribution (0 - 1), scaled to the mean of absolute historical errors. central_pressure (pc) is then changed proportionally based on the Holland B parameter.

class ensembleperturbation.perturbation.atcf.RadiusOfMaximumWinds

Bases: VortexPerturbedVariable

radius_of_maximum_winds (Rmax) It is perturbed along a uniform distribution on [-1,1] between the 0th and 100th percentile CDFs of NHC historical forecast errors. 0th and 100th percentiles are calculated based on extrapolation from the provided 15th, 50th, and 85th percentiles.

storm_errors(data_frame: DataFrame, loc_index: int = 0) DataFrame

Historical forecast errors of the given storm, based on initial size.

Parameters:
  • data_frame – storm data frame

  • loc_index – index to classify the errors at (0 by default for initial)

Returns:

errors based on size classification

class ensembleperturbation.perturbation.atcf.CrossTrack

Bases: VortexPerturbedVariable

cross_track represents a perpendicular offset of the tropical cyclone center track, accomplished by moving each forecast time left or right perpedicular to the track line. It is perturbed along a random gaussian distribution (0 - 1), scaled to the mean of absolute historical errors.

perturb(vortex_dataframe: DataFrame, values: List[float], times: List[datetime], inplace: bool = False) DataFrame

offsets points by a given perpendicular error/distance from the original track

Parameters:
  • vortex_dataframe – ATCF dataframe containing track info

  • values – cross-track errors [nm] for each forecast time (VT)

  • times – forecast times (VT)

  • inplace – modify dataframe in-place

Returns:

updated ATCF dataframe with different longitude latitude locations based on perpendicular offsets set by the cross_track_errors

class ensembleperturbation.perturbation.atcf.AlongTrack

Bases: VortexPerturbedVariable

along_track represents a parallel offset of the tropical cyclone center track, accomplished by moving each forecast time forward or backward along the track line. It is perturbed along a random gaussian distribution (0 - 1), scaled to the mean of absolute historical errors.

perturb(vortex_dataframe: DataFrame, values: List[float], times: List[datetime], inplace: bool = False) DataFrame

offsets points by a given error/distance by interpolating along the track

Parameters:
  • vortex_dataframe – ATCF dataframe containing track info

  • values – along-track errors for each forecast time (VT)

  • times – forecast timed (VT)

  • inplace – modify dataframe in-place

Returns:

updated ATCF dataframe with different longitude latitude locations based on interpolated errors along track

non-perturbed variables

class ensembleperturbation.perturbation.atcf.CentralPressure(default: float | None = None, unit: Unit | None = None)

Bases: VortexVariable

class ensembleperturbation.perturbation.atcf.BackgroundPressure

Bases: VortexVariable

perturber class

class ensembleperturbation.perturbation.atcf.VortexPerturber(storm: str, start_date: datetime | None = None, end_date: datetime | None = None, file_deck: ATCF_FileDeck | None = None, advisories: List[str] | None = None)

Bases: object

VortexPerturber takes an ATCF track from an input storm and perturbs it based on several variables (of the class VortexPerturbedVariable)

# retrieve initial storm track for Florence 2018 (defaults to archival best track)
perturber = VortexPerturber(storm='florence2018')

# write 3 tracks perturbed using specified perturbation values (perturbations are of sigma values (``0`` - ``1`` for uniform or ``-1`` - ``1`` for gaussian) that are then scaled to historical errors per-variable
perturber.write(
    perturbations=[
        -1.0,
        {
            MaximumSustainedWindSpeed: -0.25,
            CrossTrack: 0.25,
            'along_track': 0.75,
            'radius_of_maximum_winds': -1,
        },
        0.75,
    ],
    variables=[MaximumSustainedWindSpeed, RadiusOfMaximumWinds, CrossTrack, AlongTrack],
    directory='./3_tracks_perturbed_specifically',
)

# write 5 randomly-perturbed tracks, drawing randomly from the distribution of each variable except for ``CrossTrack``
perturber.write(
    perturbations=5,
    variables=[MaximumSustainedWindSpeed, RadiusOfMaximumWinds, AlongTrack],
    directory='./5_tracks_perturbed_randomly_except_crosstrack',
)

# write tracks perturbed along the quadrature (`4^n` where `n` is the number of variables)
perturber.write(
    perturbations=None,
    quadrature=True,
    variables=[MaximumSustainedWindSpeed, RadiusOfMaximumWinds, CrossTrack, AlongTrack],
    directory='./256_tracks_perturbed_along_quadrature',
)
Parameters:
  • storm – NHC storm code, for instance al062018

  • start_date – start time of ensemble

  • end_date – end time of ensemble

  • file_deck – ATCF file deck; one of a, b, f

  • advisories – ATCF advisory type; one of BEST, OFCL, OFCP, HMON, CARQ, HWRF

classmethod from_file(filename: PathLike, start_date: datetime | None = None, end_date: datetime | None = None, file_deck: ATCF_FileDeck | None = None, advisories: List[str] | None = None) VortexPerturber

build storm perturber from an existing fort.22 or ATCF file

Parameters:
  • filename – file path to fort.22 / ATCF file

  • start_date – start time of ensemble

  • end_date – end time of ensemble

  • file_deck – ATCF file deck; one of a, b, f

  • advisories – ATCF advisory type; one of BEST, OFCL, OFCP, HMON, CARQ, HWRF

classmethod from_track(track: VortexTrack) VortexPerturber

build storm perturber from an existing VortexTrack object

Parameters:

trackVortexTrack object

write(perturbations: int | List[float] | List[Dict[str, float]] | None, variables: List[VortexVariable], directory: PathLike | None = None, sample_from_distribution: bool = False, sample_rule: str = 'random', sample_division_fraction: float = 0.99, quadrature: bool = False, quadrature_order: int = 3, quadrature_rule: str = 'Gaussian', sparse_quadrature: bool = False, weights: List[float] | None = None, overwrite: bool = False, continue_numbering: bool = False, parallel: bool = True) List[Path]
Parameters:
  • perturbations – either the number of perturbations to create, or a list of floats meant to represent points on either the standard Gaussian distribution or a bounded uniform distribution

  • variables – list of variable names, any combination of [“max_sustained_wind_speed”, “radius_of_maximum_winds”, “along_track”, “cross_track”]

  • directory – directory to which to write

  • sample_from_distribution – override given perturbations with random samples from the joint distribution

  • sample_rule – rule to use for the distribution sampling. Please choose from: random [default], sobol, halton, hammersley, korobov, additive_recursion, or latin_hypercube, equal_division

  • sample_division_fraction – the fraction of the distribution to cover for equal_division sampling option

  • quadrature – add perturbations along quadrature

  • quadrature_order – order of the quadrature

  • quadrature_rule – rule of the quadrature for generating abscissas and weights

  • sparse_quadrature – use Smolyak’s sparse grid instead of normal tensor product grid

  • weights – weights to use with perturbations

  • overwrite – overwrite existing files

  • continue_numbering – continue the existing numbering scheme if files already exist in the output directory

  • parallel – generate perturbations concurrently

Returns:

written filenames

property validation_times: List[timedelta]

get the validation time of storm

property holland_B: float

Compute Holland B at each time snap

compute_pc_from_Vmax(dataframe: DataFrame) float

Compute central pressure from Vmax based on Holland B