TANGERANG SELATAN WEATHER

Rabu, 08 Juli 2026

Menghitung Kelembaban Relatif dari Data ERA5

ERA5 adalah reanalysis atmosfer global dari ECMWF yang paling banyak dipakai dalam riset cuaca dan iklim — tapi ada satu variabel yang tidak tersimpan langsung di dalamnya: kelembaban relatif. Tutorial ini menunjukkan cara menurunkan relative humidity (RH) dari dua variabel ERA5 yang tersedia, menggunakan formula Magnus-Tetens dengan Python.

Cups at varying fill levels illustrating relative humidity as fraction of maximum water vapor capacity Sumber: NOAA/NESDIS — What Is Humidity?

Latar Belakang — Mengapa Menghitung Kelembaban Relatif?

RH mengukur seberapa jenuh udara dengan uap air, dinyatakan sebagai persentase dari kapasitas maksimum yang bisa ditampung pada suhu tertentu. Ketika suhu udara sama dengan suhu dewpoint, udara tepat jenuh dan RH mencapai 100%. Udara kering dengan RH rendah mendukung evaporasi cepat, meningkatkan risiko kebakaran lahan, dan menekan konveksi.

ERA5 mengarsipkan lebih dari 240 variabel atmosfer, tapi RH permukaan tidak termasuk di antaranya. ECMWF mendokumentasikan bahwa RH harus diturunkan dari dua variabel instantaneous yang tersedia: suhu udara 2 meter (t2m, parameter ID 167) dan suhu dewpoint 2 meter (d2m, parameter ID 168) — keduanya dalam satuan Kelvin.

Perlu dibedakan antara RH dan specific humidity. RH adalah rasio tekanan uap aktual terhadap tekanan uap jenuh pada suhu yang sama — nilainya bergantung pada suhu, bukan hanya kandungan uap air mutlak. Specific humidity (g/kg) adalah massa uap air per satuan massa udara lembab, tidak bergantung pada suhu. Di kawasan tropis seperti Indonesia, RH tinggi sepanjang tahun karena SST hangat menyuplai uap air melimpah, meskipun specific humidity juga bervariasi antar musim.

Kita akan menggunakan formula Magnus-Tetens dengan koefisien resmi ECMWF — koefisien yang sama dipakai dalam produk AgERA5 — untuk memastikan konsistensi dengan pipeline reanalysis ECMWF sendiri.

Persiapan — Membuka Data ERA5

Kita butuh dua file ERA5: suhu 2m (t2m) dan dewpoint 2m (d2m) untuk Indonesia sepanjang 2024 pada resolusi 6-hourly. Jika belum punya akun CDS, daftar gratis di cds.climate.copernicus.eu dan install cdsapi terlebih dahulu.

Snippet berikut mengecek apakah file sudah ada secara lokal — jika belum, unduh via CDS. Untuk pembaca, proses download berlangsung sekitar 5–15 menit per file tergantung antrean CDS. Setelah kedua file tersedia, kita buka dengan xarray dan inspect strukturnya.

import os, cdsapi, xarray as xr

OUT_T = "era5_t2m_indonesia_2024_6h.nc"
OUT_D = "era5_d2m_indonesia_2024_6h.nc"

_params = {
    "product_type": "reanalysis",
    "year": "2024",
    "month": [f"{m:02d}" for m in range(1, 13)],
    "day":   [f"{d:02d}" for d in range(1, 32)],
    "time":  ["00:00", "06:00", "12:00", "18:00"],
    "area":  [6, 95, -11, 141],    # N, W, S, E — Indonesia
    "format": "netcdf",
}

if not os.path.exists(OUT_T) or not os.path.exists(OUT_D):
    c = cdsapi.Client(quiet=True)
    if not os.path.exists(OUT_T):
        c.retrieve("reanalysis-era5-single-levels",
                   {**_params, "variable": "2m_temperature"}, OUT_T)
    if not os.path.exists(OUT_D):
        c.retrieve("reanalysis-era5-single-levels",
                   {**_params, "variable": "2m_dewpoint_temperature"}, OUT_D)

ds_t = xr.open_dataset(OUT_T)
ds_d = xr.open_dataset(OUT_D)
print("=== 2m Temperature (t2m) ===")
print(ds_t)
print("\n=== 2m Dewpoint (d2m) ===")
print(ds_d)
=== 2m Temperature (t2m) ===
<xarray.Dataset> Size: 75MB
Dimensions:     (valid_time: 1464, latitude: 69, longitude: 185)
Coordinates:
  * valid_time  (valid_time) datetime64[ns] 12kB 2024-01-01 ... 2024-12-31T18...
    expver      (valid_time) <U4 23kB ...
  * latitude    (latitude) float64 552B 6.0 5.75 5.5 5.25 ... -10.5 -10.75 -11.0
  * longitude   (longitude) float64 1kB 95.0 95.25 95.5 ... 140.5 140.8 141.0
    number      int64 8B ...
Data variables:
    t2m         (valid_time, latitude, longitude) float32 75MB ...
Attributes:
    GRIB_centre:             ecmf
    GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
    GRIB_subCentre:          0
    Conventions:             CF-1.7
    institution:             European Centre for Medium-Range Weather Forecasts
    history:                 2026-05-10T03:51 GRIB to CDM+CF via cfgrib-0.9.1...

=== 2m Dewpoint (d2m) ===
<xarray.Dataset> Size: 75MB
Dimensions:     (valid_time: 1464, latitude: 69, longitude: 185)
Coordinates:
  * valid_time  (valid_time) datetime64[ns] 12kB 2024-01-01 ... 2024-12-31T18...
    expver      (valid_time) <U4 23kB ...
  * latitude    (latitude) float64 552B 6.0 5.75 5.5 5.25 ... -10.5 -10.75 -11.0
  * longitude   (longitude) float64 1kB 95.0 95.25 95.5 ... 140.5 140.8 141.0
    number      int64 8B ...
Data variables:
    d2m         (valid_time, latitude, longitude) float32 75MB ...
Attributes:
    GRIB_centre:             ecmf
    GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
    GRIB_subCentre:          0
    Conventions:             CF-1.7
    institution:             European Centre for Medium-Range Weather Forecasts
    history:                 2026-05-10T04:06 GRIB to CDM+CF via cfgrib-0.9.1...

Output di atas menampilkan dimensi dataset — biasanya (valid_time: 1464, latitude: 69, longitude: 185) untuk data 6-hourly selama 2024 di bbox Indonesia. Variabel utama yang kita butuhkan adalah t2m dan d2m, keduanya dalam Kelvin. Catat nama dimensi waktu yang muncul — bisa valid_time atau time tergantung versi API CDS yang digunakan; kita tangani secara dinamis di snippet berikutnya.

Formula Magnus-Tetens untuk Tekanan Uap Jenuh

Dasar perhitungan RH adalah saturation vapor pressure \(e_s\) — tekanan yang diberikan oleh uap air ketika udara tepat jenuh pada suhu tertentu. Formula Magnus-Tetens mendekati \(e_s\) sebagai fungsi suhu Celsius:

$$e_s(T_C) = 6{,}112 \cdot \exp\!\left(\frac{17{,}27 \cdot T_C}{237{,}3 + T_C}\right) \quad \text{(hPa)}$$

Koefisien \(A = 17{,}27\) dan \(B = 237{,}3\ °\text{C}\) adalah konstanta Tetens (1930) yang digunakan ECMWF dalam pipeline AgERA5. Alternatif seperti WMO CIMO (\(A = 17{,}62\), \(B = 243{,}12\)) atau Magnus (\(A = 17{,}67\), \(B = 243{,}5\)) menghasilkan perbedaan RH kurang dari \(0{,}5\%\) dalam rentang suhu meteorologi normal — tapi untuk konsistensi dengan ERA5, kita pakai koefisien ECMWF.

RH didefinisikan sebagai rasio tekanan uap dewpoint terhadap tekanan uap jenuh pada suhu udara:

$$\text{RH} = 100 \times \frac{e_s(T_d)}{e_s(T)}$$

Karena faktor \(6{,}112\) muncul di pembilang dan penyebut, nilainya saling menghilangkan, sehingga implementasinya menjadi:

$$\text{RH} = 100 \times \frac{\exp\!\left(\dfrac{17{,}27 \cdot T_d}{237{,}3 + T_d}\right)}{\exp\!\left(\dfrac{17{,}27 \cdot T}{237{,}3 + T}\right)}$$

di mana \(T\) dan \(T_d\) adalah suhu dan dewpoint dalam Celsius. Konversi dari Kelvin: \(T_C = T_K - 273{,}15\).

Snippet berikut mendefinisikan fungsi \(e_s\) dan mendemonstrasikannya pada beberapa nilai suhu representatif untuk memverifikasi perilaku eksponensialnya:

import numpy as np

def e_s(T_C):
    """
    Saturation vapor pressure (hPa) — Magnus-Tetens formula.
    Coefficients A=17.27, B=237.3 °C (Tetens 1930), per ECMWF AgERA5 ATBD.
    """
    return 6.112 * np.exp(17.27 * T_C / (237.3 + T_C))

temps_C = np.array([-10.0, 0.0, 10.0, 20.0, 30.0, 37.0])
es_vals  = e_s(temps_C)

print(f"{'T (°C)':>8}  {'e_s (hPa)':>10}")
print("-" * 22)
for T, es in zip(temps_C, es_vals):
    print(f"{T:>8.1f}  {es:>10.3f}")
  T (°C)   e_s (hPa)
----------------------
   -10.0       2.859
     0.0       6.112
    10.0      12.288
    20.0      23.398
    30.0      42.458
    37.0      62.789

Terlihat bahwa \(e_s\) tumbuh secara eksponensial: dari sekitar 2–3 hPa di suhu beku hingga lebih dari 60 hPa di suhu 37 °C. Inilah sebabnya udara tropis yang hangat bisa menampung jauh lebih banyak uap air dibanding udara dingin — dan mengapa nilai RH yang sama di daerah tropis mewakili kandungan uap air absolut yang jauh lebih besar.

Global land relative humidity anomaly map for 2013 versus 1981–2010 baseline Sumber: NOAA Climate.gov — 2013 State of the Climate: Humidity, data dari HadISDH / NOCSv2.0

Peta di atas menggambarkan anomali RH global tahun 2013 dibanding rata-rata 1981–2010. Sebagian besar daratan menunjukkan RH di bawah normal, meskipun specific humidity global meningkat — sebab suhu permukaan naik lebih cepat dari kandungan uap air. Fenomena ini penting untuk dipahami sebelum menginterpretasi tren RH dari data reanalysis.

Menghitung Kelembaban Relatif dari ERA5

Dengan fungsi \(e_s\) yang sudah terdefinisi, kita terapkan formula ke seluruh grid ERA5 Indonesia. Xarray mendukung operasi aritmatika elemen-per-elemen langsung pada DataArray, sehingga perhitungan vektorial ini cukup ringkas.

import numpy as np

# Konversi Kelvin → Celsius
T_C  = ds_t["t2m"] - 273.15
Td_C = ds_d["d2m"] - 273.15

# Hitung RH — faktor 6.112 menghilangkan dalam rasio
RH_raw = 100.0 * (
    np.exp(17.27 * Td_C / (237.3 + Td_C)) /
    np.exp(17.27 * T_C  / (237.3 + T_C ))
)

# Periksa nilai di luar rentang fisik sebelum clip
n_above = int((RH_raw > 100).sum())
n_below = int((RH_raw < 0).sum())

# Clip ke [0, 100] %
RH = RH_raw.clip(0, 100)
RH.name = "RH"
RH.attrs["units"] = "%"
RH.attrs["long_name"] = "2m Relative Humidity"

print("Dimensi RH:", dict(zip(RH.dims, RH.shape)))
print(f"\nStatistik RH — seluruh Indonesia, 2024:")
print(f"  Min  : {float(RH.min()):.2f} %")
print(f"  Max  : {float(RH.max()):.2f} %")
print(f"  Mean : {float(RH.mean()):.2f} %")
print(f"  Std  : {float(RH.std()):.2f} %")
print(f"\nNilai RH_raw > 100% (sebelum clip) : {n_above}")
print(f"Nilai RH_raw < 0%   (sebelum clip) : {n_below}")
Dimensi RH: {'valid_time': 1464, 'latitude': 69, 'longitude': 185}

Statistik RH — seluruh Indonesia, 2024:
  Min  : 18.81 %
  Max  : 100.00 %
  Mean : 82.04 %
  Std  : 7.50 %

Nilai RH_raw > 100% (sebelum clip) : 2494
Nilai RH_raw < 0%   (sebelum clip) : 0

Nilai RH di atas 100% secara fisik tidak valid, tapi bisa muncul dalam jumlah kecil ketika dewpoint sedikit melebihi suhu udara akibat rounding numerik dalam data ERA5 — terutama di suhu sub-freezing, di mana formula Magnus-Tetens (yang mengasumsikan saturasi terhadap liquid water) tidak persis mencerminkan tekanan uap jenuh terhadap es. Clip ke [0, 100]% adalah praktik standar operasional.

Di Indonesia, rata-rata RH 2m cenderung tinggi — biasanya 80–90% — mencerminkan iklim tropis lembap dengan penguapan aktif dari permukaan laut dan hutan sepanjang tahun. Variabilitas spasial akan tampak jelas di peta yang kita buat selanjutnya.

Visualisasi Kelembaban Relatif Permukaan

Langkah terakhir adalah memvisualisasikan distribusi spasial RH rata-rata tahunan 2024. Kita rata-ratakan seluruh dimensi waktu lalu plot hasilnya sebagai peta grid menggunakan pcolormesh. Deteksi nama dimensi waktu dilakukan secara dinamis agar kompatibel dengan berbagai versi output CDS API.

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np

# Deteksi nama dimensi waktu
time_dim = "valid_time" if "valid_time" in RH.dims else "time"

# Rata-rata tahunan 2024
RH_mean = RH.mean(dim=time_dim)

lons = RH_mean.longitude.values
lats = RH_mean.latitude.values

fig, ax = plt.subplots(figsize=(13, 5))
pcm = ax.pcolormesh(
    lons, lats, RH_mean.values,
    cmap="YlGnBu",
    vmin=60, vmax=100,
    shading="nearest",
)
cb = fig.colorbar(pcm, ax=ax, label="Kelembaban Relatif (%)",
                  fraction=0.025, pad=0.04)
cb.set_ticks([60, 70, 80, 90, 100])

ax.set_xlabel("Bujur (°E)", fontsize=11)
ax.set_ylabel("Lintang (°)", fontsize=11)
ax.set_title(
    "Rata-rata Tahunan Kelembaban Relatif 2m — Indonesia 2024\n"
    "Sumber data: ERA5 Reanalysis (ECMWF / Copernicus CDS)",
    fontsize=12,
)
ax.set_xlim(95, 141)
ax.set_ylim(-11, 6)
ax.grid(True, linewidth=0.3, alpha=0.5)

plt.tight_layout()
plt.savefig("rh_mean_indonesia_2024.png", dpi=150, bbox_inches="tight")
print("Plot disimpan: rh_mean_indonesia_2024.png")

Peta rata-rata tahunan kelembaban relatif 2 meter di Indonesia tahun 2024, dihitung dari ERA5

Peta menampilkan distribusi RH rata-rata sepanjang 2024. Kita biasanya akan melihat RH tinggi di atas laut dan wilayah berhutan lebat (Kalimantan, Papua bagian barat), sementara daerah seperti Nusa Tenggara Timur cenderung menunjukkan nilai lebih rendah — mencerminkan pengaruh musim kemarau yang lebih panjang dan tutupan vegetasi yang lebih rapat. Gradien antara wilayah barat dan timur Indonesia juga menggambarkan perbedaan paparan monsun.

Langkah Selanjutnya — Eksplorasi Lebih Lanjut

Dengan DataArray RH yang kita hasilkan, ada banyak arah eksplorasi yang menarik:

  • Variasi musiman: rata-ratakan per bulan (RH.groupby("valid_time.month").mean()) untuk melihat kontras musim hujan (DJF) vs kemarau (JJA) di berbagai wilayah.
  • Regional hotspot: subsetting dengan .sel(latitude=slice(-10, -5), longitude=slice(115, 125)) untuk Nusa Tenggara, atau Kalimantan, untuk studi kelembaban regional.
  • Kaitan dengan konveksi: kombinasikan RH dengan CAPE dari data ERA5 pressure-level (era5_t_pl500-850_indonesia_2024_d.nc) untuk mengidentifikasi kondisi pra-konvektif.
  • Profil vertikal: ERA5 juga menyimpan specific humidity pada beberapa level tekanan. Dari sana, RH profil vertikal bisa diturunkan dengan formula yang sama, memberi gambaran struktur termodinamika kolom atmosfer.

Pemahaman tentang RH di lapisan bawah troposfer juga punya implikasi lebih luas. Di upper troposphere, RH memainkan peran kunci dalam radiative forcing karena uap air di ketinggian tersebut adalah greenhouse gas efektif — perubahan kecil dalam RH lapisan atas punya dampak besar pada energy budget bumi.

False-color satellite map of upper troposphere relative humidity over tropical regions Sumber: NASA Earth Observatory — Relative Humidity in the Upper Troposphere; image oleh Robert Simmon, NASA; data dari Andy Dessler (NASA GSFC) dan Ken Minschwaner (New Mexico Institute of Mining and Technology)

Peta false-color di atas — dari satelit UARS — menunjukkan RH di ketinggian 10–14 km di kawasan tropis. Pola biru (RH tinggi) menandai jalur konveksi dalam yang terkait dengan ITCZ, sementara merah (RH sangat rendah) menandai subsiden di sekitarnya. Pola ini menunjukkan betapa kuat koneksi antara RH permukaan, konveksi, dan humidity di lapisan atas.

Eksplorasi artikel meteorologi lainnya di meteo.my.id — kunjungi meteo.my.id.

Referensi

Tidak ada komentar:

Posting Komentar