0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

気圧場からCOLシステムを同定したい

Last updated at Posted at 2024-06-26

目的

  気圧場が与えられたとき、COL (Cut-Off Law,ちょっと台風に似ている)を形成してしているような成分を分離したい。つまり気圧場の極小値をとってきたいな〜というのが今回のモチベーションです。厳密に閉鎖領域をもとめるのがとてもめんど……メモリ容量的に厳しかったので、上手いこと取ってこれないかなと思っていました。
 フィールド全体にスムージングをかけて、極大値の逆バージョン的なのりで極小を求めようとしたのですけれどこれが案外うまく行かなくて。あと2次元で極値を求めるコードがほとんどネットの海に転がっていなかったので少々苦戦しました。最終的にガウシアンフィルタ→極小値フィルタで解決しました。下にpythonコードを載せておきます。ご活用ください。

もとのコードをきれいにして貼っているのでもしかするとどこかエラーが出るかもしれませんが、まあご愛嬌ということで……。

ところでコードとスクリプトとプログラムの堺って年々曖昧になっていってません? 動的言語が登場したのでさもありなんといった感じではありますが……

 あ、このコード自体は別に気圧場じゃなくても閾値さえちゃんとしておけば動きます。

python スクリプト

local_minumu_location.py
import numpy as np
from scipy.ndimage import gaussian_filter, minimum_filter

def local_minimum_pressure\
    (field, lsmask=None, footprint=np.ones((5,5)), sigma=2, foot = 1000):
   '''
   <input>
   field     ::: pressure field (2d array-like object)
   lsmask    ::: land-sea mask. 0 for land, 1 for sea.
   footprint ::: smoothing filter size.
   sigma     ::: smoothing constant. 2 is standard deviation for gaussian kernel
   foot      ::: minimum value for detection.
   <output>
   peaks_index ::: index for local minimum
   '''
   field = np.array(field)
   
   assert field.ndin == 2, \
   'Input array dimension is %d. Please confirm the dimension to be 2.'%field.ndim
   
   if lsmask == None:
       lsmask = np.ones(field.shape)
   assert lsmask.shape == field.shape, \
   'array shape does not match for field with shape str(field.shape) \ 
   and lsmask with str(lsmask.shape).'
   
   filtered_field = gaussian_filter(field, sigma=sigma)
   local_min = minimum_filter(filtered_field, footprint=footprint, mode='constant')
   local_min = np.ma.masked_where(field > foot, local_min)
   
   local_min_mask = (filtered_field == local_min)
   peaks_index = np.where((local_min_mask == True))
   
   return peaks_index

プロット例

 ECMWF(欧州中期予報センター)のERA5再解析データから気圧場および陸水マスクをダウンロードしてきた前提で、プロットのためのコードを載せておきます。

plot.py

#(continuum from previous code)

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from netCDF4 import Dataset

fname1 = 'pressure.nc' # please insert appropriate file name
fname2 = 'lsmask.nc'

nc1 = Dataset(fname1, 'r')
nc2 = Dataset(fname2, 'r')

lon = nc1['longitude'][:]
lat = nc1['latitude'][:]
field = nc1['sp'][:]/100 # 'sp' means surface pressure. convert [Pa] to [hPa]
lsmask = nc2['lsmask'][:]

### ! caution !
### lsmask and pressure field resolution is different in the case of ECMWF.
### in this code, to solve this problem, reduced the resolution of pressure field.

peaks_index = local_minimum_pressure(field[::2,::2], lsmask=lsmask,\
            footprint=np.ones((5,5)), sigma=2, foot = 1000)

LON, LAT = np.meshgrid(lon[::2], lat[::2])
LON = np.ma.masked_where(lsmask == 0, LON)
LAT = np.ma.masked_where(lsmask == 0, LAT)

# gentrate figure

fig = plt.figure(figsize = (8, 4))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())

cont = ax.contourf(LON, LAT, field[::2,::2] * lsmask,\
                   levels = np.linspace(950,1030,100), cmap='rainbow')
                   
fig.colorbar(cont, ax = ax, orientation='vertical', ticks = np.arange(950, 1050, 10),\
             shrink=0.7)
             
cs = ax.contour(LON, LAT, field[::2,::2] * lsmask, levels = np.arange(950,1050,10),\
                colors='black', linewidths=1, linestyles = ['-', '--'])

ax.clabel(cs, fontsize=15, colors="black")

ax.scatter(LON[peaks_index[0], peaks_index[1]], LAT[peaks_index[0], peaks_index[1]],\
           size=100, marker='+', color='red', zorder=10)
fig.show()
 

結果

気圧場の極小値検出の例

我ながら結構いい感じですね

参考

・ガウシアンフィルター

・極小値フィルター

・python で2次元場の極値をもとめる

・ERA5再解析データ

Hersbach, H., Bell, B., Berrisford, P., Biavati, G., Horányi, A., Muñoz Sabater, J., Nicolas, J., Peubey, C., Radu, R., Rozum, I., Schepers, D., Simmons, A., Soci, C., Dee, D., Thépaut, J-N. (2023): ERA5 hourly data on single levels from 1940 to present. Copernicus Climate Change Service (C3S) Climate Data Store (CDS), DOI: 10.24381/cds.adbb2d47 (Accessed on 26-Jun-2024)

・Cut-Off Lawについて(どうやら1800年代のスペインあたりから文献が見られるらしいのだが、あいにくそこまでの言語能力がないのでwikipediaのページを貼っておく)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?