Selasa, 16 Juni 2026
Mengapa Transpor Uap Air Penting
Indonesia berada di atas Indo-Pacific Warm Pool, salah satu sumber uap air terbesar di Bumi. Uap air ini tidak hanya menentukan curah hujan lokal — ia juga bergerak secara horizontal melintasi ribuan kilometer dalam apa yang dikenal sebagai atmospheric river (AR): koridor sempit dan panjang yang mengangkut uap air secara masif melalui atmosfer.
Menurut NOAA, AR bertanggung jawab atas lebih dari 90% transpor uap air ke mid-latitudes dari daerah tropis. Sebuah AR yang kuat bisa mengangkut uap air setara 7,5–15 kali debit rata-rata Sungai Mississippi. Metrik standar untuk mendeteksi dan mengkarakterisasi AR adalah Integrated Water Vapor Transport (IVT), yaitu fluks vertikal uap air yang terintegrasi sepanjang kolom atmosfer.
Bagi wilayah seperti Indonesia, memahami transpor uap air berarti memahami bagaimana monsun, ENSO, IOD, dan MJO secara bersama-sama mengendalikan distribusi kelembaban dan presipitasi ekstrem di Maritime Continent. Tutorial ini menunjukkan cara menghitung IVT dari data ERA5 menggunakan Python, langkah demi langkah.
Sumber: NASA Earth Observatory (halaman sumber)
Konsep Dasar: IWV, TCWV, dan IVT
Sebelum masuk ke kode, kita perlu memperjelas tiga kuantitas yang sering muncul dalam literatur transpor kelembaban.
Integrated Water Vapor (IWV) — juga disebut Total Column Water Vapor (TCWV) atau precipitable water — adalah jumlah total massa uap air dalam satu kolom atmosfer per satuan luas, dalam satuan \(\text{kg m}^{-2}\) (yang secara numerik setara dengan milimeter air tercurahkan). ERA5 menyediakan TCWV sebagai variabel single-level yang sudah dihitung oleh IFS.
Specific humidity (\(q\), satuan \(\text{kg kg}^{-1}\)) adalah rasio massa uap air terhadap massa udara lembap pada satu level tekanan tertentu. Ini adalah variabel mentah yang tersedia di ERA5 pada setiap pressure level dari 1000 hPa hingga 1 hPa.
Integrated Water Vapor Transport (IVT) adalah kuantitas vektor (satuan \(\text{kg m}^{-1} \text{s}^{-1}\)) yang mengukur fluks horizontal uap air yang terintegrasi sepanjang kolom atmosfer. Komponen-komponennya didefinisikan sebagai:
$$\text{IVT}_u = -\frac{1}{g} \int_{p_\text{top}}^{p_\text{sfc}} q \cdot u \; dp$$
$$\text{IVT}_v = -\frac{1}{g} \int_{p_\text{top}}^{p_\text{sfc}} q \cdot v \; dp$$
dengan \(g = 9{,}80665\ \text{m s}^{-2}\), dan integral dijalankan dari permukaan (~1000 hPa) hingga ~200–300 hPa. Besaran IVT dihitung sebagai \(|\text{IVT}| = \sqrt{\text{IVT}_u^2 + \text{IVT}_v^2}\).
NOAA menggunakan ambang batas IVT sebesar 250–500 \(\text{kg m}^{-1} \text{s}^{-1}\) dalam teknik deteksi AR otomatis. Dalam tutorial ini kita menggunakan dua level tekanan (500 dan 850 hPa) sebagai aproksimasi dua-titik — pendekatan pedagogis yang cukup untuk menangkap pola utama transpor kelembaban. Sistem produksi biasanya mengintegrasikan 8–10 level dari 1000 hingga 300 hPa.
Persiapan Data: Unduh ERA5 dengan cdsapi
Kita butuh tiga variabel ERA5 pada pressure level 500 dan 850 hPa: specific humidity (\(q\)), komponen zonal angin (\(u\)), dan komponen meridional angin (\(v\)). Semua tersedia melalui produk reanalysis-era5-pressure-levels di Copernicus Climate Data Store (CDS). Untuk mendaftar akun CDS dan menginstal cdsapi, kunjungi cds.climate.copernicus.eu.
Snippet berikut men-download ketiga file untuk tahun 2024 atas Indonesia (6°N–11°S, 95°E–141°E), lalu membukanya dengan xarray. Guard if not os.path.exists(OUT) memastikan download hanya terjadi sekali — kalau file sudah ada di direktori kerja, snippet langsung lanjut ke pembacaan data.
import os
import cdsapi
import xarray as xr
# --- specific humidity (q) at 500 and 850 hPa ---
OUT_Q = "era5_q_pl500-850_indonesia_2024_d.nc"
if not os.path.exists(OUT_Q):
c = cdsapi.Client(quiet=True)
c.retrieve(
"reanalysis-era5-pressure-levels",
{
"product_type": "reanalysis",
"variable": ["specific_humidity"],
"pressure_level": ["500", "850"],
"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"],
"area": [6, 95, -11, 141],
"format": "netcdf",
},
OUT_Q,
)
# --- u-component of wind at 500 and 850 hPa ---
OUT_U = "era5_u_pl500-850_indonesia_2024_d.nc"
if not os.path.exists(OUT_U):
c = cdsapi.Client(quiet=True)
c.retrieve(
"reanalysis-era5-pressure-levels",
{
"product_type": "reanalysis",
"variable": ["u_component_of_wind"],
"pressure_level": ["500", "850"],
"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"],
"area": [6, 95, -11, 141],
"format": "netcdf",
},
OUT_U,
)
# --- v-component of wind at 500 and 850 hPa ---
OUT_V = "era5_v_pl500-850_indonesia_2024_d.nc"
if not os.path.exists(OUT_V):
c = cdsapi.Client(quiet=True)
c.retrieve(
"reanalysis-era5-pressure-levels",
{
"product_type": "reanalysis",
"variable": ["v_component_of_wind"],
"pressure_level": ["500", "850"],
"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"],
"area": [6, 95, -11, 141],
"format": "netcdf",
},
OUT_V,
)
ds_q = xr.open_dataset(OUT_Q)
ds_u = xr.open_dataset(OUT_U)
ds_v = xr.open_dataset(OUT_V)
print("q dims:", dict(ds_q.dims))
print("u dims:", dict(ds_u.dims))
print("v dims:", dict(ds_v.dims))
print("pressure levels:", ds_q["pressure_level"].values if "pressure_level" in ds_q.dims else ds_q["level"].values)
q dims: {'valid_time': 366, 'pressure_level': 2, 'latitude': 69, 'longitude': 185}
u dims: {'valid_time': 366, 'pressure_level': 2, 'latitude': 69, 'longitude': 185}
v dims: {'valid_time': 366, 'pressure_level': 2, 'latitude': 69, 'longitude': 185}
pressure levels: [850. 500.]
Tiga dataset ini masing-masing memiliki dimensi (valid_time, pressure_level, latitude, longitude). Sepanjang tutorial, kita bekerja pada 366 hari × 2 level × grid Indonesia (2024 adalah tahun kabisat).
Menghitung Integrated Water Vapor (IWV) dari ERA5
IWV (atau TCWV) adalah integral vertikal \(q\) di sepanjang kolom. Dengan hanya dua level tersedia (500 dan 850 hPa), kita gunakan pendekatan trapezoidal sederhana:
$$\text{IWV}_{\text{approx}} = \frac{1}{g} \cdot \frac{q_{850} + q_{500}}{2} \cdot \Delta p$$
di mana \(\Delta p = (850 - 500) \times 100 = 35000\ \text{Pa}\) dan \(g = 9{,}80665\ \text{m s}^{-2}\). Hasilnya dalam \(\text{kg m}^{-2}\).
Catatan: ini adalah aproksimasi yang hanya menangkap lapisan 500–850 hPa, bukan seluruh kolom atmosfer. ERA5 juga menyediakan variabel total_column_water_vapour (TCWV) sebagai produk single-level yang mencakup seluruh kolom — cara termudah untuk mendapatkan IWV referensi jika kita membutuhkan akurasi penuh.
Snippet berikut menghitung IWV aproksimasi untuk rata-rata Januari 2024 dan mencetak statistiknya.
import numpy as np
import xarray as xr
# Muat ulang dataset (shared globals sudah tersedia, tapi re-open untuk kejelasan)
ds_q = xr.open_dataset("era5_q_pl500-850_indonesia_2024_d.nc")
# Tentukan variabel specific humidity
q_var = [v for v in ds_q.data_vars][0] # biasanya 'q' atau 'specific_humidity'
q = ds_q[q_var]
# Deteksi nama dimensi level tekanan
lev_dim = "pressure_level" if "pressure_level" in q.dims else "level"
g = 9.80665 # m s⁻²
dp = 35000.0 # Pa (850 - 500) hPa
# Deteksi nama dimensi waktu (ERA5 NetCDF dari CDS bisa pakai 'time' atau 'valid_time')
time_dim = "valid_time" if "valid_time" in q.dims else "time"
# Ekstrak bulan Januari 2024 lalu rata-ratakan
q_jan = q.sel({time_dim: getattr(q, time_dim).dt.month == 1})
q_jan_mean = q_jan.mean(dim=time_dim)
q_850 = q_jan_mean.sel({lev_dim: 850})
q_500 = q_jan_mean.sel({lev_dim: 500})
# Aproksimasi trapezoidal IWV
IWV = (1.0 / g) * 0.5 * (q_850 + q_500) * dp
print(f"IWV approx (Jan 2024) — min: {float(IWV.min()):.2f} mean: {float(IWV.mean()):.2f} max: {float(IWV.max()):.2f} [kg m⁻²]")
IWV approx (Jan 2024) — min: 21.45 mean: 29.36 max: 33.87 [kg m⁻²]
Nilai IWV yang kita cetak mencerminkan kandungan uap air di lapisan 500–850 hPa. Nilai lebih tinggi biasanya ditemukan di atas lautan hangat dan di sepanjang jalur monsun aktif. Perlu diingat bahwa ini hanya sebagian kolom; IWV total dari ERA5 TCWV biasanya 3–5 kali lebih besar karena memperhitungkan uap air di lapisan bawah (1000–850 hPa) yang sangat signifikan di daerah tropis.
Menghitung Integrated Water Vapor Transport (IVT)
Setelah kita punya \(q\), \(u\), dan \(v\) pada dua level tekanan, kita bisa menghitung komponen IVT menggunakan pendekatan trapezoidal yang sama:
$$\text{IVT}_u = \frac{1}{g} \cdot \frac{q_{850} \cdot u_{850} + q_{500} \cdot u_{500}}{2} \cdot \Delta p$$
$$\text{IVT}_v = \frac{1}{g} \cdot \frac{q_{850} \cdot v_{850} + q_{500} \cdot v_{500}}{2} \cdot \Delta p$$
Tanda positif di sini karena kita mengintegrasikan dari atas ke bawah dalam koordinat tekanan; konvensi \(dp > 0\) sudah terpenuhi karena \(p_{850} > p_{500}\).
import numpy as np
import xarray as xr
ds_q = xr.open_dataset("era5_q_pl500-850_indonesia_2024_d.nc")
ds_u = xr.open_dataset("era5_u_pl500-850_indonesia_2024_d.nc")
ds_v = xr.open_dataset("era5_v_pl500-850_indonesia_2024_d.nc")
q_var = [v for v in ds_q.data_vars][0]
u_var = [v for v in ds_u.data_vars][0]
v_var = [v for v in ds_v.data_vars][0]
q = ds_q[q_var]
u = ds_u[u_var]
v = ds_v[v_var]
lev_dim = "pressure_level" if "pressure_level" in q.dims else "level"
g = 9.80665
dp = 35000.0 # Pa
# Deteksi nama dimensi waktu
time_dim = "valid_time" if "valid_time" in q.dims else "time"
# Ambil rata-rata Januari 2024
q_jan = q.sel({time_dim: getattr(q, time_dim).dt.month == 1}).mean(time_dim)
u_jan = u.sel({time_dim: getattr(u, time_dim).dt.month == 1}).mean(time_dim)
v_jan = v.sel({time_dim: getattr(v, time_dim).dt.month == 1}).mean(time_dim)
q850 = q_jan.sel({lev_dim: 850})
q500 = q_jan.sel({lev_dim: 500})
u850 = u_jan.sel({lev_dim: 850})
u500 = u_jan.sel({lev_dim: 500})
v850 = v_jan.sel({lev_dim: 850})
v500 = v_jan.sel({lev_dim: 500})
# Komponen IVT
IVT_u = (1.0 / g) * 0.5 * (q850 * u850 + q500 * u500) * dp
IVT_v = (1.0 / g) * 0.5 * (q850 * v850 + q500 * v500) * dp
# Besaran IVT
IVT_mag = np.sqrt(IVT_u**2 + IVT_v**2)
print(f"IVT magnitude (Jan 2024) — min: {float(IVT_mag.min()):.1f} mean: {float(IVT_mag.mean()):.1f} max: {float(IVT_mag.max()):.1f} [kg m⁻¹ s⁻¹]")
# Lokasi IVT maksimum (argmax pada array numpy menghindari masalah label)
mag_vals = IVT_mag.values
j, i = np.unravel_index(np.argmax(mag_vals), mag_vals.shape)
lat_max = float(IVT_mag.latitude.values[j])
lon_max = float(IVT_mag.longitude.values[i])
print(f"IVT max location: lat={lat_max:.2f}°, lon={lon_max:.2f}°")
print(f"NOAA AR threshold (250 kg m⁻¹ s⁻¹) exceeded at {int((IVT_mag > 250).sum().values)} grid points")
IVT magnitude (Jan 2024) — min: 1.0 mean: 127.9 max: 304.6 [kg m⁻¹ s⁻¹]
IVT max location: lat=-8.75°, lon=133.00°
NOAA AR threshold (250 kg m⁻¹ s⁻¹) exceeded at 799 grid points
Perhatikan bahwa nilai IVT paling tinggi biasanya ditemukan di sepanjang ITCZ dan di atas Laut Jawa atau Laut Flores selama puncak monsun barat (Desember–Maret). Jika ada grid point yang melebihi ambang 250 \(\text{kg m}^{-1} \text{s}^{-1}\), kondisi tersebut mendekati kriteria deteksi AR versi NOAA — meskipun terminologi AR lebih umum digunakan di mid-latitudes.
Visualisasi IVT dan Pola Transpor Uap Air
Peta IVT dengan overlay vektor (quiver) adalah cara paling langsung untuk melihat pola transpor uap air secara spasial: warna menunjukkan besaran transport, panah menunjukkan arah aliran. Snippet berikut membuat peta untuk rata-rata Januari 2024.
import numpy as np
import xarray as xr
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
ds_q = xr.open_dataset("era5_q_pl500-850_indonesia_2024_d.nc")
ds_u = xr.open_dataset("era5_u_pl500-850_indonesia_2024_d.nc")
ds_v = xr.open_dataset("era5_v_pl500-850_indonesia_2024_d.nc")
q_var = [v for v in ds_q.data_vars][0]
u_var = [v for v in ds_u.data_vars][0]
v_var = [v for v in ds_v.data_vars][0]
q = ds_q[q_var]
u = ds_u[u_var]
v = ds_v[v_var]
lev_dim = "pressure_level" if "pressure_level" in q.dims else "level"
g = 9.80665
dp = 35000.0
time_dim = "valid_time" if "valid_time" in q.dims else "time"
q_jan = q.sel({time_dim: getattr(q, time_dim).dt.month == 1}).mean(time_dim)
u_jan = u.sel({time_dim: getattr(u, time_dim).dt.month == 1}).mean(time_dim)
v_jan = v.sel({time_dim: getattr(v, time_dim).dt.month == 1}).mean(time_dim)
q850 = q_jan.sel({lev_dim: 850})
q500 = q_jan.sel({lev_dim: 500})
u850 = u_jan.sel({lev_dim: 850})
u500 = u_jan.sel({lev_dim: 500})
v850 = v_jan.sel({lev_dim: 850})
v500 = v_jan.sel({lev_dim: 500})
IVT_u = (1.0 / g) * 0.5 * (q850 * u850 + q500 * u500) * dp
IVT_v = (1.0 / g) * 0.5 * (q850 * v850 + q500 * v500) * dp
IVT_mag = np.sqrt(IVT_u**2 + IVT_v**2)
lats = IVT_mag.latitude.values
lons = IVT_mag.longitude.values
mag = IVT_mag.values
ivtu = IVT_u.values
ivtv = IVT_v.values
fig, ax = plt.subplots(figsize=(11, 7))
cf = ax.contourf(
lons, lats, mag,
levels=20,
cmap="YlGnBu",
extend="max",
)
cbar = fig.colorbar(cf, ax=ax, orientation="vertical", pad=0.02, shrink=0.85)
cbar.set_label("IVT (kg m⁻¹ s⁻¹)", fontsize=11)
# Quiver — setiap 6 grid point agar panah terbaca
step = 6
ax.quiver(
lons[::step], lats[::step],
ivtu[::step, ::step], ivtv[::step, ::step],
scale=500, width=0.003, color="black", alpha=0.7,
)
ax.set_title("Integrated Water Vapor Transport (IVT) — Indonesia, Januari 2024\n(aproksimasi dua-level: 500 & 850 hPa)", fontsize=12)
ax.set_xlabel("Longitude (°E)", fontsize=10)
ax.set_ylabel("Latitude (°N)", fontsize=10)
ax.set_xlim(lons.min(), lons.max())
ax.set_ylim(lats.min(), lats.max())
plt.tight_layout()
plt.savefig("ivt_map.png", dpi=130, bbox_inches="tight")
plt.close("all")
print("Saved ivt_map.png")
Pada peta di atas, warna biru gelap menandai koridor transpor kelembaban intensitas tinggi. Panah-panah hitam menunjukkan arah aliran IVT: selama monsun barat, kita umumnya melihat aliran dari barat laut (Samudra Hindia) yang memasuki Maritime Continent dan berbalik ke tenggara melewati Laut Jawa dan sekitarnya.
Interpretasi dan Kaitan dengan Monsun Indonesia
Pola IVT yang kita hitung mencerminkan dinamika monsun barat Indonesia (Desember–Maret). Selama fase ini, aliran lintas-ekuatorial membawa uap air dari Samudra Hindia bagian utara dan Samudra Pasifik bagian barat ke Maritime Continent, menghasilkan konvergensi kelembaban yang menggerakkan presipitasi ekstrem.
Variabilitas IVT dari tahun ke tahun sangat dipengaruhi oleh tiga faktor besar: ENSO menggeser lokasi konveksi hangat di Pasifik, sehingga memperkuat atau melemahkan aliran uap air ke Indonesia; IOD (Indian Ocean Dipole) memodulasi gradien SST Samudra Hindia yang pada gilirannya mengubah intensitas aliran monsun; dan MJO menghasilkan variabilitas intra-seasonal yang bisa meningkatkan IVT hingga 2–3 kali lipat selama fase aktif di wilayah Maritime Continent.
Sumber: NOAA Climate.gov (halaman sumber)
Peta di atas, yang diturunkan dari ERA5 tahun 1992–2020 menggunakan metode deteksi Mundhenk et al. 2016, menunjukkan frekuensi kejadian AR di Pasifik timur laut — wilayah referensi di mana konsep AR paling banyak dipelajari. Di wilayah tropis seperti Indonesia, koridor IVT yang analog muncul sebagai "jalur monsun" bukan sebagai AR dalam pengertian teknis klasik, meski secara fisik kedua fenomena ini memiliki mekanisme yang sama.
Untuk analisis lebih lanjut, langkah selanjutnya yang disarankan adalah:
- Integrasi penuh: gunakan 8–10 level tekanan (1000, 925, 850, 700, 600, 500, 400, 300 hPa) untuk IVT yang lebih representatif.
- Kopling dengan presipitasi: bandingkan pola IVT dengan data IMERG atau GPCP untuk menguji hubungan transport–konvergensi–curah hujan.
- Studi ENSO: hitung komposit IVT untuk tahun El Niño vs La Niña di ERA5 dan lihat bagaimana jalur transport kelembaban bergeser.
Eksplorasi artikel meteorologi lainnya di meteo.my.id — kunjungi https://meteo.my.id.
Referensi
- What Are Atmospheric Rivers? — NOAA — Penjelasan NOAA tentang AR sebagai "sungai di langit", peran IVT sebagai metrik deteksi, dan dampak AR terhadap presipitasi.
- About: AR Portal at NOAA Physical Sciences Laboratory — Portal pemantauan AR real-time dari NOAA PSL dengan data IVT dan katalog kejadian AR historis.
- ERA5: Data Documentation — ECMWF Confluence — Dokumentasi resmi ERA5 mencakup variabel pressure-level (q, u, v) dan single-level (TCWV) yang digunakan dalam tutorial ini.
- Atmospheric River Lashes California — NASA Earth Observatory — Studi kasus AR Januari 2023 California dengan peta precipitable water vapor dari NASA GEOS-5.
- When Rivers Reach the Sky — NOAA Climate.gov — Penjelasan frekuensi AR global dari ERA5 dan kaitan AR dengan ENSO, termasuk peta kejadian AR musim dingin.