/**
* European Centre for Medium-Range Weather Forecasts (ECMWF) API
* This API provides access to various weather and climate data products including
* forecasts, reanalysis datasets, and climate projections.
*
* **Data Information:**
* - **Source:** ECMWF & Copernicus Climate Data Store (CDS)
* - **Format:** GRIB2, NetCDF (requires conversion/processing)
* - **Key Products:** ERA5 (Reanalysis), Seasonal Forecasts, High-res Operations
* - **Access:** **REQUIRES API KEY** (See: https://cds.climate.copernicus.eu/api-how-to)
*
* **Available Data Types:**
* - `era5`: ERA5 Reanalysis data (Hourly, Monthly).
* - `seasonal-forecast`: Seasonal long-range forecasts.
* - `climate-projections`: CMIP6 global climate projections.
* - `forecast-grib2`: Operational forecasts (Real-time).
* - `point-data` / `grid-data`: Spatial extractions.
*
* **Example Usage:**
*
* @example
* // 1. Retrieve ERA5 Reanalysis Data (Surface Temperature)
* // Note: Response is often binary (GRIB/NetCDF), requires params.process=true or manual handling
* const era5Data = await hydro.data.retrieve({
* params: {
* source: 'ecmwf',
* datatype: 'era5',
* key: 'YOUR_ECMWF_API_KEY'
* },
* args: {
* product_type: 'reanalysis',
* variable: ['2m_temperature'],
* year: '2022',
* month: '01',
* day: '01',
* time: ['12:00'],
* area: [50, -10, 40, 10], // Spatial subset
* format: 'netcdf'
* }
* });
*
* @example
* // 2. Retrieve Operational Forecast (GRIB2)
* const forecast = await hydro.data.retrieve({
* params: {
* source: 'ecmwf',
* datatype: 'forecast-grib2'
* },
* args: {
* date: '20230101',
* time: '00',
* step: '24', // 24-hour forecast
* param: '167' // 2m Temperature parameter ID
* }
* });
*
* @see https://confluence.ecmwf.int/display/WEBAPI/ECMWF+Web+API
* @type {Object}
* @name ECMWF
* @memberof datasources
*/
const defaultExport = {
/**
* Generates the URL/Endpoint for ECMWF data based on user arguments.
* @param {Object} args - Arguments for the request
* @param {string} dataType - Type of data requested (mapped to dataset key)
* @returns {string} Endpoint URL
*/
sourceType: function (args, dataType) {
console.log(`[ECMWF Debug] sourceType called with dataType: ${dataType}`);
// Default to era5-grib2 if not specified or known, similar to chirps
// Note: dataType here corresponds to 'dataset' in ecmwf config usually
// Check if this.datasets is accessible
if (!this.datasets) {
console.error("[ECMWF Debug] this.datasets is undefined!");
// Fallback to accessing via the variable if 'this' context is lost (though it shouldn't be)
if (defaultExport && defaultExport.datasets) {
console.log("[ECMWF Debug] Recovered datasets from defaultExport variable.");
return defaultExport.sourceType(args, dataType); // Be careful of recursion if context matches
}
}
const datasetKey = (dataType && this.datasets[dataType]) ? dataType : "era5-grib2";
console.log(`[ECMWF Debug] Resolved datasetKey: ${datasetKey}`);
const config = this.datasets[datasetKey];
if (!config) {
throw new Error(`ECMWF Dataset '${dataType}' is not supported or invalid.`);
}
console.log(`[ECMWF Debug] Config endpoint: ${config.endpoint}`);
// Auto-construct full resource URL for CDS API
if (config.endpoint.includes('cds.climate.copernicus.eu') && config.params && config.params.dataset) {
const fullUrl = `${config.endpoint}/resources/${config.params.dataset}`;
console.log(`[ECMWF Debug] Constructed full URL: ${fullUrl}`);
return fullUrl;
}
return config.endpoint;
},
datasets: {
// Get MARS data (Meteorological Archival and Retrieval System)
"mars-data": {
endpoint: "https://api.ecmwf.int/v1/services/mars/requests",
params: {
dataset: null,
date: null,
expver: null,
levtype: null,
param: null,
step: null,
stream: null,
time: null,
type: null,
target: null,
format: null,
area: null
},
methods: {
type: "json",
method: "POST"
}
},
// Get data from the ERA5 reanalysis dataset
"era5": {
endpoint: "https://api.ecmwf.int/v1/services/cds/datasets/reanalysis-era5-single-levels",
params: {
product_type: null,
format: null,
variable: null,
year: null,
month: null,
day: null,
time: null,
area: null
},
methods: {
type: "json",
method: "POST"
}
},
// Get seasonal forecast data
"seasonal-forecast": {
endpoint: "https://api.ecmwf.int/v1/services/cds/datasets/seasonal-monthly-single-levels",
params: {
originating_centre: null,
system: null,
variable: null,
product_type: null,
year: null,
month: null,
leadtime_month: null,
format: null
},
methods: {
type: "json",
method: "POST"
}
},
// Get climate projections data
"climate-projections": {
endpoint: "https://api.ecmwf.int/v1/services/cds/datasets/projections-cmip6",
params: {
format: null,
experiment: null,
temporal_resolution: null,
variable: null,
model: null,
date: null,
area: null
},
methods: {
type: "json",
method: "POST"
}
},
// ECMWF GRIB2 data access (direct file access)
"grib2-data": {
endpoint: null, // Dynamic endpoint based on product type
params: {
product: null, // Product type: 'oper', 'enfo', 'wave', 'seasonal', 'monthly'
date: null, // Date in YYYYMMDD format
time: null, // Time in HH format
step: null, // Forecast step
param: null, // Parameter code
levtype: null, // Level type: 'sfc', 'pl', 'ml', 'pt', 'pv'
levelist: null, // Level values
area: null, // Area specification
grid: null, // Grid resolution
format: "grib2" // Always GRIB2 for this endpoint
},
methods: {
type: "binary",
method: "GET"
}
},
// Explicit raw-grib2 config as specific alias for direct retrieval testing
"raw-grib2": {
endpoint: "https://cds.climate.copernicus.eu/api/v2",
params: {
dataset: "reanalysis-era5-single-levels",
product_type: "reanalysis",
format: "grib",
},
methods: {
type: "binary",
method: "POST"
}
},
// Enhanced ERA5 data with GRIB2 format option
"era5-grib2": {
endpoint: "https://cds.climate.copernicus.eu/api/v2",
params: {
dataset: "reanalysis-era5-single-levels",
product_type: "reanalysis",
format: "grib",
variable: null,
year: null,
month: null,
day: null,
time: null,
area: null
},
methods: {
type: "json",
method: "POST"
}
},
// ECMWF forecast data in GRIB2 format
"forecast-grib2": {
endpoint: "https://api.ecmwf.int/v1/services/mars/requests",
params: {
class: "od", // Operational dissemination
date: null,
expver: "1",
levtype: null,
param: null,
step: null,
stream: null, // oper, enfo, wave
time: null,
type: "fc", // Forecast
target: null,
format: "grib2",
area: null
},
methods: {
type: "json",
method: "POST"
}
},
// Point data extraction - single location, single variable
"point-data": {
endpoint: null, // Dynamic endpoint based on dataset
params: {
dataset: null, // Dataset identifier (e.g., "era5")
variable: null, // Variable name (e.g., "2m_temperature", "total_precipitation")
latitude: null, // Single latitude coordinate
longitude: null, // Single longitude coordinate
startDate: null, // ISO date string
endDate: null, // ISO date string
format: null // Output format: "json", "csv", "netcdf"
},
methods: {
type: "json",
method: "GET"
}
},
// Grid data extraction - spatial subset
"grid-data": {
endpoint: null, // Dynamic endpoint based on dataset
params: {
dataset: null, // Dataset identifier
variable: null, // Variable name
bbox: null, // Bounding box: [west, south, east, north]
startDate: null, // ISO date string
endDate: null, // ISO date string
format: null // Output format
},
methods: {
type: "json",
method: "GET"
}
},
// Time series extraction - single location, time series
"timeseries-data": {
endpoint: null, // Dynamic endpoint based on dataset
params: {
dataset: null, // Dataset identifier
variable: null, // Variable name
latitude: null, // Single latitude coordinate
longitude: null, // Single longitude coordinate
startDate: null, // ISO date string
endDate: null, // ISO date string
format: null // Output format
},
methods: {
type: "json",
method: "GET"
}
},
// Available variables
"available-variables": {
endpoint: null,
params: {},
methods: {
type: "json",
method: "GET"
}
}
},
requirements: {
needProxy: true, // ECMWF data should use proxy for CORS
requireskey: true,
keyname: "key",
},
info: {
returnFormats: "grib, grib2, netcdf, json",
MoreInfo: "https://confluence.ecmwf.int/display/WEBAPI/ECMWF+Web+API",
About: "European Centre for Medium-Range Weather Forecasts (ECMWF) API provides access to various weather and climate data products including GRIB2 format support. Requires registration and an API key."
},
"endpoint-info": {
"mars-data": {
paramFormat: {
dataset: "String - Dataset name (e.g., 'oper', 'era5')",
date: "String - Date in YYYYMMDD format",
expver: "String - Experiment version",
levtype: "String - Level type (e.g., 'sfc' for surface)",
param: "String - Parameter(s) to retrieve (e.g., 't2m,tp')",
step: "String - Forecast step(s)",
stream: "String - Stream type (e.g., 'oper', 'enfo')",
time: "String - Time of day in HH:MM format",
type: "String - Type of data (e.g., 'an' for analysis, 'fc' for forecast)",
target: "String - Target filename",
format: "String - Output format (e.g., 'grib', 'netcdf')",
area: "String - Geographic area [north, west, south, east]"
},
infoSource: "https://confluence.ecmwf.int/display/WEBAPI/MARS+service",
example: {
dataset: "era5",
date: "20200101",
levtype: "sfc",
param: "t2m",
target: "output.grib",
exampleRequest: "POST to https://api.ecmwf.int/v1/services/mars/requests with parameters: {'dataset': 'era5', 'date': '20200101', 'levtype': 'sfc', 'param': 't2m', 'target': 'output.grib'}"
}
},
"era5": {
paramFormat: {
product_type: "String - Product type (e.g., 'reanalysis')",
format: "String - Output format (e.g., 'grib', 'netcdf')",
variable: "Array - Variables to retrieve (e.g., ['2m_temperature', 'total_precipitation'])",
year: "String/Array - Year(s) to retrieve data for",
month: "String/Array - Month(s) to retrieve data for",
day: "String/Array - Day(s) to retrieve data for",
time: "String/Array - Time(s) of day (e.g., ['00:00', '12:00'])",
area: "Array - Geographic area [north, west, south, east]"
},
infoSource: "https://confluence.ecmwf.int/display/CKB/ERA5%3A+data+documentation",
example: {
product_type: "reanalysis",
variable: ["2m_temperature"],
year: "2020",
month: "01",
day: "01",
time: ["00:00", "12:00"],
format: "netcdf",
exampleRequest: "POST to https://api.ecmwf.int/v1/services/cds/datasets/reanalysis-era5-single-levels with parameters: {'product_type': 'reanalysis', 'variable': ['2m_temperature'], 'year': '2020', 'month': '01', 'day': '01', 'time': ['00:00', '12:00'], 'format': 'netcdf'}"
}
},
"seasonal-forecast": {
paramFormat: {
originating_centre: "String - Originating center (e.g., 'ecmwf')",
system: "String - System version",
variable: "Array - Variables to retrieve",
product_type: "String - Product type (e.g., 'monthly_mean')",
year: "String/Array - Year(s) to retrieve data for",
month: "String/Array - Month(s) to retrieve data for",
leadtime_month: "String/Array - Lead time in months",
format: "String - Output format"
},
infoSource: "https://confluence.ecmwf.int/display/CKB/Seasonal+forecasts+and+the+Copernicus+Climate+Change+Service",
example: {
originating_centre: "ecmwf",
variable: ["2m_temperature"],
product_type: "monthly_mean",
year: "2020",
month: "01",
leadtime_month: ["1", "2", "3"],
format: "netcdf",
exampleRequest: "POST to https://api.ecmwf.int/v1/services/cds/datasets/seasonal-monthly-single-levels with parameters: {'originating_centre': 'ecmwf', 'variable': ['2m_temperature'], 'product_type': 'monthly_mean', 'year': '2020', 'month': '01', 'leadtime_month': ['1', '2', '3'], 'format': 'netcdf'}"
}
},
"climate-projections": {
paramFormat: {
format: "String - Output format (e.g., 'zip', 'netcdf')",
experiment: "String - Experiment name (e.g., 'historical', 'ssp5_8_5')",
temporal_resolution: "String - Temporal resolution (e.g., 'monthly', 'daily')",
variable: "Array - Variables to retrieve",
model: "String - Climate model name",
date: "String - Date range",
area: "Array - Geographic area [north, west, south, east]"
},
infoSource: "https://confluence.ecmwf.int/display/CKB/CMIP6%3A+Global+climate+projections",
example: {
experiment: "historical",
temporal_resolution: "monthly",
variable: ["near_surface_air_temperature"],
model: "mpi_esm1_2_hr",
date: "2000-2010",
format: "netcdf",
exampleRequest: "POST to https://api.ecmwf.int/v1/services/cds/datasets/projections-cmip6 with parameters: {'experiment': 'historical', 'temporal_resolution': 'monthly', 'variable': ['near_surface_air_temperature'], 'model': 'mpi_esm1_2_hr', 'date': '2000-2010', 'format': 'netcdf'}"
}
},
"grib2-data": {
paramFormat: {
product: "String - Product type ('oper', 'enfo', 'wave', 'seasonal', 'monthly')",
date: "String - Date in YYYYMMDD format",
time: "String - Time in HH format (e.g., '00', '12')",
step: "String - Forecast step in hours (e.g., '0', '6', '12')",
param: "String - GRIB2 parameter code (e.g., '167' for 2m temperature)",
levtype: "String - Level type ('sfc' for surface, 'pl' for pressure levels, 'ml' for model levels)",
levelist: "String - Level values (for non-surface data)",
area: "String - Geographic area [north, west, south, east]",
grid: "String - Grid resolution (e.g., '0.25/0.25' for 0.25 degree)",
format: "String - Always 'grib2'"
},
infoSource: "https://confluence.ecmwf.int/display/UDOC/GRIB2+parameter+codes",
example: {
product: "oper",
date: "20240101",
time: "00",
step: "0",
param: "167",
levtype: "sfc",
area: "60/-10/50/5", // Europe region
grid: "0.25/0.25",
format: "grib2",
exampleRequest: "Retrieve surface temperature from operational forecast for Europe"
}
},
"era5-grib2": {
paramFormat: {
dataset: "String - Dataset identifier (usually 'reanalysis-era5-single-levels')",
product_type: "String - Product type ('reanalysis')",
format: "String - 'grib' for GRIB2 format",
variable: "Array - Variable names (e.g., ['2m_temperature', 'total_precipitation'])",
year: "String/Array - Year(s) to retrieve",
month: "String/Array - Month(s) to retrieve",
day: "String/Array - Day(s) to retrieve",
time: "String/Array - Time(s) of day",
area: "Array - Geographic area [north, west, south, east]"
},
infoSource: "https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-single-levels",
example: {
dataset: "reanalysis-era5-single-levels",
product_type: "reanalysis",
format: "grib",
variable: ["2m_temperature", "total_precipitation"],
year: "2020",
month: "01",
day: "01",
time: ["00:00", "12:00"],
area: [60, -10, 50, 5], // Europe region
exampleRequest: "Retrieve ERA5 temperature and precipitation data in GRIB2 format for January 1, 2020"
}
},
"forecast-grib2": {
paramFormat: {
class: "String - Data class ('od' for operational dissemination)",
date: "String - Forecast date in YYYYMMDD format",
expver: "String - Experiment version ('1' for operational)",
levtype: "String - Level type ('sfc', 'pl', 'ml')",
param: "String - GRIB2 parameter code",
step: "String/Array - Forecast steps in hours",
stream: "String - Data stream ('oper' for operational, 'enfo' for ensemble)",
time: "String - Forecast base time in HH format",
type: "String - Data type ('fc' for forecast)",
target: "String - Output filename",
format: "String - 'grib2'",
area: "String - Geographic area [north, west, south, east]"
},
infoSource: "https://confluence.ecmwf.int/display/UDOC/MARS+user+documentation",
example: {
class: "od",
date: "20240101",
expver: "1",
levtype: "sfc",
param: "167",
step: "6",
stream: "oper",
time: "00",
type: "fc",
target: "forecast.grib2",
format: "grib2",
area: "60/-10/50/5",
exampleRequest: "Retrieve 6-hour surface temperature forecast for Europe in GRIB2 format"
}
}
}
};
export default defaultExport;