AERMOD/ISCST3遠端模擬控制程式設計 Table of contents 背景 作業目標:給定AERMOD/ISC runstream檔、氣象及地形檔案,啟動遠端執行程式,並提供結果檔案之連結。 考量及優勢避免本地執行檔之編譯、前後處理程式系統之建置 使用遠端計算資源 快速上手、有助進行模式設定敏感性之測試 整體架構詳見ISCST/AERMOD 主程式 之說明,此處著眼於CGI程式的說明。 程式碼:AERMOD.py 執行前的檢核 執行緒之讀取 應用subprocess模組進行讀取。bash指令運用了ps、grep、以及wc 因工作站有可能同時運作了iscst及aermod程式,因此分別讀取緒數予以相加。 工作站為 6 核心,限制總緒數在5以下以提高服務效能(see TODO’s ) 必須在程式已開始就先確認執行緒數,儘快提供使用者正確的資訊,以避免錯誤期待。 npid1 = subprocess . check_output ( 'ps -ef|grep aermod|grep -v grep|wc -l' , shell = True ). decode ( 'utf8' ). strip ( ' \n ' )
npid2 = subprocess . check_output ( 'ps -ef|grep iscst3|grep -v grep|wc -l' , shell = True ). decode ( 'utf8' ). strip ( ' \n ' )
npid = int ( npid1 ) + int ( npid2 )
if npid >= 5 :
print 'total ' + str ( npid ) + ' iscst or aermod processes are running, please wait. </br>'
print '</body></html>'
sys . exit ()
檔案數的檢核 html提供的檔案欄位數共有4個,最少需2個檔案(ISCST3的runstream與氣象檔案) 將檔名記住備用(inames
)RUNMDL = ISCST3
if model == 'AERMOD' : RUNMDL = AERMOD
inames = []
for nf in '1234' :
fileitem = form [ 'filename' + nf ]
if fileitem . filename :
fn = os . path . basename ( fileitem . filename )
open ( pth + fn , 'wb' ). write ( fileitem . file . read ())
inames . append ( pth + fn )
else :
if nf == '4' : continue
if model == 'ISCST' and nf == '3' : continue
print 'Absent of file number: ' + nf + '</body></html>'
sys . exit ( 'err input file' )
檔案名稱之讀取 從runstream需讀到錯誤訊息檔(ename
)、繪圖檔(pname
)、摘要檔(sname
)的名稱 另外產生std output(oname
)以及kml、grd檔(kname
) ename = subprocess . check_output ( 'grep ERRORFIL ' + inames [ 0 ], shell = True ). decode ( 'utf8' ). strip ( ' \n ' ). split ()[ 1 ]
pname = subprocess . check_output ( 'grep PLOTFILE ' + inames [ 0 ] + '|awk "{print \$NF}"' , shell = True ). decode ( 'utf8' ). strip ( ' \n ' ). split ()
sname = subprocess . check_output ( 'grep SUMMFILE ' + inames [ 0 ] + '|awk "{print \$NF}"' , shell = True ). decode ( 'utf8' ). strip ( ' \n ' ). split ()
ext = inames [ 0 ]. split ( '.' )[ - 1 ]
iname = inames [ 0 ]. split ( '/' )[ - 1 ]
oname = iname . replace ( ext , 'out' )
kname = [ p + '.kml' for p in pname [:]] + [ p + '.grd' for p in pname [:]]
模式之執行 啟動模式 複製一份會自動更新的html 檔到工作目錄,並以sed
進行目錄的更換,其內容將會在waitc.cs內更新。 執行模式,並記錄執行緒號pid
。 #execution of model
cmd = 'cd ' + pth + ';'
#progression checking webpage
cmd += 'cp ' + WEB + '/isc_results/demo/autorefresh.html prog.html;'
cmd += 'sed -ie "s/isc3_RAND/' + ROT + '_' + ran + '/g" prog.html;'
cmd += RUNMDL + ' ' + iname + ' ' + oname + OUT + ';'
cmd = cmd . strip ( ';' )
os . system ( 'echo "' + cmd + '"' + OUT )
pid = subprocess . check_output ( cmd + OUT + '&disown;echo $!' , shell = True ). decode ( 'utf8' ). strip ( ' \n ' )
if len ( pid ) == 0 :
print """Something wrong in Model excutions, see <a href="%s" target="_blank">%s</a>
</body></html>
""" % ( rrn + ename , ename )
sys . exit ()
監看程式的必要性 讓CGI程式可以離線 由監看程式輸出結果到log.out、可以在autorefresh.html呈現出最新進度。 在執行緒多的時候可以跳脫 監看程式之啟動 # The model is running, initiate the waitc.cs to generate log.out for showing progress
cmd = 'cd ' + pth + ';'
cmd += 'time ' + WAITC + ' ' + pth + ' ' + pid + ' &disown'
os . system ( cmd )
監看程式之條件迴圈 ...
for (( i = 0; i>= 0; i+= 1)) ; do
if [ -e $LST ] ; then
grep 'Now Processing Data' $LST |tail -n1 > $OUT
else
echo 'isc3/aermod (pid=' $2 ') has been executed for ' ${ i } '0 seconds' >> $OUT
fi
now = $( ps -ef |grep $2 |grep -v grep |wc -l )
echo 'isc3/aermod (pid=' $2 ') has been executed for ' ${ i } '0 seconds' >> $OUT
all = $( /opt/local/bin/cpu)
echo 'All ' ${ all } ' cpu are occupied' >> $OUT
if [ $now != 1 ] ; then
brk = 0
for pname in $( grep PLOTFILE $iname |awk "{print \$ NF}" ) ; do
if [ -s $pname ] ; then brk = 1; fi
done
if [ $brk == 1 ] ; then break ; fi
fi
sleep 10
done
...
iname = $( ls -rt |head -n1 )
...
for pname in $( grep PLOTFILE $iname |awk "{print \$ NF}" ) ; do
/opt/anaconda3/envs/py27/bin/python $DAT2KML -f $1 /$pname
done
執行成果範例 pid= 79669(check progress)
Model_results: The Model process should be ended in 3 min. After that You may click:
AERTEST_ERRORS.OUT
linko_CO.out
isc.out
AER_CO_01H.PLT
AER_CO_Y.PLT
AER_CO.SUM
AER_CO_01H.PLT.kml
AER_CO_Y.PLT.kml
AER_CO_01H.PLT.grd
AER_CO_Y.PLT.grd