Python发射窗口长度分析器 背景:
我正在写论文“覆盖网络中萤火虫激发的心跳同步”。正如其标题所示,本文打算同步萤火虫等设备,使它们在发光时同步 为此,我实现了本文中介绍的自适应Ermentrout模型,并进行了一些测试,以分析模型的行为。我现在有这样的情节 ,显示节点的同步 我现在想做的是计算发射窗口长度作为时间的函数。发射被定义为可能发生在不同节点上的闪光事件的集合(了解图中的列)。换句话说,我想得到发射的第一次闪光的时间,以及发射的最后一次闪光的时间。 这就是我遇到麻烦的地方,我没有设法解决它 有一个参数$\Delta$,它是周期长度,该参数随时间而变化 我开始用Python编写解析器,这就是我现在所拥有的:Python发射窗口长度分析器 背景:,python,parsing,Python,Parsing,我正在写论文“覆盖网络中萤火虫激发的心跳同步”。正如其标题所示,本文打算同步萤火虫等设备,使它们在发光时同步 为此,我实现了本文中介绍的自适应Ermentrout模型,并进行了一些测试,以分析模型的行为。我现在有这样的情节 ,显示节点的同步 我现在想做的是计算发射窗口长度作为时间的函数。发射被定义为可能发生在不同节点上的闪光事件的集合(了解图中的列)。换句话说,我想得到发射的第一次闪光的时间,以及发射的最后一次闪光的时间。 这就是我遇到麻烦的地方,我没有设法解决它 有一个参数$\Delta$,它
import getopt
import sys
import re
def get_time(line):
time = re.match('(\d+):(\d+):(\d+)\.(\d+) \(\d+\) \w+', line)
return int(time.group(1)) * 3600 + int(time.group(2)) * 60 + int(time.group(3)) + int(time.group(4)) / 10 ** (len(time.group(4)))
def init_parser():
input_file = ''
output_file = ''
try:
opts, args = getopt.getopt(sys.argv[1:], 'hi:o:', ['ifile=', 'ofile='])
except getopt.GetoptError:
print('python3 Parser-emission-window.py -i <input file> -o <output file>')
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print('python3 Parser-emission-window.py -i <input file> -o <output file>')
sys.exit()
elif opt in ('-i', '--ifile'):
input_file = arg
elif opt in ('-o', '--ofile'):
output_file = arg
return input_file, output_file
def parser():
input_file, output_file = init_parser()
reference_time, initial_time, current_time, delta = 0, 0, 0, 2
is_reference_time, is_initial_time = False, False
input_file = open(input_file, 'r')
output_file = open(output_file, 'w')
for line in input_file:
current_line = re.match('(\d+):(\d+):(\d+)\.(\d)\d* \(\d+\) Node (\d+) emitted a flash.', line)
if current_line and not is_initial_time:
initial_time = get_time(line)
is_initial_time = True
if current_line and not is_reference_time:
reference_time = get_time(line)
is_reference_time = True
if current_line and get_time(line) - reference_time < delta:
current_time = get_time(line)
elif current_line and get_time(line) - reference_time >= delta:
output_file.write(str(current_time - initial_time) + "\t" + str(current_time - reference_time) + "\n")
reference_time = get_time(line)
input_file.close()
output_file.close()
def main():
parser()
if __name__ == '__main__':
main()
导入getopt
导入系统
进口稀土
def get_时间(行):
时间=重新匹配(“(\d+):(\d+):(\d+)\(\d+)\(\d+)\w+”,行)
return int(time.group(1))*3600+int(time.group(2))*60+int(time.group(3))+int(time.group(4))/10**(len(time.group(4)))
def init_解析器():
输入文件=“”
输出文件=“”
尝试:
opts,args=getopt.getopt(sys.argv[1:],'hi:o:',['ifile=','ofile=')
除getopt.GetoptError外:
打印('python3 Parser-emission-window.py-i-o')
系统出口(2)
对于opt,opt中的参数:
如果opt='-h':
打印('python3 Parser-emission-window.py-i-o')
sys.exit()
elif选择加入('-i','-ifile'):
输入文件=arg
elif选择加入('-o','-ofile'):
输出文件=arg
返回输入文件、输出文件
def解析器():
输入文件,输出文件=init\u解析器()
参考时间,初始时间,当前时间,增量=0,0,0,2
is_reference_time,is_initial_time=False,False
输入文件=打开(输入文件'r')
输出文件=打开(输出文件“w”)
对于输入_文件中的行:
当前\u line=re.match(“(\d+):(\d+):(\d+)\(\d)\d*\(\d+\)节点(\d+)发出闪光。”,第行)
如果“当前”和“非”为“初始”时间:
初始时间=获取时间(行)
_initial_time=真吗
如果当前_线和非_参考_时间:
参考时间=获取时间(行)
_reference_time=真吗
如果当前_行和获取_时间(行)-参考_时间<增量:
当前时间=获取时间(行)
elif当前行和获取时间(行)-参考时间>=增量:
输出文件.write(str(当前时间-初始时间)+“\t”+str(当前时间-参考时间)+“\n”)
参考时间=获取时间(行)
输入_文件。关闭()
输出_文件。关闭()
def main():
解析器()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
但正如你所看到的
,这与另一个图并不完全对应
如果这有什么帮助的话,我在MacOSX10.10.5上工作
另外,如果你需要相应的日志,我会将其发布在通讯中(不能放置超过2个链接)
欢迎任何帮助/提示 好的,所以我想出了办法。 我将在下面发布代码,如果有人需要它,它(我希望)已经有足够的注释了。(请注意,我没有花时间对其进行优化,而且我不是Python专家,所以我所做的一些事情可能不正确/实现得不好)
导入getopt
进口稀土
导入系统
类分析器(对象):
def_uuuinit_uuu(自,输入文件):
self.input\u file=输入文件
def get_节点数(自身):
"""
:return:根据文件名的节点数
"""
返回int(re.match('Logs/Firefly-\w\w-(\d+).+',self.input\u file.group(1))
@静力学方法
def get_时间(行):
"""
函数获取时间
:param line:包含格式为HH:MM:SS.NNNN的时间戳的日志行
:return:以秒为单位的时间
"""
时间=重新匹配(“(\d+):(\d+):(\d+)\(\d+)\(\d+)\w+”,行)
return int(time.group(1))*3600+int(time.group(2))*60+int(time.group(3))+int(time.group(4))/10**(
len(时间组(4)))
def get_初始_时间_和_id(自身):
"""
函数get_initial_time:读取输入_文件,直到找到第一个闪存
:rtype:object
:return:第一次闪烁的时间(秒)
"""
打开(self.input_文件,'r')作为f:
对于f中的行:
当前\u line=re.match(“(\d+):(\d+):(\d+)\。\d+\(\d+\)节点(\d+)发出闪光。”,第行)
如果当前_行:
返回self.get_time(line),int(当前_line.group(4))
#需要定义东西来创建所有的表和东西
def get_时间戳(自身):
"""
get_timestamps:读取输入_文件(日志),每次节点发出闪存时,读取闪存的时间
发出的数据存储在列表的第i个数组中(其中i是节点的id)。
:return:包含节点发光时间的列表。
"""
init_time,u=self.get_initial_time_和_id()
列出范围内i的_时间=[[](self.get_节点数())]
打开(self.input_文件,'r')作为ifile:
对于ifile中的行:
当前\u line=re.match(“(\d+):(\d+):(\d+)\(\d)\d*\(\d+\)节点(\d+)发出闪光。”,第行)
如果当前_行:
列出\u时间[int(当前\u行.group(5))-1]。追加(self.get\u时间(行)-init\u时间)
返回时间
def get_路径():
"""
通过获取输入文件(作为参数传递)生成输出文件
:return:周期长度的输入文件、输出文件
import getopt
import re
import sys
class Parser(object):
def __init__(self, input_file):
self.input_file = input_file
def get_number_of_nodes(self):
"""
:return: the number of nodes according to the name of the file
"""
return int(re.match('Logs/Firefly-\w\w-(\d+).+', self.input_file).group(1))
@staticmethod
def get_time(line):
"""
Function get_time
:param line: line of the log containing a timestamp of the form HH:MM:SS.NNNN
:return: Time in seconds
"""
time = re.match('(\d+):(\d+):(\d+)\.(\d+) \(\d+\) \w+', line)
return int(time.group(1)) * 3600 + int(time.group(2)) * 60 + int(time.group(3)) + int(time.group(4)) / 10 ** (
len(time.group(4)))
def get_initial_time_and_id(self):
"""
Function get_initial_time: reads input_file until it finds the first flash
:rtype: object
:return: time (in seconds) of the first flash
"""
with open(self.input_file, 'r') as f:
for line in f:
current_line = re.match('(\d+):(\d+):(\d+)\.\d+ \(\d+\) Node (\d+) emitted a flash.', line)
if current_line:
return self.get_time(line), int(current_line.group(4))
# Need to define the thing to create all the tables and stuff
def get_timestamps(self):
"""
get_timestamps: reads the input_file (log) and every time a node emits a flash, the time at which the flash was
emitted is stored in the i-th array of lists_time (where i is the id of the node).
:return: the lists containing the time at which nodes emitted light.
"""
init_time, _ = self.get_initial_time_and_id()
lists_time = [[] for i in range(self.get_number_of_nodes())]
with open(self.input_file, 'r') as ifile:
for line in ifile:
current_line = re.match('(\d+):(\d+):(\d+)\.(\d)\d* \(\d+\) Node (\d+) emitted a flash.', line)
if current_line:
lists_time[int(current_line.group(5)) - 1].append(self.get_time(line) - init_time)
return lists_time
def get_paths():
"""
Generate the output files by getting the input file (passed as an argument)
:return: input file, output file for cycle lengths, output file for emission window length
"""
try:
opts, args = getopt.getopt(sys.argv[1:], 'hi:', ['ifile='])
except getopt.GetoptError:
print('python3 Parser-synchronization.py -i <input file>')
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print('python3 Parser-synchronization.py -i <input file>')
print('Ex: \"python3 Parser-synchronization.py -i foo\" will get the file Logs/foo.txt')
sys.exit()
elif opt in ('-i', '--ifile'):
input_file = 'Logs/' + str(arg) + '.txt'
output_file_cl = 'Parsed-logs/' + str(arg) + '-cl-parsed.txt'
output_file_ewl = 'Parsed-logs/' + str(arg) + '-ewl-parsed.txt'
return input_file, output_file_cl, output_file_ewl
def cycle_lengths(lists, ofile):
"""
This function calculates the cycle lengths for each nodes.
:param lists: list containing the times at which every node flashed
:param ofile: output file to write the cycle lengths to.
"""
with open(ofile, 'w') as output_file:
for elem in lists:
for i in range(1, len(elem)):
output_file.write(str(elem[i]) + '\t' + str(elem[i] - elem[i - 1]) + '\n')
def get_closests(lists, time):
# This is not the best thing to do, but radius = Delta/2
# I did not want to create another parameter, especially that I only used Delta = 5 in my test.
"""
This is the second step of the algorithm described in emission_window_length.
It reads every time list (for each node) until it finds a timestamp within 2.5sec
:param lists: list containing the times at which every node flashed
:param time: time of the reference node to look for
:return: list of all the time within 2.5 sec of the ref time (at most one per node)
"""
radius = 2.5
closests = []
for l in lists:
i = 0
while i < len(l)-1 and abs(l[i] - time) > radius:
i += 1
# Now we found an element in the ball of center time and radius 2.5.
# We need to check which of this element or the successor is closest to time.
if abs(l[i] - time) <= radius:
if i < len(l) - 2 and abs(l[i] - time) > abs(l[i + 1] - time):
closests.append(l[i + 1])
else:
closests.append(l[i])
return closests
def emission_window_length(lists, ofile, ref_id):
"""
Explanation of how the function works:
1. We get the id of the node that emitted the first flash. This will be our ref_id (passed in parameter)
2. Every time this node emit a flash, we look for all the nodes that emitted a flash less than 2.5 seconds
before or after the node. We consider that it is in the same emission.
node id node 3 = ref node, At first node 2 is not in the emission window.
^ -----------
| 3 | o | o o
| |<-- 5 --->|
| 2 | | o o
| |<2.5> |
| 1 | o | o o
| -----------
--------------------------------------------------------> time
3. Once we have this list, we look for the min and max, and max-min is our emission window length for the
current emission.
4. Do this for every time ref_id flashed.
WARNING: As the nodes do not start at the same time, we do NOT consider the flashes after ref_id node stops.
:param lists: list containing the times at which every node flashed
:param ofile: output file
:param ref_id: reference id of the node that first flashed
"""
with open(ofile, 'w') as output_file:
for time in lists[ref_id]:
lists_closests = get_closests(lists, time)
# to get min and max of list, we use the built in functions in python
min_time = min(lists_closests)
max_time = max(lists_closests)
length = max_time - min_time
output_file.write('{0}\t{1}\n'.format(str(time), str(length)))
def main():
ifile, ofile_cl, ofile_ewl = get_paths()
parser = Parser(ifile)
_, init_id = parser.get_initial_time_and_id()
lists_time = parser.get_timestamps()
cycle_lengths(lists_time, ofile_cl)
emission_window_length(lists_time, ofile_ewl, init_id)
if __name__ == '__main__':
main()