datesIn.py程式說明
Table of contents
前言/背景
背景與目的
- cat_mdl.cs批次檔是進行測站比對、性能評估的最終階段,原設計是執行全月比較,以符合規範要求。
- 現因使用EC再分析數據做邊界條件與ENKF3D,模式精準度大幅提高,可以進行更小時間範圍的比對及評估。
- datesIn.py的必要性及設計原理說明如下。
目標
按camx經驗,時間範圍的定義是在abi_inp.txt,因此本項作業的目標: 讀取abi_inp.txt之起、迄時間(bdate、edate) 讀取模擬結果、測站測值之全月數據 由其中篩選出bdate~edate之範圍 讓abi_cmaq.f可以按照abi_inp.txt之起、迄時間執行測站數據比對
sed用來刪除前後不需要的行數
- 舊版cat_mdl.cs曾使用sed指令來修剪不需要的時間及行數
#delete the lines after last hour
LAST=20$(head -n2 abi_inp.txt|tail -n1|awkk 2|cut -c1-6)
LSTH=$(head -n2 abi_inp.txt|tail -n1|awkk 2|cut -c7-8)
dd=$(date -ud "${LAST}" +%Y-%m-%d)
for ((h=${LSTH}+1;h<=24;h+=1));do
T=$( printf '%02d' $h )
sed -i "/${dd},${T}:00:00/d" MDL.csv
done
for ((n=1;n<=10;n+=1));do
dd=$(date -ud "${LAST} + ${n}day" +%Y-%m-%d)
sed -i "/${dd}/d" MDL.csv
done
條件與策略
檔案管理之邏輯
原全月範疇之ovm.dat,加上BAK字尾以資辨識,另存新檔以供修剪。 MDL.csv為讀取(cat)wsite的綜合結果,並不會動到原檔,可以覆蓋。 按照abi_inp.txt之起迄時間執行測站數據比對
不另創新檔名
由於MDL*csv是按照日期切割的,每個檔案的起、迄小時一律是0800及0700,需整併後才能讀取「任意」小時的起迄時間,不易另創時間定義方式 儘量避免修改原fortran程式 修改fortran程式涉及版本管理,為保持檔案時間,以不修改為原則
以py37另撰修減時間的小程式
利用DataFrame的邏輯篩選,可以快速解決 以unix指令sed進行篩選(原cat_mdl.cs策略詳下述) 逐日、逐時刪除選取範圍以外、前後之內容 好處是腳本簡短、 壞處是 執行速率不佳(詳下述執行結果) sed對觀測檔案(ovm.dat_camx)檔案頭尾,沒有良好的去除策略(時間標籤不明確)
規避中文字的執行困擾
txt檔案中文檔的讀取 使用一般open-read會因環境不同而有差異 使用pandas.read_csv,指定encoding方式,可以解決此一問題 fortran與py37之中文碼不相符合 原ovm.dat_camx為aok(fortran 程式)所產生,其對中文之讀寫似與py37有所不同, py37產生之中文字元,回到fortran程式,將無法辨識(待解決)。 站名將會用在abi_d0?.txt檔案內,有其意義 結論:以英文站名(sta_ll.csv內容)取代之
程式設計
時間標籤之定義
abi_inp.txt 文字(檔)讀成datetime wsite結果中,時間標籤分散在2欄: df.date為日期(%Y-%m-%d)、df.Time(%H:00:00)為小時:分:秒。 須先將其整併、解讀為datetime,以利計算判別。
ovm.dat文字檔的讀取與解析
除了測站編號與站名黏在一起成了新的變數(57NAME)外,其餘尚有間隔可以split()。 似乎只能逐一測試測站編號的位數,來解析成為1~999之整數,並將其區分開來(def rdA15)。 將文字檔先讀成資料結構(DataFrame),如此才方便進行時間篩選。
去中文化
由於py37寫的中文字,無法被fortran程式解讀,造成當機。 利用sta_ll.csv內容,建立一測站編號與英文名稱的字典,將其置換為英文。 寫出ovm.dat 因ovm.dat具有固定的fortran輸入格式,因此必須按其格式輸出。 在此引用fortranformat模組進行輸出。 因測站編號與名稱已經順利切割,輸出時也多了1欄。
應用
批次檔前後之內容
- 形成全月MDL.csv之後即可呼叫本程式
- 執行本程式之後,原本修減(sed)小時之部分腳本應該可以不必執行。
- pandas的DataFrame比sed更有效率
修正結果
$ head MDL.csv
siteid,column,row,longitude,latitude,date,Time,NO2,O3,PM10,PM25_NO3,PM25_SO4,PM25_TOT,SO2,VOC
1,67,123,121.76000,25.12917,2016-09-30,08:00:00,1.17543,49.2205,6.55583,0.536996E-01,2.23841,3.51880,0.137914,37.3447
1,67,123,121.76000,25.12917,2016-09-30,09:00:00,0.860888,50.6654,6.13043,0.472058E-01,2.25603,3.44657,0.179717,37.7828
$ tail MDL.csv
84,60,129,121.53778,25.29722,2016-11-02,05:00:00,0.387033,43.6261,14.1320,0.582876E-01,2.49103,4.22779,0.108618,10.6993
84,60,129,121.53778,25.29722,2016-11-02,06:00:00,0.400964,43.4368,14.2808,0.572451E-01,2.60123,4.31227,0.915345E-01,11.9385
84,60,129,121.53778,25.29722,2016-11-02,07:00:00,0.443238,41.4981,11.7637,0.410973E-01,2.18446,3.55049,0.890396E-01,13.7664
$ cat abi_inp.txt
1610baseKF.S.grd02
16101620 16102520
$ head -n3 MDL.csv
siteid,column,row,longitude,latitude,date,Time,NO2,O3,PM10,PM25_NO3,PM25_SO4,PM25_TOT,SO2,VOC,dt
1,67,123,121.76,25.12917,2016-10-16,20:00:00,3.31776,23.8603,7.74962,0.100152,1.18119,2.27233,0.221385,32.7990,2016-10-16 20:00:00
1,67,123,121.76,25.12917,2016-10-16,21:00:00,2.81255,23.6580,2.78081,0.224228E-01,0.544535,0.930699,0.110365,30.3581,2016-10-16 21:00:00
$ tail -n2 MDL.csv
84,60,129,121.53778,25.29722,2016-10-25,19:00:00,2.23919,53.4506,20.2096,0.410098,5.69840,9.43429,1.68084,46.2761,2016-10-25 19:00:00
84,60,129,121.53778,25.29722,2016-10-25,20:00:00,4.26775,53.1935,20.5157,1.13997,5.16592,10.2227,5.53251,52.6116,2016-10-25 20:00:00