eis/py/glitch/glitch_model.py

121 lines
5.1 KiB
Python
Raw Normal View History

#!/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