/
alignRTT.py
148 lines (124 loc) · 5.51 KB
/
alignRTT.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#alignment
import atlasTools as at
from scipy.cluster.vq import kmeans
import numpy as np
import sys
import time
from globalConfig import *
MODE = ['avg', 'min', 'max']
PING_INTV = 240
def read_pdid(file):
pb_list = []
f = open(file, 'r')
for line in f:
if line.strip().isdigit():
pb_list.append(int(line))
return pb_list
def interv(list):
return np.array(list[1:]) - np.array(list[:-1])
def main(argv):
mode = 'avg'
if len(argv) != 1:
print "Usage: python alignRTT.py mode\n\
all possible modes are %s." % MODE
exit()
mode = argv[0]
if mode not in MODE:
print "mode %s not recognized, set to default mode 'avg', \
all possible modes are %s" % (mode, MODE)
mode = 'avg'
valid_id = read_pdid(PROBE_ID_VALID_FILE)
alltrace = at.readPingJSON(MES_PING_FILE)
pbAct = alltrace.keys()
pbVal = list(set(valid_id) & set(pbAct))
clean_trace = {k: alltrace[k] for k in pbVal}
print len(clean_trace)
#Quantify measurment dis-sync in time with k-means
len_sort = sorted(clean_trace.items(), key=lambda s:len(s[1]['time_epc']), reverse=True)
#find the probe with maximum data length
max_len_pb = len_sort[0][0]
max_length = len(len_sort[0][1]['time_epc'])
all_time_epc = []
for pb in clean_trace:
for t in clean_trace[pb]['time_epc']:
all_time_epc.append(t)
all_time_epc = np.array(all_time_epc).astype(float).reshape(len(all_time_epc),1)
# use the timestamps of the probe with max data length as the beginning centroids
book = np.array(clean_trace[max_len_pb]['time_epc']).astype(float).reshape(max_length,1)
alTP, dist = kmeans(all_time_epc, book)
alTP = sorted(alTP)
alTP = [i[0] for i in alTP]
tpIntv = interv(alTP)
#print "In average measurements are dis-synchronized by %.3fsec." % dist
print "Calculating 'aligned' timestamps that minimize time distortion after alignment"
print "Aligned timestamps have:\n\
- mean interval of %.3fsec;\n\
- interval std of %.3fsec." % (np.mean(tpIntv), np.std(tpIntv))
print "RTT measurements of each probe will be aligned to the cloest 'aligned' timestamp."
filename = 'pingAL_'+mode+'.csv'
f = open(filename, 'w')
line = 'id,' + ','.join(['%d'%round(t) for t in alTP]) + '\n'
f.write(line)
mean_time_dist = 0
for pb in clean_trace:
align = np.zeros(max_length) # max_length equals the length of alTP
# for i in range(len(clean_trace[pb]['time_epc'])):
# distance = []
# for c in alTP:
# distance.append(np.linalg.norm(c - clean_trace[pb]['time_epc'][i]))
# lb = np.argmin(distance)
# # assign RTT measuremrnt to the cloest aligend timestamp
# align[lb] = clean_trace[pb][mode][i]
# it actually sounds like Dynamic Time Wrapping...
last_match = 0
time_dis = []
for i in range(len(clean_trace[pb]['time_epc'])):
last_dist = 10e6
last_pose = -1
for j in range(last_match, max_length, 1): # begin the search from last matched value
distance = abs(alTP[j] - clean_trace[pb]['time_epc'][i])
if distance < last_dist: # if the distance is deacreasing, continue
last_dist = distance
last_pose = j
else: # if otherwise, last searched al timestamp must be the closest
break
align[last_pose] = clean_trace[pb][mode][i] # assigne the measurment to the aligend postion
last_match = last_pose # update last match position
time_dis.append(last_dist)
if last_match == (max_length - 1):
# if already at the end of aligned ts, stop the procedure, even if there are still values left
break
clean_trace[pb]['time_dis'] = time_dis
print "Probe %d, time dist: avg. %8.3f, max. %8.3f at %d" % (pb, np.mean(time_dis), np.max(time_dis), np.argmax(time_dis))
mean_time_dist += np.mean(time_dis)
# in case 0 or -1 align list,
# assigne the cloest (in time both direction) valide value
for i in range(max_length):
#if align[i] == 0 or align[i] == -1:
if align[i] <= 0:
left_candi = -1
right_candi = -1
for j in range(1,5,1): # neighbour search range
if left_candi == -1:
if (i-j >= 0) and (align[i-j] != 0 and align[i-j] != -1):
left_candi = i-j
if right_candi == -1:
if (i+j < max_length) and (align[i+j] != 0 and align[i+j] != -1):
right_candi = i+j
if left_candi + right_candi > -2: #at least one candidate
break
if left_candi == -1:
align[i] = align[right_candi]
elif right_candi == -1:
align[i] = align[left_candi]
elif (alTP[i] - alTP[left_candi]) <= (alTP[right_candi] - alTP[i]):
align[i] = align[left_candi]
else:
align[i] = align[right_candi]
clean_trace[pb]['align'] = align
line = "%s," % pb + ",".join(map(str, clean_trace[pb]['align'])) + '\n'
f.write(line)
f.close()
print "mean time dist of all probes: %.3f" % (float(mean_time_dist)/len(clean_trace))
if __name__ == "__main__":
main(sys.argv[1:])