121 lines
5.1 KiB
Python
121 lines
5.1 KiB
Python
|
|
#!/users/dsc/binp/Python3
|
||
|
|
#-*-coding: UTF-8 -*-
|
||
|
|
|
||
|
|
from datetime import datetime
|
||
|
|
from tokenize import Double
|
||
|
|
from comlib.shm.MemMap import MemMap
|
||
|
|
import logging as d
|
||
|
|
from comlib.shm.Serialization import Serialization
|
||
|
|
import struct
|
||
|
|
import pandas as pd
|
||
|
|
import numpy as np
|
||
|
|
from glitch.alarm_info import AlarmInfo
|
||
|
|
from glitch.GlitchDetector import GlitchDetector
|
||
|
|
from datetime import datetime
|
||
|
|
class GM:
|
||
|
|
def __init__(self):
|
||
|
|
self.mm = MemMap('ZONE20', 16008)
|
||
|
|
self.serializtion=Serialization("2000dii")
|
||
|
|
self.alarm_info=AlarmInfo()
|
||
|
|
self.limit_down=0
|
||
|
|
self.limit_up=0
|
||
|
|
self.current_value=0
|
||
|
|
self.kurtosis_threshold=15#阈值 baseline_kurtosis的倍数
|
||
|
|
self.detector = GlitchDetector(kurtosis_threshold=self.kurtosis_threshold)
|
||
|
|
self.baseline_kurtosis=0.08#正常数据的峰度(绝对值)
|
||
|
|
self.last_alarm_time={}
|
||
|
|
self.now_time=datetime.now()
|
||
|
|
self.AlarmIntervalHours=1 #最小报警时间间隔 小时
|
||
|
|
def dispose(self,ruleid:str,rulename:str,alarm_content:str,stime,endtime,th:float):
|
||
|
|
self.now_time=datetime.now()
|
||
|
|
d.info("----dispose---")
|
||
|
|
res=self.mm[ruleid]
|
||
|
|
if res is None:
|
||
|
|
d.error(f"MemMap not find key '{ruleid}' !")
|
||
|
|
d.debug("|ruleid|"+res.key)
|
||
|
|
data_value=self.serializtion.deserialize(res.value)
|
||
|
|
d_n=data_value[-2]
|
||
|
|
dataX=data_value[:data_value[-2]]
|
||
|
|
self.df=pd.DataFrame(data=dataX)
|
||
|
|
is_alarm=self.detection(dataX=dataX,th=th)
|
||
|
|
if is_alarm:
|
||
|
|
# alarm_content=alarm_content+" 当前值:"+format(self.result["current_kurtosis"],'.3f')+" 合理区间:["+format(-self.baseline_kurtosis*self.kurtosis_threshold,'.3f')+","+format(self.baseline_kurtosis*self.kurtosis_threshold,'.3f')+"]"
|
||
|
|
alarm_result=self.alarm_info.build_alarm(ruleid=ruleid,rulename=rulename,
|
||
|
|
alarm_content=alarm_content,
|
||
|
|
stime=stime/1000,etime=endtime/1000)
|
||
|
|
d.debug(alarm_result)
|
||
|
|
if self.check_last_alarm_time(ruleid)==False:
|
||
|
|
d.debug(self.last_alarm_time[ruleid].strftime("%Y-%m-%d %H:%M:%S.%f")[:-3])
|
||
|
|
return None
|
||
|
|
d.debug("Alarm!"+self.last_alarm_time[ruleid].strftime("%Y-%m-%d %H:%M:%S.%f")[:-3])
|
||
|
|
return alarm_result
|
||
|
|
return None
|
||
|
|
def detection(self,dataX,th):
|
||
|
|
self.df=pd.DataFrame(data=dataX,columns=["data"])
|
||
|
|
self.result = self.detector.detect_glitches(self.df,baseline_kurtosis=self.baseline_kurtosis)
|
||
|
|
# self.limit_down=self.detector.lb
|
||
|
|
# self.limit_up=self.detector.ub
|
||
|
|
# self.current_value=self.detector.va
|
||
|
|
# d.debug("self.df.kurtosis():"+str(self.df.kurtosis()))
|
||
|
|
# d.debug("self.df.skew():"+str(self.df.skew()))
|
||
|
|
# res=self.IQR()
|
||
|
|
# d.debug("IQR----res:"+str(res))
|
||
|
|
# res2=self.sigma(3)
|
||
|
|
# d.debug("sigma---res:"+str(res2))
|
||
|
|
# self.limit_up=th
|
||
|
|
# self.current_value=res
|
||
|
|
if self.result["has_glitch"]:
|
||
|
|
self.current_value=1
|
||
|
|
return True
|
||
|
|
self.current_value=0
|
||
|
|
return False
|
||
|
|
def check_last_alarm_time(self,ruleid):
|
||
|
|
if ruleid in self.last_alarm_time.keys():
|
||
|
|
d.debug("ruleid:"+ruleid+" in self.last_alarm_time.keys!")
|
||
|
|
exp_time=(self.now_time-self.last_alarm_time[ruleid]).total_seconds()
|
||
|
|
if exp_time> self.AlarmIntervalHours*3600:
|
||
|
|
self.last_alarm_time[ruleid]=self.now_time
|
||
|
|
return True
|
||
|
|
else:
|
||
|
|
d.debug("time:"+str(exp_time)+"s <"+str(self.AlarmIntervalHours*3600)+"s")
|
||
|
|
return False
|
||
|
|
else:
|
||
|
|
d.debug("ruleid:"+ruleid+" not in self.last_alarm_time.keys!")
|
||
|
|
self.last_alarm_time[ruleid]=self.now_time
|
||
|
|
return True
|
||
|
|
def IQR(self):
|
||
|
|
if self.df is not None:
|
||
|
|
d.debug("IQR--------1")
|
||
|
|
if self.df["data"].std()==0:
|
||
|
|
d.debug("数据平稳")
|
||
|
|
return 0
|
||
|
|
self.df["data"]=(self.df["data"]-self.df["data"].mean())/self.df["data"].std()
|
||
|
|
Q1=self.df["data"].quantile(0.25)
|
||
|
|
Q3=self.df["data"].quantile(0.75)
|
||
|
|
IQR=Q3-Q1
|
||
|
|
lb=Q1-1.5*IQR
|
||
|
|
ub=Q3+1.5*IQR
|
||
|
|
d.debug(f"Q1:{Q1},Q3:{Q3},IQR:{IQR}")
|
||
|
|
d.debug("lb:"+str(lb)+",ub:"+str(ub))
|
||
|
|
d.debug("IQR--------2")
|
||
|
|
no_outer=(self.df["data"]>=lb)&(self.df["data"]<=ub)
|
||
|
|
d.debug("max:")
|
||
|
|
d.debug(self.df["data"][(~no_outer)].max())
|
||
|
|
|
||
|
|
return (~no_outer).sum()/len(self.df)
|
||
|
|
return None
|
||
|
|
def sigma(self,th=3):
|
||
|
|
if self.df is not None:
|
||
|
|
d.debug("sigma------1")
|
||
|
|
mean=self.df["data"].mean()
|
||
|
|
std=self.df["data"].std()
|
||
|
|
lb=mean-th*std
|
||
|
|
ub=mean+th*std
|
||
|
|
d.debug(f"mean:{mean}, std:{std}")
|
||
|
|
d.debug("lb:"+str(lb)+",ub:"+str(ub))
|
||
|
|
d.debug("sigma------2")
|
||
|
|
no_outer=(self.df["data"]>=lb)&(self.df["data"]<=ub)
|
||
|
|
return (~no_outer).sum()/len(self.df)
|
||
|
|
def IQR(self,df):
|
||
|
|
pass
|