arlmet.records#

ARL record parsing and data unpacking.

This module provides classes and functions for parsing ARL file records, including index records, data records, headers, and the differential unpacking algorithm. It handles the binary format used in ARL meteorological files.

Functions

letter_to_thousands(char)

Convert letter to thousands digit for large grids.

restore_year(yr)

Convert 2-digit year to 4-digit year.

unpack(data, nx, ny, precision, exponent, ...)

Unpacks a differentially packed byte array into a 2D numpy array.

Classes

DataRecord(header, data)

Represents a data record containing packed meteorological data.

Header(year, month, day, hour, forecast, ...)

First 50 bytes of each record

IndexRecord(header, source, forecast_hour, ...)

Represents a complete ARL index record that precedes data records for each time period.

LvlInfo(index, height, variables)

Information about a single vertical level.

VarInfo(checksum, reserved)

arlmet.records.letter_to_thousands(char)[source]#

Convert letter to thousands digit for large grids. A=1000, B=2000, C=3000, etc.

Return type:

int

arlmet.records.restore_year(yr)[source]#

Convert 2-digit year to 4-digit year.

Parameters:

yr (str or int) – Year value (2-digit or 4-digit).

Returns:

4-digit year. Years < 40 are mapped to 2000+yr, otherwise 1900+yr. Already 4-digit years (>= 1900) are returned unchanged.

Return type:

int

arlmet.records.unpack(data, nx, ny, precision, exponent, initial_value, checksum=None)[source]#

Unpacks a differentially packed byte array into a 2D numpy array.

This function is a vectorized Python translation of the HYSPLIT FORTRAN PAKINP subroutine. It uses a differential unpacking scheme where each value is derived from the previous one. The implementation is optimized with numpy for high performance.

Parameters:
  • data (bytes or bytearray) – Packed input data as a 1D array of bytes.

  • nx (int) – The number of columns in the full data grid.

  • ny (int) – The number of rows in the full data grid.

  • precision (float) – Precision of the packed data. Values with an absolute value smaller than this will be set to zero.

  • exponent (int) – The packing scaling exponent.

  • initial_value (float) – The initial real value at the grid position (0,0).

  • checksum (int, optional) – If provided, a checksum is calculated over data and compared against this value. A ValueError is raised on mismatch. If None (default), the check is skipped.

Returns:

The unpacked 2D numpy array of shape (ny, nx) and dtype float32.

Return type:

np.ndarray

Raises:

ValueError – If a checksum is provided and the calculated checksum does not match.

class arlmet.records.Header(year, month, day, hour, forecast, level, grid, variable, exponent, precision, initial_value)[source]#

First 50 bytes of each record

year: int#
month: int#
day: int#
hour: int#
forecast: int#
level: int#
grid: tuple[int, int]#
variable: str#
exponent: int#
precision: float#
initial_value: float#
N_BYTES: ClassVar[int] = 50#
classmethod from_bytes(data)[source]#

Parse header from raw bytes.

Return type:

Header

property time: Timestamp#

Get the timestamp for this record.

Returns:

Timestamp constructed from year, month, day, and hour fields.

Return type:

pd.Timestamp

to_dict()[source]#

Convert header to dictionary.

Returns:

Dictionary representation of the header fields.

Return type:

dict[str, Any]

to_bytes()[source]#

Convert header to bytes (not yet implemented).

Returns:

Binary representation of the header.

Return type:

bytes

Raises:

NotImplementedError – This functionality is not yet implemented.

__init__(year, month, day, hour, forecast, level, grid, variable, exponent, precision, initial_value)#
class arlmet.records.VarInfo(checksum, reserved)[source]#
checksum: int#
reserved: str#
__init__(checksum, reserved)#
class arlmet.records.LvlInfo(index, height, variables)[source]#

Information about a single vertical level.

Parameters:
  • index (int) – Level index.

  • height (float) – Height in units of the vertical coordinate system.

  • variables (dict[str, VarInfo]) – Dictionary mapping variable names to VarInfo (checksum and reserved).

index: int#
height: float#
variables: dict[str, VarInfo]#
__init__(index, height, variables)#
class arlmet.records.IndexRecord(header, source, forecast_hour, minutes, pole_lat, pole_lon, tangent_lat, tangent_lon, grid_size, orientation, cone_angle, sync_x, sync_y, sync_lat, sync_lon, reserved, nx, ny, nz, vertical_flag, index_length, levels)[source]#

Represents a complete ARL index record that precedes data records for each time period. Combines the fixed portion with the variable levels portion.

Parameters:
  • header (Header) – The header information for the index record.

  • source (str) – Source identifier (4 characters).

  • forecast_hour (int) – Forecast hour.

  • minutes (int) – Minutes after the hour.

  • pole_lat (float) – Pole latitude position of the grid projection. For lat-lon grids: max latitude of the grid.

  • pole_lon (float) – Pole longitude position of the grid projection. For lat-lon grids: max longitude of the grid.

  • tangent_lat (float) – Reference latitude at which the grid spacing is defined. For conical and mercator projections, this is the latitude at which the grid touches the surface. For lat-lon grids: grid spacing in degrees latitude.

  • tangent_lon (float) – Reference longitude at which the grid spacing is defined. For conical and mercator projections, this is the longitude at which the grid touches the surface. For lat-lon grids: grid spacing in degrees longitude.

  • grid_size (float) – Grid spacing in km at the reference position. For lat-lon grids: value of zero signals that the grid is a lat-lon grid.

  • orientation (float) – Angle at the reference point made by the y-axis and the local direction of north. For lat-lon grids: 0

  • cone_angle (float) – Angle between the axis and the surface of the cone. For regular projections it equals the latitude at which the grid is tangent to the earth’s surface. Stereographic: ±90, Mercator: 0, Lambert Conformal: 0 ~ 90 For lat-lon grids: 0

  • sync_x (float) – Grid x-coordinate used to equate a position on the grid with a position on earth. This is a unitless grid index (FORTRAN 1-based).

  • sync_y (float) – Grid y-coordinate used to equate a position on the grid with a position on earth. This is a unitless grid index (FORTRAN 1-based).

  • sync_lat (float) – Earth latitude corresponding to the grid position (sync_x, sync_y). For lat-lon grids: latitude of the (0,0) grid point position.

  • sync_lon (float) – Earth longitude corresponding to the grid position (sync_x, sync_y). For lat-lon grids: longitude of the (0,0) grid point position.

  • nx (int) – Number of grid points in the x-direction (columns).

  • ny (int) – Number of grid points in the y-direction (rows).

  • nz (int) – Number of vertical levels.

  • vertical_flag (int) – Vertical coordinate system type (1=sigma, 2=pressure, 3=terrain, 4=hybrid).

  • index_length (int) – Total length of the index record in bytes, including fixed and variable portions.

  • levels (list[LvlInfo]) –

    List of levels, each containing:
    • level: Level index (0 to nz-1).

    • height: Height of the level in units of the vertical coordinate.

    • vars: Dictionary mapping variable names to VarInfo (checksum and reserved).

N_BYTES_FIXED#

Number of bytes in the fixed portion of the index record (108 bytes).

Type:

int

time#

The valid time of the record, calculated from the header time and minutes.

Type:

pd.Timestamp

header: Header#
source: str#
forecast_hour: int#
minutes: int#
pole_lat: float#
pole_lon: float#
tangent_lat: float#
tangent_lon: float#
grid_size: float#
orientation: float#
cone_angle: float#
sync_x: float#
sync_y: float#
sync_lat: float#
sync_lon: float#
reserved: float#
nx: int#
ny: int#
nz: int#
vertical_flag: int#
index_length: int#
levels: Sequence[LvlInfo]#
N_BYTES_FIXED: ClassVar[int] = 108#
static parse_fixed(data)[source]#

Parse the fixed 108-byte portion of an index record from raw bytes.

Parameters:

data (bytes) – Raw bytes containing the fixed portion of the index record. 108 bytes expected.

Returns:

Parsed fields as a dictionary.

Return type:

dict

static parse_extended(data, nz)[source]#

Parse the variable-length portion of an index record containing level information.

Parameters:
  • data (bytes) – Raw bytes containing the extended portion of the index record.

  • nz (int) – Number of vertical levels (from the fixed portion).

Returns:

List of LevelInfo objects for each vertical level.

Return type:

list[LevelInfo]

property time: Timestamp#

Get the valid time for this index record.

Returns:

Valid time calculated from header time plus minutes offset.

Return type:

pd.Timestamp

property total_nx: int#

Total number of grid points in the x-direction, including any additional thousands from the grid letters.

Returns:

Total number of grid points in x-direction.

Return type:

int

property total_ny: int#

Total number of grid points in the y-direction, including any additional thousands from the grid letters.

Returns:

Total number of grid points in y-direction.

Return type:

int

__init__(header, source, forecast_hour, minutes, pole_lat, pole_lon, tangent_lat, tangent_lon, grid_size, orientation, cone_angle, sync_x, sync_y, sync_lat, sync_lon, reserved, nx, ny, nz, vertical_flag, index_length, levels)#
class arlmet.records.DataRecord(header, data)[source]#

Represents a data record containing packed meteorological data.

Parameters:
  • header (Header) – The header for this data record.

  • data (bytes) – The packed binary data.

header: Header#
data: bytes#
property variable: str#

Get the variable name for this data record.

Returns:

Variable name from the header.

Return type:

str

property level: int#

Get the vertical level for this data record.

Returns:

Level index from the header.

Return type:

int

property forecast: int#

Get the forecast hour for this data record.

Returns:

Forecast hour from the header.

Return type:

int

unpack(nx, ny)[source]#

Unpack the data record into a 2D numpy array.

Parameters:
  • nx (int) – Number of grid points in the x-direction.

  • ny (int) – Number of grid points in the y-direction.

Returns:

Unpacked 2D numpy array of shape (ny, nx).

Return type:

np.ndarray

__init__(header, data)#