馬士振,林向東,蘇柱金,梁 芳,牟磊育,吳衛(wèi)遠(yuǎn)
(1.北京市地震局,北京 100080;2.廣東省地震局,廣州 510070;3.中國(guó)地震局地球物理研究所,北京 100081;4.北京港震科技股份有限公司,北京 102628)
測(cè)震、強(qiáng)震、烈度儀臺(tái)站24 h 不間斷運(yùn)行,不斷生產(chǎn)著觀測(cè)數(shù)據(jù)。這些觀測(cè)數(shù)據(jù)為后續(xù)各項(xiàng)工作,如地震速報(bào)、地震編目、烈度速報(bào)、地震預(yù)警等提供數(shù)據(jù)基礎(chǔ)[1]。優(yōu)質(zhì)觀測(cè)數(shù)據(jù)是開展科研工作諸多要素中的重要一環(huán),有助于產(chǎn)出高質(zhì)量的科研成果。在觀測(cè)數(shù)據(jù)質(zhì)量的多項(xiàng)評(píng)價(jià)指標(biāo)中,數(shù)據(jù)的斷計(jì)情況統(tǒng)計(jì)是一項(xiàng)重要的內(nèi)容。這里的斷計(jì)統(tǒng)計(jì)包含斷計(jì)秒數(shù)和斷計(jì)次數(shù)兩項(xiàng)內(nèi)容,斷計(jì)秒數(shù)指統(tǒng)計(jì)時(shí)段內(nèi)信號(hào)中斷的秒數(shù),斷計(jì)次數(shù)指統(tǒng)計(jì)時(shí)段內(nèi)數(shù)據(jù)中出現(xiàn)的中斷次數(shù)①?gòu)V東省地震監(jiān)測(cè)中心.數(shù)字中心數(shù)據(jù)處理軟件系統(tǒng)JOPENS6.0(區(qū)域臺(tái)網(wǎng)版)人機(jī)交互MSDP使用指南.廣州,2018.。通過斷計(jì)秒數(shù)和斷計(jì)次數(shù)這兩項(xiàng)指標(biāo),可以對(duì)數(shù)據(jù)的完整性做出較直觀的判斷。
數(shù)字地震臺(tái)網(wǎng)中心數(shù)據(jù)處理軟件系統(tǒng)(以下簡(jiǎn)稱JOPENS 系統(tǒng))[2]擁有豐富的配套軟件。其中的人機(jī)交互MSDP 軟件提供了斷計(jì)統(tǒng)計(jì)功能,統(tǒng)計(jì)結(jié)果包括統(tǒng)計(jì)時(shí)段內(nèi)每日數(shù)據(jù)中斷的秒數(shù)、統(tǒng)計(jì)時(shí)段內(nèi)總的中斷秒數(shù)、中斷數(shù)據(jù)占比、連續(xù)數(shù)據(jù)占比。但是,使用MSDP 完成斷計(jì)統(tǒng)計(jì)需要手工設(shè)置斷計(jì)統(tǒng)計(jì)時(shí)間段、存放目錄等,通過MSDP 實(shí)現(xiàn)自動(dòng)化的斷計(jì)統(tǒng)計(jì)存在一定困難。此外,運(yùn)維人員獲取斷計(jì)統(tǒng)計(jì)結(jié)果的主要方法是主動(dòng)使用軟件進(jìn)行查詢,這樣在查詢結(jié)果的獲取途徑上會(huì)受到一定程度的約束,且查詢結(jié)果的分發(fā)還需要再借助其他通信軟件。
斷計(jì)統(tǒng)計(jì)工作屬于機(jī)械性的重復(fù)工作,如果可以每日自動(dòng)完成數(shù)據(jù)的斷計(jì)情況統(tǒng)計(jì)和信息發(fā)布將在一定程度上節(jié)約運(yùn)維人員的工作時(shí)間。本文利用JOPENS6.1.2 系統(tǒng)提供的HTTP 數(shù)據(jù)傳輸協(xié)議②廣東省地震監(jiān)測(cè)中心.數(shù)字中心數(shù)據(jù)處理軟件系統(tǒng)JOPENS6.0用戶手冊(cè). 廣州,2017,(實(shí)測(cè)可支持到JOPENS6.1.8, 以下簡(jiǎn)稱JOPENS6)和obspy 這個(gè)開源的Python 庫(kù)[3-5],實(shí)現(xiàn)了對(duì)臺(tái)站觀測(cè)數(shù)據(jù)自動(dòng)化的斷計(jì)統(tǒng)計(jì)工作,并通過企業(yè)微信實(shí)現(xiàn)統(tǒng)計(jì)結(jié)果的發(fā)布。
本文軟件采用Python 開發(fā),實(shí)現(xiàn)了三個(gè)功能,一是通過HTTP 數(shù)據(jù)傳輸協(xié)議從JOPENS6系統(tǒng)下載數(shù)據(jù);二是使用obspy 庫(kù)的函數(shù)實(shí)現(xiàn)斷計(jì)信息的獲??;三是通過定時(shí)任務(wù)使數(shù)據(jù)下載、斷計(jì)統(tǒng)計(jì)和企業(yè)微信發(fā)布自動(dòng)化執(zhí)行。
JOPENS6 系統(tǒng)采用HTTP 協(xié)議,統(tǒng)一在8080端口提供數(shù)據(jù)匯集與共享服務(wù)。下載數(shù)據(jù)的具體實(shí)現(xiàn)過程是:根據(jù)預(yù)置的條件,如臺(tái)網(wǎng)代碼、臺(tái)站代碼、通道代碼、起止時(shí)間等,構(gòu)建數(shù)據(jù)下載URL,然后使用Python的相關(guān)模塊實(shí)現(xiàn)從JOPENS6系統(tǒng)下載miniseed格式數(shù)據(jù)。
為了統(tǒng)計(jì)斷計(jì)信息,需要獲取數(shù)據(jù)的實(shí)際起止時(shí)間。obspy 是一個(gè)開源的Python 庫(kù),擁有如數(shù)據(jù)讀取、波形繪制、濾波、譜分析等豐富的功能,通過簡(jiǎn)單的函數(shù)調(diào)用即可實(shí)現(xiàn)對(duì)地震數(shù)據(jù)的處理。在本文中,主要使用了obspy 的數(shù)據(jù)讀取功能。obspy 讀入一個(gè)miniseed 文件后,會(huì)將讀入的數(shù)據(jù)看作一個(gè)流對(duì)象(stream),如果這段數(shù)據(jù)沒有出現(xiàn)斷計(jì),那么這個(gè)流對(duì)象只有一個(gè)trace;如果出現(xiàn)了數(shù)據(jù)中斷,那么這個(gè)流會(huì)包含多個(gè)trace。每一個(gè)trace 都有開始和截止時(shí)間,將后一個(gè)trace 的起始時(shí)間減去前一個(gè)trace 的截止時(shí)間,即實(shí)現(xiàn)了斷計(jì)時(shí)長(zhǎng)的計(jì)算。多個(gè)斷計(jì)時(shí)長(zhǎng)累加在一起,就可以獲得整段數(shù)據(jù)的中斷時(shí)長(zhǎng)。
為了實(shí)現(xiàn)自動(dòng)化的數(shù)據(jù)下載、斷計(jì)統(tǒng)計(jì)和企業(yè)微信發(fā)布,需要軟件自動(dòng)根據(jù)預(yù)設(shè)時(shí)間開展相關(guān) 工 作。 本 文 采 用 了Apscheduler 庫(kù)(http://apscheduler.readthedocs.io/en/latest/)[6],它是Python的一個(gè)第三方庫(kù),實(shí)現(xiàn)了定時(shí)任務(wù)功能。
本文的軟件即在Apscheduler 的管理下,通過HTTP 協(xié)議下載JOPENS6 系統(tǒng)上的數(shù)據(jù),然后使用obspy讀取該數(shù)據(jù),從而實(shí)現(xiàn)數(shù)據(jù)斷計(jì)統(tǒng)計(jì)的功能。軟件結(jié)構(gòu)示意見圖1。圖中T2s指后一個(gè)trace 的開始時(shí)間,T1e指前一個(gè)trace的結(jié)束時(shí)間。
圖1 斷計(jì)統(tǒng)計(jì)執(zhí)行流程Fig.1 Flowchart of gap count
JOPENS6 產(chǎn)出數(shù)據(jù)的斷計(jì)統(tǒng)計(jì)與信息發(fā)布需要多個(gè)模塊的協(xié)作,主要包括數(shù)據(jù)下載模塊、斷計(jì)統(tǒng)計(jì)模塊、企業(yè)微信發(fā)布模塊和定時(shí)任務(wù)管理模塊。
為了通過HTTP 數(shù)據(jù)傳輸協(xié)議下載JOPENS6 系統(tǒng)存儲(chǔ)的觀測(cè)數(shù)據(jù),需要編寫待下載數(shù)據(jù)的相關(guān)信息,并將此信息提交給系統(tǒng),從而實(shí)現(xiàn)數(shù)據(jù)的下載。
為了下載數(shù)據(jù),本文使用了requests 庫(kù)。這是一個(gè)Python的第三方庫(kù),通過簡(jiǎn)單的方式即可實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)資源的訪問。首先建立一個(gè)新的會(huì)話對(duì)象(session)
#導(dǎo)入requests庫(kù)
import requests
j6Session = requests. Session()# 建 立 一個(gè)session對(duì)象
然后,構(gòu)建一個(gè)字符串,該字符串包含JOPENS 服務(wù)器的IP 地址、端口號(hào)、臺(tái)網(wǎng)代碼、臺(tái)站代碼、數(shù)據(jù)起止時(shí)間。通過會(huì)話對(duì)象(seesion)將其提交給JOPENS6 系統(tǒng),系統(tǒng)會(huì)根據(jù)提交的信息返回相應(yīng)觀測(cè)數(shù)據(jù)。關(guān)鍵代碼如下:
#構(gòu)建下載信息字符串
cmd_download = ‘http://JOPENS6IP: 8080 /jopens-ws/app/aws/gwfw;net=BJ;sta=DAX;loc=00;cha=HHZ;beg=2021-01-01 01:00:00;end=2021-01-01 02:00:00’
resp = j6Session. get(cmd_download)# 獲 取JOPENS6返回信息
with open(outfile_name,′wb′)as f:# 打開文件,以二進(jìn)制形式寫入
f.write(resp.content)#將數(shù)據(jù)寫入文件
通過上述操作,即可將需要的觀測(cè)數(shù)據(jù)下載到本地,并以二進(jìn)制miniseed文件形式進(jìn)行保存。
obspy 庫(kù)有一個(gè)內(nèi)置的read 函數(shù),可讀取多種格式的地震數(shù)據(jù),讀入的數(shù)據(jù)構(gòu)成流(stream)對(duì)象。一個(gè)流對(duì)象可由一個(gè)或多個(gè)trace 組成,每個(gè)trace 都有起止時(shí)間,可以通過trace 的函數(shù)獲得。需要注意的是,trace 的起止時(shí)間是UTC 時(shí)間,為了更符合人們的工作習(xí)慣,需要把UTC 格式的起止時(shí)間替換為北京時(shí)間。本文即根據(jù)trace 的起止時(shí)間統(tǒng)計(jì)斷計(jì)結(jié)果。流、trace 起止時(shí)間的示意見圖2,其中t1、t2、t3為斷計(jì)時(shí)長(zhǎng)。關(guān)鍵代碼如下:
圖2 流(stream)對(duì)象與trace關(guān)系示意Fig.2 Diagram of relationship between stream and trace
#導(dǎo)入dateutil模塊和obpsy的read函數(shù)
import dateutil
from obspy import read
st=read(‘miniseed 文件名’)#讀取miniseed文件,構(gòu)成名為st的流對(duì)象
trace1=st[0]#從流對(duì)象列表中取一個(gè)trace
#trace起止時(shí)間的獲取
trace1_starttime = dateutil. parser. parse(str
(trace1.stats.starttime)) #提取開始時(shí)間
.astimezone(pytz.timezone(′Asia/Shanghai′))#轉(zhuǎn)換為北京時(shí)間
.replace(tzinfo=None)#轉(zhuǎn)換為不含時(shí)區(qū)的類型
trace1_endtime=dateutil.parser.parse(str(trace1.stats.endtime))
.astimezone(pytz.timezone(′Asia/Shanghai′))
.replace(tzinfo=None)
若一個(gè)stream 包含兩個(gè)trace,如trace1 和trace2,根據(jù)以上代碼分別獲取各自的起止時(shí)間,而后將trace2的開始時(shí)間與trace1的結(jié)束時(shí)間相減,即可獲得兩者之間的斷計(jì)時(shí)間,即
timedelta=trace2_starttime-trace1_endtime
timedelta.seconds#斷計(jì)的秒數(shù)
timedelta.microseconds#斷計(jì)的微秒數(shù)
注意,在統(tǒng)計(jì)斷計(jì)時(shí)長(zhǎng)時(shí),還需要考慮第1個(gè)trace與miniseed 文件標(biāo)稱開始時(shí)間之差,以及最后一個(gè)trace與miniseed文件標(biāo)稱結(jié)束時(shí)間之差。將這兩個(gè)時(shí)間差與各trace 間時(shí)間差相加起來(lái),即可獲得下載數(shù)據(jù)的總的斷計(jì)時(shí)長(zhǎng)。
至于斷計(jì)次數(shù),分為兩種情況:若第1個(gè)trace的開始時(shí)間、最后一個(gè)trace 的結(jié)束時(shí)間與下載數(shù)據(jù)時(shí)設(shè)置的起止時(shí)間一致,則:斷計(jì)次數(shù)= trace總數(shù)-1。否則,斷計(jì)次數(shù)=trace 總數(shù)-1+(首或尾的斷計(jì)次數(shù))
通過上述計(jì)算,即可獲得下載數(shù)據(jù)的斷計(jì)時(shí)長(zhǎng)和斷計(jì)次數(shù)。將統(tǒng)計(jì)時(shí)段、斷計(jì)時(shí)長(zhǎng)、斷計(jì)次數(shù)輸出為csv格式的文件,以便于使用excel等工具進(jìn)一步開展統(tǒng)計(jì)工作,如繪制統(tǒng)計(jì)圖表,進(jìn)而對(duì)斷計(jì)分布情況做出分析。斷計(jì)統(tǒng)計(jì)見圖3。
圖3 斷計(jì)統(tǒng)計(jì)圖Fig.3 Diagram of gap count
本文軟件選用企業(yè)微信作為信息發(fā)布的媒介主要基于如下三個(gè)考慮,一是企業(yè)微信是騰訊公司針對(duì)企業(yè)開發(fā)的通信和辦公工具,具有和微信一致的交流體驗(yàn);二是企業(yè)微信中可以包括若干應(yīng)用,各應(yīng)用對(duì)誰(shuí)可見由管理員根據(jù)需要進(jìn)行控制;三是企業(yè)微信提供了開發(fā)接口,可以實(shí)現(xiàn)與開發(fā)者的軟件對(duì)接,從而實(shí)現(xiàn)信息的發(fā)布、交互等。為了實(shí)現(xiàn)將斷計(jì)統(tǒng)計(jì)結(jié)果自動(dòng)發(fā)送給運(yùn)維人員,本文軟件的實(shí)現(xiàn)思路是:首先通過企業(yè)微信ID、應(yīng)用的secret,獲取接口調(diào)用憑證;其次,將統(tǒng)計(jì)結(jié)果文件提交到騰訊臨時(shí)媒體庫(kù),并獲得一個(gè)媒體ID;最后,向指定應(yīng)用發(fā)送該媒體ID,從而實(shí)現(xiàn)了將文件發(fā)送到指定應(yīng)用的目標(biāo)。以下為關(guān)鍵代碼:
corp_id='企業(yè)微信ID'
app_secret='應(yīng)用的secret'
url = ′https://qyapi. weixin. qq. com / cgi-bin /gettoken?corpid={}&corpsecret={}′
#獲取接口調(diào)用憑證
access_token = requests. get(url=url. format(corp_id,app_secret)).json().get(′access_token′)
file_url=′https://qyapi.weixin.qq.com/cgi-bin/media / upload? access_token= {}&type=file′. format(access_token)
#上傳文件到臨時(shí)媒體庫(kù)media_id=requests. post(file_url, files= {′file′:open(‘文件絕對(duì)路徑’,′rb′)}).json()[′media_id′]
send_file_url=′https://qyapi.weixin.qq.com/cgibin / message / send? access_token= {}′. format(access_token)
send_values = {′touser′:企業(yè)微信的用戶名,′msgtype′: ′file′, ′agentid′: 應(yīng) 用 的 ID,′file′:{′media_id′:media_id},}
#將臨時(shí)媒體庫(kù)的文件發(fā)送到企業(yè)微信的應(yīng)用requests. post(url=send_file_url, data= json.dumps(send_values))
本文軟件使用的定時(shí)任務(wù)模塊為Apscheduler,在windows、linux 上均可運(yùn)行。通過設(shè)置任務(wù)的開始時(shí)間,即可實(shí)現(xiàn)周期性的定時(shí)任務(wù)。通過該模塊,每日定時(shí)從JOPENS6 服務(wù)器下載前一天的觀測(cè)數(shù)據(jù),并對(duì)其進(jìn)行斷計(jì)統(tǒng)計(jì),最后將統(tǒng)計(jì)結(jié)果發(fā)送到企業(yè)微信。關(guān)鍵代碼如下:
#導(dǎo)入Apscheduler相關(guān)模塊
from apscheduler.schedulers.background import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
scheduler = BlockingScheduler()# 建立一個(gè)定時(shí)任務(wù)對(duì)象
trigger = CronTrigger(hour=′1′,minute=′00′)
#設(shè)置定時(shí)任務(wù)的開始時(shí)間
#周期性執(zhí)行routine 函數(shù),該函數(shù)是將前述的數(shù)據(jù)下載、斷計(jì)統(tǒng)計(jì)整合在一起的函數(shù)
scheduler.add_job(routine,trigger,max_instances=10)
分別采用本文軟件和MSDP(6.0 版)對(duì)北京市測(cè)震臺(tái)網(wǎng)連續(xù)7天的觀測(cè)數(shù)據(jù)進(jìn)行了斷計(jì)統(tǒng)計(jì),并對(duì)兩者產(chǎn)出結(jié)果進(jìn)行比較,詳見表1。
表1 兩種統(tǒng)計(jì)方法產(chǎn)出的斷計(jì)秒數(shù)差異Table 1 The difference of output results between two statistical methods
(接表1)
在斷計(jì)秒數(shù)方面,可以注意到大興、密云、牛欄山、天壇、西集、齋堂等6個(gè)臺(tái)站差值略大。經(jīng)檢查,注意到MSDP 的斷計(jì)結(jié)果中每小時(shí)的斷計(jì)秒數(shù)均為整數(shù)。在與本文統(tǒng)計(jì)結(jié)果進(jìn)行比較后,可以初步認(rèn)為MSDP 對(duì)有小數(shù)的斷計(jì)秒數(shù)進(jìn)行了向下取整操作。因此,對(duì)于上述6個(gè)臺(tái)站,其斷計(jì)統(tǒng)計(jì)結(jié)果的差值即來(lái)自被向下取整的小數(shù)之和。
為了統(tǒng)計(jì)高頻中斷次數(shù)統(tǒng)計(jì)的準(zhǔn)確程度,本文使用三個(gè)斷記次數(shù)在9000 次左右的miniseed 數(shù)據(jù)文件進(jìn)行了測(cè)試。這三個(gè)數(shù)據(jù)文件是人為構(gòu)建的,每個(gè)數(shù)據(jù)文件中每個(gè)trace 時(shí)長(zhǎng)不同,各trace間的間隔時(shí)長(zhǎng)隨機(jī)。數(shù)據(jù)文件構(gòu)成后使用本文軟件進(jìn)行斷記次數(shù)統(tǒng)計(jì)。統(tǒng)計(jì)結(jié)果顯示,軟件統(tǒng)計(jì)的斷記次數(shù)與數(shù)據(jù)文件的實(shí)際斷記次數(shù)一致,詳見表2。
表2 斷記次數(shù)統(tǒng)計(jì)結(jié)果Table 2 The statistics of gap times
經(jīng)測(cè)試,企業(yè)微信中“臺(tái)站運(yùn)行率”應(yīng)用可以成功接收到本文軟件發(fā)送的斷計(jì)結(jié)果統(tǒng)計(jì)文件,并可正常顯示文件內(nèi)容,見圖4。
圖4 企業(yè)微信接收到的文件及其內(nèi)容Fig.4 Files and contents received by enterprise Wechat
通過本文的軟件,可以實(shí)現(xiàn)在每天規(guī)定的時(shí)間,自動(dòng)對(duì)監(jiān)測(cè)臺(tái)網(wǎng)全部臺(tái)站觀測(cè)數(shù)據(jù)以小時(shí)為單位進(jìn)行斷計(jì)秒數(shù)、斷計(jì)次數(shù)統(tǒng)計(jì),其統(tǒng)計(jì)結(jié)果與JOPENS6 配套軟件MSDP 的結(jié)果基本一致。另外,通過企業(yè)微信的應(yīng)用,實(shí)現(xiàn)了臺(tái)站運(yùn)行率結(jié)果的自動(dòng)發(fā)布,有利于運(yùn)維人員及時(shí)掌握臺(tái)站運(yùn)行率指標(biāo),盡快發(fā)現(xiàn)問題,解決問題,以盡可能提高有數(shù)據(jù)時(shí)段的占比,更好地為地震數(shù)據(jù)分析、地震科學(xué)研究提供服務(wù)。