TANGERANG SELATAN WEATHER

Minggu, 24 Mei 2026

Menghitung Tinggi Geopotensial dari ERA5

Vertical atmospheric gradient representing geopotential height levels

Mengapa Tinggi Geopotensial Penting di Peta Sinoptik

Peta 500 hPa adalah satu-satunya peta yang paling sering dibuka oleh meteorolog operasional. Bukan tanpa alasan — di ketinggian inilah geopotential height membagi massa atmosfer kira-kira menjadi dua bagian setara, sehingga 500 hPa menjadi representasi terbaik dari "jantung" dinamika troposfer.

Pola ridge dan trough pada peta Z500 berfungsi sebagai steering level bagi sistem cuaca di permukaan. Ridge (kontur tinggi yang melengkung ke arah kutub) mengindikasikan udara hangat, tekanan tinggi, dan cuaca cerah. Trough (kontur rendah yang melengkung ke arah ekuator) mengindikasikan udara dingin, tekanan rendah, dan cuaca buruk. Di kawasan tropis seperti Indonesia, variasi Z500 yang tampaknya kecil — puluhan gpm — tetap relevan untuk melacak anomali konveksi dan posisi ITCZ.

ERA5, reanalysis global dari ECMWF dengan resolusi 0,25°, menyediakan geopotential pada 37 pressure level sejak 1940 hingga mendekati hari ini. Dalam tutorial ini kita unduh data geopotensial ERA5 untuk 500 dan 850 hPa, konversi ke geopotential height dalam gpm, petakan pola tahunannya atas Indonesia, lalu hitung ketebalan 500–850 hPa sebagai proksi temperatur mid-troposfer.

Geopotential versus Geopotential Height

ERA5 menyimpan geopotential (simbol \(\Phi\)) dalam satuan m²/s² — bukan dalam metre atau gpm. Geopotential adalah kerja per satuan massa yang diperlukan untuk mengangkat parsel udara dari permukaan laut ke ketinggian tertentu melawan gravitasi. Secara matematis:

$$\Phi = \int_0^z g(z)\, dz$$

Untuk keperluan praktis, kita konversi ke geopotential height \(Z\) dalam satuan geopotential metres (gpm) menggunakan standar gravitasi \(g_0 = 9{,}80665\ \text{m/s}^2\):

$$Z = \frac{\Phi}{g_0} = \frac{\Phi}{9{,}80665}$$

Secara numerik, satu gpm hampir identik dengan satu metre geometrik di ketinggian rendah. Perbedaannya baru signifikan di atas 20 km.

Kesalahan paling umum: mengabaikan pembagian ini dan langsung memplot nilai \(\Phi\) mentah dari ERA5 sebagai ketinggian. Hasilnya akan tampak seperti Z500 di angka ~57.000 alih-alih ~5.800 gpm — sekitar 10 kali lebih besar dari nilai meteorologis yang benar. ECMWF sendiri secara eksplisit menegaskan: "Simply divide the geopotential by the Earth's gravitational acceleration, which has a fixed value of 9.80665 m/s² in the IFS."

Dalam xarray, konversinya satu baris: Z_gpm = ds["z"] / 9.80665.

Mengunduh Data Geopotensial dari ERA5

Geopotential pada pressure level diakses lewat dataset CDS reanalysis-era5-pressure-levels. Kita request dua level — 500 dan 850 hPa — untuk seluruh 2024 dengan bounding box Indonesia. Snippet berikut menyertakan guard if not os.path.exists(OUT) sehingga kita hanya download sekali; iterasi berikutnya membaca dari file lokal.

import os
import cdsapi
import xarray as xr

OUT = "era5_z_pl500-850_indonesia_2024_d.nc"

if not os.path.exists(OUT):
    c = cdsapi.Client(quiet=True)
    c.retrieve(
        "reanalysis-era5-pressure-levels",
        {
            "product_type": "reanalysis",
            "variable": ["geopotential"],
            "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],   # N, W, S, E — Indonesia
            "format": "netcdf",
        },
        OUT,
    )

ds = xr.open_dataset(OUT)
print(ds)
<xarray.Dataset> Size: 37MB
Dimensions:         (valid_time: 366, pressure_level: 2, latitude: 69,
                     longitude: 185)
Coordinates:
  * valid_time      (valid_time) datetime64[ns] 3kB 2024-01-01 ... 2024-12-31
    expver          (valid_time) <U4 6kB ...
  * pressure_level  (pressure_level) float64 16B 850.0 500.0
  * latitude        (latitude) float64 552B 6.0 5.75 5.5 ... -10.5 -10.75 -11.0
  * longitude       (longitude) float64 1kB 95.0 95.25 95.5 ... 140.8 141.0
    number          int64 8B ...
Data variables:
    z               (valid_time, pressure_level, latitude, longitude) float32 37MB ...
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:08 GRIB to CDM+CF via cfgrib-0.9.1...

Output di atas memperlihatkan struktur dataset: dimensi (time, pressure_level, latitude, longitude), koordinat waktu dalam UTC, dan variabel z dengan satuan m²/s². Perhatikan bahwa nilai mentah di kisaran 50.000-an — itu normal untuk m²/s², bukan gpm.

Mengonversi ke Geopotential Height dan Validasi

Setelah dataset terbuka, kita bagi variabel z dengan \(g_0\) untuk mendapatkan geopotential height dalam gpm. Lalu kita cetak statistik dasar per level sebagai sanity check — nilai yang realistis untuk tropis Indonesia adalah sekitar 5.840–5.900 gpm di 500 hPa dan sekitar 1.460–1.510 gpm di 850 hPa.

import numpy as np

G0 = 9.80665  # m/s², standar IFS ECMWF

# Konversi geopotential (m²/s²) → geopotential height (gpm)
Z_gpm = ds["z"] / G0

print(f"Variabel asal : z  |  units : {ds['z'].attrs.get('units', 'tidak ada di attrs')}")
print(f"Setelah dibagi g0 : units menjadi gpm (geopotential metres)")
print()

for lev in [500, 850]:
    Z_lev = Z_gpm.sel(pressure_level=lev)
    print(f"--- {lev} hPa ---")
    print(f"  Mean : {float(Z_lev.mean()):8.1f} gpm")
    print(f"  Min  : {float(Z_lev.min()):8.1f} gpm")
    print(f"  Max  : {float(Z_lev.max()):8.1f} gpm")
    print()
Variabel asal : z  |  units : m**2 s**-2
Setelah dibagi g0 : units menjadi gpm (geopotential metres)

--- 500 hPa ---
  Mean :   5886.6 gpm
  Min  :   5814.6 gpm
  Max  :   5937.4 gpm

--- 850 hPa ---
  Mean :   1514.5 gpm
  Min  :   1417.3 gpm
  Max  :   1574.6 gpm

Output di atas mengonfirmasi bahwa nilai Z500 berada di kisaran wajar untuk kawasan tropis. Jika angka mean muncul di kisaran 57.000-an, berarti pembagian belum dilakukan — itu nilai \(\Phi\) mentah, bukan gpm.

Memetakan Tinggi 500 hPa atas Indonesia

Rata-rata tahunan Z500 atas Indonesia menunjukkan sebaran spasial yang relatif homogen karena kita berada di tropis — variasi hanya beberapa puluh gpm dari barat ke timur. Namun pola inilah yang menjadi baseline untuk mendeteksi anomali ketika ENSO atau MJO aktif. Snippet berikut merender peta contour Z500 rata-rata tahunan lengkap dengan label, coastline, dan colorbar.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

G0 = 9.80665

# Rata-rata tahunan Z500
Z_gpm = ds["z"] / G0
Z500_ann = Z_gpm.sel(pressure_level=500).mean(dim="valid_time")

lat = Z500_ann.latitude.values
lon = Z500_ann.longitude.values
data = Z500_ann.values

fig = plt.figure(figsize=(12, 6))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent([95, 141, -11, 6], crs=ccrs.PlateCarree())

# Filled contour
levels = np.arange(int(data.min()) - 10, int(data.max()) + 20, 10)
cf = ax.contourf(lon, lat, data, levels=levels, cmap="RdYlBu_r",
                  transform=ccrs.PlateCarree(), extend="both")

# Contour lines + labels
cs = ax.contour(lon, lat, data, levels=levels[::2], colors="k",
                linewidths=0.6, transform=ccrs.PlateCarree())
ax.clabel(cs, fmt="%d", fontsize=7, inline=True)

# Fitur kartografis
ax.add_feature(cfeature.COASTLINE.with_scale("50m"), linewidth=0.7, edgecolor="#222")
ax.add_feature(cfeature.BORDERS.with_scale("50m"), linewidth=0.4, edgecolor="#444", linestyle=":")

# Gridlines
gl = ax.gridlines(draw_labels=True, linewidth=0.3, color="gray", alpha=0.5)
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.top_labels = False
gl.right_labels = False

plt.colorbar(cf, ax=ax, orientation="horizontal", pad=0.08,
             shrink=0.75, label="Geopotential Height 500 hPa (gpm)")
ax.set_title("Rata-rata Tahunan Z500 atas Indonesia — ERA5 2024",
             fontsize=12, weight="bold", pad=10)

plt.tight_layout()
plt.savefig("z500_indonesia.png", dpi=150, bbox_inches="tight")
plt.show()

Contour map of annual mean 500 hPa geopotential height over Indonesia from ERA5 2024 reanalysis

Peta di atas memperlihatkan distribusi Z500 rata-rata tahunan atas Indonesia. Kontur yang rapat menandakan gradien geopotential yang besar — region tempat vorticity dan wind shear cenderung kuat. Di tropis dekat ekuator, kontur biasanya lebih renggang dan pola ridge/trough lebih halus dibanding lintang menengah.

Menghitung Ketebalan 500-850 hPa sebagai Proksi Temperatur

Thickness (ketebalan) adalah selisih geopotential height antara dua pressure level:

$$\Delta Z = Z_{500} - Z_{850}$$

Lewat hypsometric equation, ketebalan proporsional terhadap temperatur rata-rata lapisan tersebut:

$$\Delta Z = \frac{R_d\, \bar{T}_v}{g_0} \ln\!\left(\frac{p_1}{p_2}\right)$$

di mana \(R_d = 287\ \text{J kg}^{-1}\text{K}^{-1}\) adalah konstanta gas udara kering, \(\bar{T}_v\) adalah mean virtual temperature lapisan, dan \(p_1/p_2 = 850/500\). Lapisan yang lebih tebal berarti udara lebih hangat; lapisan yang lebih tipis berarti udara lebih dingin. Ini membuat thickness menjadi proxy temperatur yang sangat berguna di mid-troposfer.

G0 = 9.80665

Z_gpm = ds["z"] / G0
Z500 = Z_gpm.sel(pressure_level=500)
Z850 = Z_gpm.sel(pressure_level=850)

thickness = Z500 - Z850

# Rata-rata atas seluruh domain dan waktu
thk_mean = float(thickness.mean())
thk_min  = float(thickness.min())
thk_max  = float(thickness.max())

print(f"Thickness 500–850 hPa atas Indonesia (ERA5 2024)")
print(f"  Mean : {thk_mean:.1f} gpm")
print(f"  Min  : {thk_min:.1f} gpm")
print(f"  Max  : {thk_max:.1f} gpm")
print()

# Estimasi kasar T mean dari hypsometric equation
import math
Rd = 287.05
ln_ratio = math.log(850 / 500)
T_est = thk_mean * G0 / (Rd * ln_ratio)
print(f"Estimasi mean virtual temperature lapisan (dari hypsometric eq.):")
print(f"  T̄v ≈ {T_est:.1f} K  ({T_est - 273.15:.1f} °C)")
print()
print("Interpretasi: lapisan lebih tebal → udara lebih hangat di mid-troposfer.")
Thickness 500–850 hPa atas Indonesia (ERA5 2024)
  Mean : 4372.2 gpm
  Min  : 4321.5 gpm
  Max  : 4416.6 gpm

Estimasi mean virtual temperature lapisan (dari hypsometric eq.):
  T̄v ≈ 281.5 K  (8.3 °C)

Interpretasi: lapisan lebih tebal → udara lebih hangat di mid-troposfer.

Output di atas memperlihatkan rata-rata thickness 500–850 hPa dan estimasi kasar temperatur rata-rata lapisan tersebut. Nilai thickness yang kita lihat di tropis Indonesia secara tipikal lebih besar dibanding lintang tinggi, mencerminkan udara yang lebih hangat di antara kedua level tekanan ini. Variabilitas thickness dari bulan ke bulan pada tahun 2024 bisa dikaitkan dengan anomali SST dan fase ENSO yang aktif sepanjang tahun tersebut.

Langkah Selanjutnya

Dalam tutorial ini kita telah menyelesaikan alur kerja penuh: download geopotensial ERA5 lewat cdsapi, konversi ke gpm dengan pembagian \(g_0\), validasi melalui statistik per level, visualisasi Z500 dengan Cartopy, dan kalkulasi thickness 500–850 hPa sebagai proksi temperatur.

Dari sini ada beberapa arah yang menarik untuk dieksplorasi. Pertama, anomaly map — kurangi nilai Z500 tahunan dengan klimatologi multi-tahun untuk mengidentifikasi bulan-bulan dengan ridge atau trough yang abnormal kuat. Kedua, thickness 1000–500 hPa yang merupakan lapisan standar operasional NOAA untuk threshold hujan/salju (540 dam); membangun ulang threshold ini untuk lapisan tropis melatih pemahaman tentang hypsometric equation lebih mendalam. Ketiga, identifikasi jet stream menggunakan wind shear antara 200 dan 850 hPa — yang membutuhkan data u dan v wind pada pressure level, keduanya tersedia di CDS.

Untuk memahami cara membaca peta 500 hPa secara operasional — shortwave trough, longwave ridge, vorticity maxima — NOAA JetStream adalah referensi yang sangat baik.

Eksplorasi artikel meteorologi lainnya di meteo.my.id

Referensi

Tidak ada komentar:

Posting Komentar