Link Search Menu Expand Document

2023/06更新

Table of contents

背景

依據

修改大要

此次更新除了強化之前將模擬結果區分成快取、與永久保存2處分開提供,也有下述改變:

  • 將過去的污染物項目(VAR、MASSMR等開頭的變數名稱),全部改為物質簡稱(小寫)以及粒狀物(aermr01~20)。
  • 時間變數名稱改成’time’、經緯度也更名了。
  • 新增生物源及人為源的有機性粒狀物2項。國際間研究不少以此為主題的,CMAQ後處理($SpecDef)也預留了這2個選項,可作為對照的依據。

造成效果與因應對策

  • 下載腳本(get_all.cs)須更新
    • ncl_convert2nc無法轉檔、由eccodes中的grib_to_netcdf取代
    • ncks之執行方式:因應維度名稱的改變
    • merge.cs
    • 新增SDATE及STIME將模擬起始日期時間記下來
    • 新版python檔案之應用
  • 物質名稱對照表
    • GrbNam2ChemV2.json:行列文字版本、下載過程的merge.cs會用到
    • nms_gas.json:CAMS對應到CMAQ名稱
    • nms_part.json:粒狀物名稱改變、項目也有改變
    • dic.json:前述GrbNam2ChemV2.json的連續版本。
  • python程式(get_All.py/grb2icon.py/grb2bcon.py)須更新
    • 新的物質項目名稱
      • "biogenic_secondary_organic_aerosol_mixing_ratio"
      • "anthropogenic_secondary_organic_aerosol_mixing_ratio"
      • 因項目正好27項,不必修改程式其他地方。
    • 因應grib檔案時間、經緯度命名方式之更新
    • 對照表更新
  • run_cmaq.cs執行前所需檔案時間檢核chk_IBM.cs:這支程式會檢查前述腳本的執行成果,測試是否所有物質都妥善轉換。

下載與轉檔流程

下載流程

完整的下載流程詳見get_all.cs說明 更新項目內容全貌詳見前述2023/06更新,此處說明處理腳本更動的部分。

轉檔方式

  • 由ncl_convert2nc改成eccodes中的grib_to_netcdf取代
    • 基本上ncl系統是個較舊的系統,且官網已經宣布不再更新進版了,而相對的eccodes系統卻持續更新,因此這項轉換似乎是必然也是顯而易見,即使eccodes並沒有提供執行檔,需要在本地工作站上重新編譯
  • 除了轉檔之外,unlimiting dimension的設定(-u time)也在此解決,不必另外再用ncks設定。
#  PATH=/bin:/opt/anaconda3/envs/ncl_stable/bin ncl_convert2nc allEA_$i.grib -nc4c >& /dev/null
  /opt/anaconda3/envs/gribby/bin/grib_to_netcdf  -u time -o allEA_$i.nc allEA_$i.grib >& /dev/null

模擬起始時間之註記

  • 因原始grib檔案的屬性真的太多樣了,grib_to_netcdf也無法完全轉換全部所有的項目(例如模擬起始日期時間),因此還是需要另外用grib_dump來讀取
  • 紀錄位置的考量:nc檔的屬性名稱太多樣,此處與ioapi convention一樣,用全域屬性SDATE及STIME來紀錄、以備後續使用。
  sdate=$($c2j $(/opt/anaconda3/envs/gribby/bin/grib_dump -D allEA_$i.grib|grep "validityDate"|head -n1|$awkk 5))
  stime=$(/opt/anaconda3/envs/gribby/bin/grib_dump -D allEA_$i.grib|grep "dataTime"|head -n1|$awkk 5)0000
  $nced -a SDATE,global,o,i,$sdate allEA_$i.nc_0
  $nced -a STIME,global,o,i,$stime allEA_$i.nc_0

merge.cs的改變

  • grib_to_netcdf的轉換結果,變數的型態不是一般的float,而是short。
    • 這是因為grib檔使用了局部的校調,每個變數有自己的off-set與scale factor。如此可以大幅降低其數據精度需求及檔案的大小。
    • 好在python的netCDF4模組再轉換時會自行將此校調應用回去,使用者不需要自己再做計算(參型態轉換user’s guideexplained)。
  • 不再需要在此設定unlimiting dimension,已經用grib_to_netcdf直接設定了。
#  var=$(/usr/bin/ncdump -h $nc|grep float|grep forecast_time|$awkk 2|cut -d'(' -f1)
  var=$(/usr/bin/ncdump -h $nc|grep short|$awkk 2|cut -d'(' -f1)
#    $ncks -O -v $v --mk_rec_dmn initial_time0_hours $nc tmp.nc
    $ncks -O -v $v $nc tmp.nc

呼叫新版的grb2icon.py與grb2bcon.py

./grb2iconV2.py
...
./grb2bconV2.py ${td};
  • 各個py程式修改的重點說明如後。

物質對照表

下載名稱與CAMS模式物質名稱

kuang@dev2 /u01/ecmwf/CAMS/CAMS_global_atmospheric_composition_forecasts/2022
$ cat GrbNam2ChemV2.json
{
"aermr01":"sea_salt_aerosol_0.03-0.5um_mixing_ratio",
"aermr02":"sea_salt_aerosol_0.5-5um_mixing_ratio",
"aermr03":"sea_salt_aerosol_5-20um_mixing_ratio",
"aermr04":"dust_aerosol_0.03-0.55um_mixing_ratio",
"aermr05":"dust_aerosol_0.55-0.9um_mixing_ratio",
"aermr06":"dust_aerosol_0.9-20um_mixing_ratio",
"aermr07":"hydrophilic_organic_matter_aerosol_mixing_ratio",
"aermr08":"hydrophobic_organic_matter_aerosol_mixing_ratio",
"aermr09":"hydrophilic_black_carbon_aerosol_mixing_ratio",
"aermr10":"hydrophobic_black_carbon_aerosol_mixing_ratio",
"aermr11":"sulphate_aerosol_mixing_ratio",
"aermr16":"nitrate_fine_mode_aerosol_mass_mixing_ratio",
"aermr17":"nitrate_coarse_mode_aerosol_mass_mixing_ratio",
"aermr18":"ammonium_aerosol_mass_mixing_ratio",
"aermr19":"biogenic_secondary_organic_aerosol_mixing_ratio",
"aermr20":"anthropogenic_secondary_organic_aerosol_mixing_ratio",
"c2h6":"ethane",
"c3h8":"propane",
"c5h8":"isoprene",
"co":"carbon_monoxide",
"go3":"ozone",
"hcho":"formaldehyde",
"hno3":"nitric_acid",
"pan":"peroxyacetyl_nitrate",
"no2":"nitrogen_dioxide",
"no":"nitrogen_monoxide",
"so2":"sulphur_dioxide",
}

粒狀物名稱對照表

  • 新增項目
    • 其中的aermr19生物二次有機氣膠、aermr20人為污染二次有機氣膠的成分,為此次新增。
    • 參考combine.exe讀取的$SPECIES_DEF設定檔案內容
  • 取消:nitrate在去年的更新就不再提供了,此次當然也不會有。
  • NH3在2022年被移到Multi-level Slow access 項目,無法每日下載。
{"aermr18": ["ANH4I", "ANH4J", "ANH4K"], "aermr04": ["AFEJ", "AALJ", "ASIJ", "ACAJ", "AMGJ", "AKJ", "AMNJ","ATIJ"], "aermr05": ["AFEJ", "AALJ", "ASIJ", "ACAJ", "AMGJ", "AKJ", "AMNJ","ATIJ"], "aermr06": ["ACORS", "ASOIL"], "aermr09": ["AECI", "AECJ"], "aermr07": ["APOCI", "APNCOMI", "APOCJ", "AOTHRJ", "AISO3J", "ASQTJ", "AORGCJ", "AOLGBJ", "AOLGAJ"], "aermr10": ["AECI", "AECJ"], "aermr08": ["APOCI", "APNCOMI", "APOCJ", "AOTHRJ", "AISO3J", "ASQTJ", "AORGCJ", "AOLGBJ", "AOLGAJ"], "aermr01": ["ANAI", "ACLI", "ANAJ", "ACLJ"], "aermr02": ["ACLK", "ASEACAT"],"aermr03": ["ACLK", "ASEACAT"], "aermr11": ["ASO4I", "ASO4J", "ASO4K"],"aermr17":["ANO3K"],"aermr16":["ANO3I", "ANO3J"],"aermr19":["AISO1J","AISO2J","AISO3J","AMT1J","AMT2J","AMT3J","AMT4J","AMT5J","AMT6J","AMTNO3J","AMTHYDJ","AGLYJ","ASQTJ","AOLGBJ"],"aermr20":["AAVB1J","AAVB2J","AAVB3J","AAVB4J","AOLGAJ"]}

氣狀物名稱對照表

  • 氨氣、有機物(PAR、OLE等等)還是沒有出現在快取區域。
{"co": "CO", "c2h6": "ETH", "hcho": "FORM", "c5h8": "ISOP", "hno3": "HNO3", "no2": "NO2", "no": "NO", "VAR_192_217_11_P0_L105_GLL0": "OLE", "VAR_192_217_15_P0_L105_GLL0": "XPAR", "go3": "O3", "VAR_192_217_9_P0_L105_GLL0": "PAR", "pan": "PAN", "c3h8": "PRPA", "so2": "SO2"}

py程式之更新

grb2icon.py程式碼更新

  • 經緯度名稱更新了,此處用通案作法,以避免再次更動。
  • 沒有initial_time的屬性了,改成全域屬全域屬性SDATE及STIME。
kuang@dev2 /u01/ecmwf/CAMS/CAMS_global_atmospheric_composition_forecasts/2022
$ diff grb2icon.py grb2iconV2.py
40,41c40,44
< xlat=np.flip(nc['lat_0'])
< xlon=nc['lon_0']
---
> slat=[i.lower() for i in V[0] if 'lat' in i.lower()]
> slon=[i.lower() for i in V[0] if 'lon' in i.lower()]
> if len(slat)==0 or len(slon)==0:sys.exit('fail to find latitude in V[0]')
> xlat=np.flip(nc[slat[0]])
> xlon=nc[slon[0]]
44c47
< date=datetime.datetime.strptime(nc.variables[V[3][0]].initial_time,'%m/%d/%Y (%H:%M)') #+datetime.timedelta(hours=12)
---
> sdate=datetime.datetime.strptime(str(nc.SDATE)+' '+str(nc.STIME),'%Y%j %H') #+datetime.timedelta(hours=12)

grb2bcon.py程式碼更新

  • 更新項目內容全貌詳見背景,此處說明邊界檔轉換程式更動部分
  • 因應grib_to_netcdf轉檔結果,時間標籤改在nc['time'],單位是1900-01-01 00:00:00.0之後的小時數。其餘沒有更動。
  • 對照表的內容更新了,但檔名沒有更動。
kuang@dev2 /u01/ecmwf/CAMS/CAMS_global_atmospheric_composition_forecasts/2022
$ diff grb2bcon.py grb2bconV2.py
44,45c44,47
<     fcst_hr=float(np.array(nc['forecast_time0'])[0])
<     bdatef=datetime.datetime.strptime(nc.variables[V[3][0]].initial_time,'%m/%d/%Y (%H:%M)')+datetime.timedelta(hours=fcst_hr)
---
>     v='time'
>     udate=datetime.datetime.strptime(' '.join(nc[v].units.split()[2:4]),'%Y-%m-%d %H:%M:%S.0')
>     fcst_hr=float(np.array(nc[v])[0])
>     bdatef=udate+datetime.timedelta(hours=fcst_hr)