Shear angin vertikal adalah salah satu faktor lingkungan paling penting dalam prakiraan intensitas siklon tropis (TC). Seorang forecaster yang memantau perkembangan TC di Samudra Pasifik barat atau Samudra Hindia selatan selalu memeriksa berapa besar wind shear di sekitar sistem sebelum memproyeksikan apakah badai akan menguat atau melemah. Tutorial ini mengajarkan cara menghitung wind shear 500–850 hPa dari data ERA5 menggunakan Python dan xarray, memetakannya dengan cartopy, lalu mengklasifikasikannya ke dalam rezim operasional. Di bagian akhir kita juga membahas cara mengakses data GFS real-time dari NOMADS untuk analisis serupa.
Pengenalan Shear Angin dan Peran GFS
Wind shear vertikal, atau dalam bahasa operasional sering disebut cukup "shear", adalah perbedaan vektor angin horizontal antara dua level tekanan berbeda. American Meteorological Society (AMS) mendefinisikannya sebagai variasi (biasanya turunan arah) dari medan vektor angin sepanjang suatu arah di ruang. Dalam konteks prakiraan TC, shear konvensional dihitung sebagai selisih vektor antara angin di 200 hPa (troposfer atas) dan 850 hPa (troposfer bawah) — disebut deep-layer shear (DLS).
Secara operasional, GFS menjadi model utama yang dipakai untuk mengevaluasi shear karena tersedia real-time empat kali sehari (siklus 00, 06, 12, 18 UTC), resolusi 0,25°, dan dapat diakses langsung dari NOMADS NCEP tanpa registrasi. Output GFS digunakan oleh Climate Prediction Center (CPC) NOAA untuk memproduksi peta 200–850 hPa shear 10-hari yang menjadi referensi standar bagi para forecaster TC di seluruh dunia.
Relevansinya untuk Indonesia sangat konkret. Kawasan maritim kontinen Indonesia berada di persimpangan dua basin TC aktif — Samudra Pasifik barat dan Samudra Hindia selatan. Pemantauan shear di wilayah ini membantu forecaster menilai potensi pembentukan TC dan mengevaluasi risiko penerbangan (low-level wind shear, LLWS) di bandara-bandara pesisir.
Konsep Shear Angin Vertikal
Secara formal, deep-layer shear didefinisikan sebagai:
$$\vec{S} = \vec{V}_{200} - \vec{V}_{850}$$
dan magnitudonya:
$$|\vec{S}| = \sqrt{(\Delta u)^2 + (\Delta v)^2}$$
di mana \(\Delta u = u_{200} - u_{850}\) dan \(\Delta v = v_{200} - v_{850}\).
Tanda hasilnya tidak berubah apabila urutan pengurangan dibalik (850 − 200) karena kita mengambil magnitude. Yang penting adalah konsistensi — gunakan selalu \(\vec{V}_{\text{atas}} - \vec{V}_{\text{bawah}}\).
Threshold operasional yang dipakai secara luas adalah:
- < 8 m/s: favorable untuk perkembangan TC — ini adalah threshold yang dipakai CPC dalam produk shear 10-harinya
- < 10 m/s (~20 kt): soft limit yang digunakan model SHIPS (Statistical Hurricane Intensity Prediction System) dari AOML/NOAA; probabilitas rapid intensification (RI) paling tinggi di bawah nilai ini
- > 10 m/s: inhibitory — shear mulai "merobekkan" vortex TC secara vertikal, mengganggu simetri eyewall, dan membawa udara kering ke dalam core badai
Untuk kepentingan tutorial ini, kita akan menghitung 500–850 hPa shear (low-to-mid-layer) menggunakan data ERA5 2024. Ini bukan DLS standar (yang butuh 200 hPa), melainkan representasi yang valid untuk menganalisis angin jet tingkat rendah dan interaksi monsun–TC di kawasan Indonesia. Matematika vektornya persis sama.
Skema kalkulasi wind shear vertikal dan klasifikasi rezim operasional berdasarkan threshold CPC dan SHIPS/AOML.
Mengunduh Data Tekanan Level dari ERA5
Data yang kita butuhkan adalah komponen u-wind dan v-wind di level tekanan 500 dan 850 hPa untuk domain Indonesia. Kita download dari CDS (Climate Data Store) Copernicus menggunakan cdsapi. Untuk mendaftar akun CDS dan mengonfigurasi .cdsapirc, kunjungi cds.climate.copernicus.eu.
Download dilakukan sekali saja — setelah file ada di direktori kerja, snippet berikutnya langsung membaca dari file lokal tanpa perlu koneksi lagi.
import os
import cdsapi
import xarray as xr
OUT_U = "era5_u_pl500-850_indonesia_2024_d.nc"
OUT_V = "era5_v_pl500-850_indonesia_2024_d.nc"
# Download u-wind jika belum ada
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,
)
# Download v-wind jika belum ada
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_u = xr.open_dataset(OUT_U)
ds_v = xr.open_dataset(OUT_V)
# Tangani nama dimensi waktu (valid_time atau time)
time_dim_u = "valid_time" if "valid_time" in ds_u.dims else "time"
time_dim_v = "valid_time" if "valid_time" in ds_v.dims else "time"
print("=== u-wind dataset ===")
print(f"Dims : {dict(ds_u.dims)}")
print(f"Vars : {list(ds_u.data_vars)}")
print(f"Levels: {ds_u['pressure_level'].values.tolist()} hPa")
print(f"Time range: {str(ds_u[time_dim_u].values[0])[:10]} — {str(ds_u[time_dim_u].values[-1])[:10]}")
print()
print("=== v-wind dataset ===")
print(f"Dims : {dict(ds_v.dims)}")
print(f"Vars : {list(ds_v.data_vars)}")
=== u-wind dataset ===
Dims : {'valid_time': 366, 'pressure_level': 2, 'latitude': 69, 'longitude': 185}
Vars : ['u']
Levels: [850.0, 500.0] hPa
Time range: 2024-01-01 — 2024-12-31
=== v-wind dataset ===
Dims : {'valid_time': 366, 'pressure_level': 2, 'latitude': 69, 'longitude': 185}
Vars : ['v']
Kedua file tersebut berisi data harian pukul 00 UTC sepanjang tahun 2024 untuk domain Indonesia (6°N–11°S, 95°E–141°E) pada dua level tekanan (500 dan 850 hPa). Ukuran file masing-masing sekitar 30–50 MB — cukup kecil untuk disimpan lokal dan dibaca berulang kali.
Menghitung Magnitude Shear Angin
Dengan dataset di tangan, kita ekstrak komponen angin di masing-masing level lalu hitung shear vektornya. Formula yang diimplementasikan:
$$|\vec{S}_{500\text{–}850}| = \sqrt{(u_{500} - u_{850})^2 + (v_{500} - v_{850})^2}$$
import numpy as np
# Tentukan nama dimensi waktu
time_dim = "valid_time" if "valid_time" in ds_u.dims else "time"
# Ekstrak komponen per level
u500 = ds_u["u"].sel(pressure_level=500)
u850 = ds_u["u"].sel(pressure_level=850)
v500 = ds_v["v"].sel(pressure_level=500)
v850 = ds_v["v"].sel(pressure_level=850)
# Pastikan koordinat waktu selaras
u500 = u500.assign_coords({time_dim: ds_v[time_dim]}) if time_dim in ds_v.coords else u500
# Hitung komponen shear dan magnitude
du = u500.values - u850.values
dv = v500.values - v850.values
shear_mag = np.sqrt(du**2 + dv**2) # shape: (time, lat, lon)
# Statistik domain — mean dan max sepanjang 2024
domain_mean = float(np.nanmean(shear_mag))
domain_max = float(np.nanmax(shear_mag))
print(f"Domain mean shear (500–850 hPa, 2024) : {domain_mean:.2f} m/s")
print(f"Domain max shear (500–850 hPa, 2024) : {domain_max:.2f} m/s")
print()
# Monthly mean (rata-rata spasial per bulan)
time_vals = ds_u[time_dim].values
import pandas as pd
months = pd.DatetimeIndex(time_vals).month
print("Monthly domain-mean shear (m/s):")
print(f"{'Bulan':<8}", end="")
for m in range(1, 13):
mask = months == m
if mask.sum() > 0:
val = float(np.nanmean(shear_mag[mask]))
print(f" {m:02d}: {val:.2f}", end="")
print()
print()
print("Threshold reference:")
print(" < 8 m/s → favorable TC development (CPC operational threshold)")
print(" < 10 m/s → rapid intensification possible (SHIPS/AOML soft limit)")
print(" > 10 m/s → generally inhibitory for TC intensification")
Domain mean shear (500–850 hPa, 2024) : 6.18 m/s
Domain max shear (500–850 hPa, 2024) : 36.73 m/s
Monthly domain-mean shear (m/s):
Bulan 01: 5.60 02: 5.81 03: 6.12 04: 5.06 05: 6.63 06: 6.27 07: 6.62 08: 6.73 09: 7.05 10: 5.74 11: 5.15 12: 7.27
Threshold reference:
< 8 m/s → favorable TC development (CPC operational threshold)
< 10 m/s → rapid intensification possible (SHIPS/AOML soft limit)
> 10 m/s → generally inhibitory for TC intensification
Angka domain mean dan max di atas menggambarkan kondisi rata-rata shear setingkat 500–850 hPa di wilayah Indonesia sepanjang 2024. Bandingkan nilai bulanan tersebut dengan threshold 8 dan 10 m/s untuk melihat bulan-bulan mana yang secara rata-rata masuk rezim favorable atau inhibitory.
Memetakan Distribusi Shear di Maritim Kontinen
Statistik angka saja tidak cukup — kita perlu melihat distribusi spasialnya. Plot berikut menampilkan annual-mean shear magnitude di domain Indonesia dengan colormap yang dicetak pada batas 8 dan 10 m/s agar pembaca bisa langsung membaca rezim TC per wilayah.
import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
# Annual mean shear (rata-rata sepanjang sumbu waktu)
shear_annual_mean = np.nanmean(shear_mag, axis=0) # shape: (lat, lon)
lat = ds_u["latitude"].values
lon = ds_u["longitude"].values
# Colormap bertingkat: hijau < 8, kuning 8–10, merah > 10 m/s
cmap = mcolors.LinearSegmentedColormap.from_list(
"shear_regime",
[
(0.0, "#2ecc71"), # 0 m/s — hijau (favorable)
(0.4, "#a8e6a3"), # ~8 m/s — transisi
(0.5, "#f39c12"), # 10 m/s — marginal
(0.65, "#e67e22"),
(1.0, "#c0392b"), # max — inhibitory
]
)
vmax = 25.0
fig, ax = plt.subplots(
figsize=(12, 6),
subplot_kw={"projection": ccrs.PlateCarree()}
)
pcm = ax.pcolormesh(
lon, lat, shear_annual_mean,
transform=ccrs.PlateCarree(),
cmap=cmap,
vmin=0, vmax=vmax,
shading="auto",
)
ax.add_feature(cfeature.COASTLINE, linewidth=0.8, edgecolor="black")
ax.add_feature(cfeature.BORDERS, linewidth=0.4, edgecolor="gray")
ax.add_feature(cfeature.LAND, facecolor="none", edgecolor="none")
ax.gridlines(draw_labels=True, linewidth=0.4, linestyle="--", color="gray", alpha=0.6)
# Kontur threshold
cs = ax.contour(
lon, lat, shear_annual_mean,
levels=[8, 10],
colors=["blue", "darkred"],
linewidths=1.2,
transform=ccrs.PlateCarree(),
)
ax.clabel(cs, fmt="%d m/s", fontsize=9)
cb = plt.colorbar(pcm, ax=ax, orientation="vertical", pad=0.04, shrink=0.85)
cb.set_label("Wind Shear 500–850 hPa (m/s)", fontsize=11)
ax.set_title(
"Annual-Mean 500–850 hPa Wind Shear — Indonesia (ERA5, 2024)",
fontsize=13, fontweight="bold"
)
ax.set_extent([95, 141, -11, 6], crs=ccrs.PlateCarree())
out = os.environ.get("EXPECT_IMAGE_PATH", "shear_map.png")
fig.savefig(out, dpi=130, bbox_inches="tight")
print("wrote", out)
Peta di atas memperlihatkan gradien shear yang khas di wilayah Indonesia. Area dengan shear rendah (hijau, < 8 m/s) umumnya berada di wilayah di mana pembentukan TC secara historis lebih sering terjadi. Sebaliknya, zona shear tinggi (merah, > 10 m/s) berkorelasi dengan aktivitas jet yang kuat atau pengaruh monsun.
Perlu diingat bahwa 500–850 hPa bukan DLS standar untuk analisis TC — threshold 8 dan 10 m/s di atas berasal dari studi 200–850 hPa. Gunakan nilai ini sebagai referensi komparatif, bukan sebagai angka operasional langsung.
Sebagai konteks nyata: pada Februari 2025, enam TC aktif secara bersamaan di Belahan Bumi Selatan — tiga di Samudra Pasifik selatan (Alfred, Rae, Seru) dan tiga di Samudra Hindia selatan (Bianca, Honde, Garance). Menurut NASA Earth Observatory, salah satu faktor pendukung proliferasi siklon yang luar biasa ini adalah kondisi shear rendah yang meluas di kedua basin tersebut, dikombinasikan dengan SST di atas normal.
Sumber: NASA Earth Observatory (Cyclone Flurry in the Southern Hemisphere)
Berikut adalah infografis dari NOAA/AOML yang menggambarkan mekanisme fisik di balik efek shear terhadap vortex TC — shear yang kuat memiringkan kolom konveksi, membawa udara kering dari luar ke dalam core badai.
Sumber: NOAA/AOML (Impact of Wind Shear on Tropical Cyclone Intensity)
Klasifikasi Rezim Shear untuk Prakiraan TC
Dengan shear magnitude di tangan, kita bisa mengklasifikasikan setiap grid cell ke dalam tiga rezim operasional dan menghitung fraksi area yang masuk masing-masing kategori sepanjang 2024.
import numpy as np
import pandas as pd
# Annual-mean shear per grid cell (sudah dihitung di snippet-3)
S = shear_annual_mean # (lat, lon)
total = np.sum(~np.isnan(S))
fav = np.sum(S < 8) / total * 100
marg = np.sum((S >= 8) & (S <= 10)) / total * 100
inh = np.sum(S > 10) / total * 100
print("=== Klasifikasi Rezim Shear (Annual Mean, 2024) ===")
print(f" Favorable (< 8 m/s) : {fav:5.1f}% dari total area domain")
print(f" Marginal (8–10 m/s) : {marg:5.1f}% dari total area domain")
print(f" Inhibitory (> 10 m/s) : {inh:5.1f}% dari total area domain")
print()
# Monthly breakdown — per bulan, fraksi area favorable
time_dim = "valid_time" if "valid_time" in ds_u.dims else "time"
time_vals = ds_u[time_dim].values
months = pd.DatetimeIndex(time_vals).month
print("Monthly area-fraction favorable (shear < 8 m/s):")
for m in range(1, 13):
mask = months == m
if mask.sum() > 0:
monthly_shear = np.nanmean(shear_mag[mask], axis=0)
frac_fav = np.sum(monthly_shear < 8) / np.sum(~np.isnan(monthly_shear)) * 100
bar = "#" * int(frac_fav / 2)
print(f" {m:02d}: {frac_fav:5.1f}% {bar}")
=== Klasifikasi Rezim Shear (Annual Mean, 2024) ===
Favorable (< 8 m/s) : 97.5% dari total area domain
Marginal (8–10 m/s) : 2.5% dari total area domain
Inhibitory (> 10 m/s) : 0.0% dari total area domain
Monthly area-fraction favorable (shear < 8 m/s):
01: 95.6% ###############################################
02: 99.9% #################################################
03: 98.7% #################################################
04: 98.2% #################################################
05: 72.7% ####################################
06: 90.8% #############################################
07: 94.0% ###############################################
08: 78.4% #######################################
09: 80.8% ########################################
10: 91.8% #############################################
11: 99.6% #################################################
12: 74.0% #####################################
Hasil klasifikasi di atas menunjukkan berapa persen wilayah Indonesia (secara rata-rata tahunan) berada di rezim yang favorable, marginal, atau inhibitory. Variasi bulanan penting untuk diperiksa — bulan-bulan tertentu yang memiliki fraksi favorable lebih tinggi berkorelasi historis dengan aktivitas TC yang lebih aktif di dekat perairan Indonesia.
Dari perspektif perubahan iklim, NOAA Climate.gov menyebutkan bahwa proyeksi di beberapa region menunjukkan pengurangan deep-layer shear di masa depan — yang secara teori meningkatkan probabilitas rapid intensification sebelum landfall.
Perbandingan dengan GFS GRIB2 dan Langkah Selanjutnya
Kita telah menghitung shear dari ERA5 — dataset reanalisis yang sangat cocok untuk klimatologi dan validasi. Untuk analisis operasional real-time, data yang dipakai adalah output GFS dari NOMADS NCEP. Alurnya sebagai berikut:
Download GFS GRIB2 via NOMADS menggunakan URL kanonikal:
https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.YYYYMMDD/HH/atmos/gfs.tHHz.pgrb2.0p25.fFFF
di mana YYYYMMDD adalah tanggal siklus, HH adalah siklus runtime (00/06/12/18 UTC), dan FFF adalah forecast hour (000–384).
Agar tidak download file GRIB2 lengkap (beberapa GB per file), gunakan NOMADS GRIB2 filter tool di https://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_0p25.pl untuk subset hanya variabel UGRD dan VGRD di level lev_200_mb dan lev_850_mb. File subset hasil filter biasanya < 5 MB per forecast hour.
Setelah file ter-download, baca dengan cfgrib:
import xarray as xr
ds_gfs = xr.open_dataset(
"gfs.t00z.pgrb2.0p25.f000",
engine="cfgrib",
filter_by_keys={"typeOfLevel": "isobaricInhPa", "shortName": ["u", "v"]},
)
Blok di atas bersifat ilustratif — membutuhkan file GFS lokal yang tidak tersedia di semua lingkungan. Perhatikan bahwa NOMADS hanya menyimpan sekitar 10 hari terakhir; untuk data historis GFS, gunakan AWS Open Data (s3://noaa-gfs-bdp-pds) atau NCAR RDA.
Yang sudah kita pelajari dalam tutorial ini:
- Cara mengunduh komponen u/v angin di pressure levels dari CDS menggunakan
cdsapidengan guardos.path.exists - Menghitung wind shear 500–850 hPa menggunakan vector math sederhana dengan NumPy
- Memetakan distribusi spasial shear menggunakan matplotlib dan cartopy
- Mengklasifikasikan grid cells ke dalam rezim favorable/marginal/inhibitory berdasarkan threshold operasional CPC dan SHIPS/AOML
Ekstensi yang disarankan: - Hitung ensemble shear spread dari GFS ensemble (GEFS) untuk kuantifikasi ketidakpastian - Buat time-series anomali shear bulanan terhadap klimatologi untuk deteksi sinyal La Niña/El Niño - Korelasikan shear dengan RAMI (Rapid Intensification) events dari IBTrACS database - Bandingkan 500–850 hPa shear dengan 200–850 hPa DLS menggunakan ERA5 pressure level yang mencakup 200 hPa
Eksplorasi artikel meteorologi lainnya di meteo.my.id — kunjungi https://meteo.my.id.
Referensi
- NCEP Data Products: GFS and GDAS — NCEP NOAA, panduan resmi naming convention GFS GRIB2 dan akses NOMADS
- Wind shear — AMS Glossary of Meteorology — American Meteorological Society, definisi formal wind shear vertikal dan hubungannya dengan thermal wind
- Climate Prediction Center: 200–850 hPa Vertical Wind Shear (10-Day Mean) — NOAA CPC, produk operasional shear 10-hari dengan threshold 8 m/s sebagai batas favorable TC
- Climate change is probably increasing the intensity of tropical cyclones — NOAA Climate.gov, pengaruh perubahan iklim terhadap deep-layer shear dan intensitas TC
- Impact of Wind Shear Direction on Tropical Cyclone Intensity — NOAA/AOML, mekanisme fisik shear terhadap struktur vortex TC dan model SHIPS
- Cyclone Flurry in the Southern Hemisphere (February 2025) — NASA Earth Observatory, dokumentasi enam TC simultan di Belahan Bumi Selatan dalam kondisi shear rendah
Tidak ada komentar:
Posting Komentar