Source code for pydsstools.core.gridinfo.hrap

"""HRAP grid type implementation and utilities.

This module provides the HrapInfo class and HRAP-specific utility functions.
HRAP (Hydrologic Rainfall Analysis Project) uses a polar stereographic
projection commonly used for precipitation data.
"""

import logging
from typing import Optional

try:
    from typing import Annotated, Literal
except ImportError:
    from typing_extensions import Annotated, Literal

from pydantic import Field, AliasChoices

from ..enums import GridType
from ..crs import hrap as hrap_crs
from .undefined import GridInfo
from .base import GridTypeField

__all__ = ["HrapInfo", "HRAP_CELL_SIZE"]


# HRAP standard cell size at 60°N latitude (meters)
HRAP_CELL_SIZE = 4762.5


[docs] class HrapInfo(GridInfo): """Metadata for HRAP (Hydrologic Rainfall Analysis Project) grid. HRAP uses a polar stereographic projection centered on the North Pole, commonly used for precipitation data in hydrologic modeling. The standard HRAP grid has 4.7625 km cell size at 60°N latitude. In addition to the parameters inherited from :class:`GridInfo`, this class adds ``data_source`` for tracking data provenance. Examples -------- Create HRAP grid for NEXRAD precipitation: >>> from pydsstools.core.gridinfo import HrapInfo, GridType, DataType >>> info = HrapInfo( ... grid_type=GridType.hrap, ... data_type=DataType.per_aver, ... shape=(100, 150), ... cell_size=HRAP_CELL_SIZE, # 4762.5 m ... data_units="MM", ... data_source="NEXRAD" ... ) Or use the factory function (recommended): >>> from pydsstools.core.gridinfo import GridInfoCreate >>> info = GridInfoCreate( ... grid_type=GridType.hrap, ... data_type=DataType.per_aver, ... shape=(100, 150), ... cell_size=HRAP_CELL_SIZE, ... data_units="MM", ... data_source="NEXRAD" ... ) Notes ----- **HRAP Projection Parameters:** * Projection: Polar Stereographic * Latitude of true scale: 60N * Central meridian: 105W * False easting: 401 grid cells * False northing: 1601 grid cells * Standard cell size: 4.7625 km at 60N **Typical Users:** * National Weather Service (NWS) * River Forecast Centers (RFCs) * HEC-HMS for precipitation input **Coordinate System:** * Origin is at the North Pole * X-axis points along 105W meridian * Grid cells are 4.7625 km x 4.7625 km at 60N * Standard grid covers the United States **Common Data Sources:** * NEXRAD - Next-Generation Radar * MPE - Multi-sensor Precipitation Estimator * RFC - River Forecast Center * PRISM - Parameter-elevation Regressions on Independent Slopes Model References ---------- .. [hrap1] NOAA National Weather Service, "HRAP Coordinate System" https://www.nws.noaa.gov/oh/hrl/nwsrfs/users_manual/part2/_pdf/22hrap.pdf """ grid_type: Annotated[ Literal[GridType.hrap_time, GridType.hrap], Field(description="Grid type for HRAP grid data. Only hrap and hrap_time are valid.") ] = GridType.hrap_time """GridType: Type of grid projection. Only ``hrap`` and ``hrap_time`` are valid. Default ``GridType.hrap_time``.""" data_source: str = Field( default="", validation_alias=AliasChoices( "data_source", "data_sources", "datasource", "datasources", "dsource", "dsources", ), description="Data source or provenance information" ) """str: Source or provenance of the data. Common values: ``"NEXRAD"``, ``"MPE"``, ``"RFC"``, ``"PRISM"``. Default ``""``.""" def _infer_crs(self) -> str: """Infer CRS for HRAP grid. Returns ------- str HRAP CRS definition (PROJ or WKT format). """ # Check if user provided custom CRS in extra if "crs" in self.extra_info: crs = self.extra_info["crs"].strip() if crs: logging.warning( "Custom CRS found in extra_info for HRAP grid. " "Using standard HRAP CRS instead." ) return hrap_crs() def _infer_crs_name(self) -> str: """Infer CRS name for HRAP grid. Returns ------- str Always returns "HRAP". """ return "HRAP"