-
Notifications
You must be signed in to change notification settings - Fork 1
/
pacman-generator-RAW.py
245 lines (214 loc) · 11 KB
/
pacman-generator-RAW.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#general imports
import argparse
import time
import sys
import multiprocessing
#import h5py
import random
#larpix imports
sys.path.insert(1, '../scripts')
import larpixtools
#zmq imports
import zmq
# Prepare ports
echo = 'tcp://127.0.0.1:5554'
cmd = 'tcp://127.0.0.1:5555'
data = 'tcp://127.0.0.1:5556'
# Converts HDF5 files into a list of PACMAN messegaes (bytes)
def hdf5ToPackets(datafile):
print("Reading from:",datafile)
packets = larpixtools.from_file(datafile)['packets'] #read from HDF5 file
print("Separating into messages based on timestamp packets...")
msg_breaks = [i for i in range(len(packets)) if packets[i].packet_type == 0 or i == len(packets)-1] #find the timestamp packets which signify message breaks
msg_packets = [packets[i:j] for i,j in zip(msg_breaks[:-1], msg_breaks[1:])] #separate into messages
msgs = [larpixtools.format(p, msg_type='DATA') for p in msg_packets]
print("Extracting headers and words from messages...")
#header_list = [pacman_msg_format.parse_msg(p)[0] for p in msgs] #retrieve headers
word_lists = [larpixtools.parse_msg(p)[1] for p in msgs] #retrieve lists of words from each message
'''
# Deprecated method of making messages
messages = []
print("Creating a message every second...")
for i in msg_packets:
messages.append(pacman_msg_format.format(i, msg_type='DATA'))
print(pacman_msg_format.parse(pacman_msg_format.format(i, msg_type='DATA')))
time.sleep(1)
'''
'''
# Modern method of making messages
messages = []
print("Creating a message every second...")
for i in word_lists:
messages.append(pacman_msg_format.format_msg('DATA',i))
print(pacman_msg_format.parse_msg(pacman_msg_format.format_msg('DATA',i)))
time.sleep(1)
print("Messages created.")
'''
print("Read complete. PACMAN style messages prepared.")
return word_lists
# Useful print message for the user which tells them what they are about to run.
def print_explain_modes():
print("""
Running mode 0:
You will send all of the messages in the input file individually at
intervals of 1 to 3 seconds drawn randomly. If you specified --n_messages_total,
--n_messages_group or --group_interval, this will be ignored.\n
Running mode 1:
For each loop of the input file you specified, you will send groups of messages
of size, split by intervals of and totalling the numbers you specify using
--n_messages_total, --n_messages_group and --group_interval.\n
Running mode 2:
For each loop of the input file you will send a single message.
If you specified --n_messages_total, --n_messages_group or --group_interval, this will be ignored.\n
Running mode 3:
For each loop of the input file you will send 10 total messages individually
spaced by 1 second.
If you specified --n_messages_total, --n_messages_group or --group_interval, this will be ignored.\n
Running mode 4:
For each loop of the input file you will send 50 total messages in groups of 5
spaced by 1 second.
If you specified --n_messages_total, --n_messages_group or --group_interval, this will be ignored.
""")
sys.exit()
return
def print_mode_info (mode, this_n_messages_total, this_n_messages_group, this_group_interval):
s_print = "\n\n\n Running mode " + str(mode) + "\n"
if mode == 0:
s_print += """ You will send all of the messages in the input file individually at
intervals of 1 to 3 seconds drawn randomly. If you specified --n_messages_total,
--n_messages_group or --group_interval, this will be ignored.
\n\n\n"""
elif mode == 1:
s_print += " For each loop of the input file you specified, you will send " + str(this_n_messages_total) + " total"
s_print += " messages in groups of " + str(this_n_messages_group)
s_print += " at intervals of " + str(this_group_interval) + " seconds.\n\n\n"
elif mode == 2:
s_print += """ For each loop of the input file you will send a single message.
If you specified --n_messages_total, --n_messages_group or --group_interval, this will be ignored.
\n\n\n"""
elif mode == 3:
s_print += """ For each loop of the input file you will send 10 total messages individually
spaced by 1 second.
If you specified --n_messages_total, --n_messages_group or --group_interval, this will be ignored.
\n\n\n"""
elif mode == 4:
s_print += """ For each loop of the input file you will send 50 total messages in groups of 5
spaced by 1 second.
If you specified --n_messages_total, --n_messages_group or --group_interval, this will be ignored.
\n\n\n"""
print(s_print)
return
# Instance of a PACMAN card
def pacman(_echo_server,_cmd_server,_data_server,word_lists,mode,n_messages_total,n_messages_group,group_interval,n_file_evals=1):
try:
# Set up sockets
print("Setting up ZMQ sockets...")
ctx = zmq.Context()
data_socket = ctx.socket(zmq.STREAM)
socket_opts = [
(zmq.LINGER,100),
(zmq.RCVTIMEO,100),
(zmq.SNDTIMEO,100)
]
print("Parsing socket options...")
for opt in socket_opts:
data_socket.setsockopt(*opt)
print("Connecting sockets...")
id = 0
while id == 0:
try:
data_socket.connect(_data_server)
# need to receive two messages to get target ID
id = data_socket.recv()
message = data_socket.recv()
except:
print("No receiver ready to connect to. Retrying...")
time.sleep(1) #wait 1s before retrying
continue
print('Press any key to start sending data...')
input()
print('Initialising...')
time.sleep(1)
print("Data will repeat %i times." %(n_file_evals-1))
print('Sending PACMAN messages.')
# MODE 0: Default (and original) behaviour. Single messages sent at randon intervals between 1 and 3 seconds.
# MODE 1: User specifies one or all of n_messages_total, n_messages_group and group_interval.
# If a particular one isn't specified, it is just set to its default value.
# MODES 2 AND ABOVE: Predefined n_messages_total, n_messages_group and group_interval. If user specifies these parameters
# they will be ignored.
# MODE 2: Single message.
# MODE 3: 10 total message sent individually at intervals of 1 second.
# MODE 4: 50 total message sent in groups of 5 at intervals of 1 second.
if mode < 3:
this_n_messages_total = n_messages_total
this_n_messages_group = n_messages_group
this_group_interval = group_interval
if mode == 3:
this_n_messages_total = 10
this_n_messages_group = 1
this_group_interval = 1
if mode == 4:
this_n_messages_total = 50
this_n_messages_group = 5
this_group_interval = 1
print_mode_info (mode, this_n_messages_total, this_n_messages_group, this_group_interval);
# Send messages in intervals based on timestamps
message_count = 0
for n in range(n_file_evals):
for i in word_lists:
#data_socket.send(b"", zmq.SNDMORE)
data_socket.send_multipart([id,larpixtools.format_msg('DATA',i)])
print(larpixtools.parse_msg(larpixtools.format_msg('DATA',i)))
message_count += 1
print("Total messages sent:",message_count)
if mode == 2: break;
elif mode > 0:
if message_count % this_n_messages_total == 0:
time.sleep(next_sleep);
break;
if message_count % this_n_messages_group == 0:
next_sleep = this_group_interval;
else: continue;
else:
next_sleep = random.randrange(1,3)
if message_count != len(word_lists)*n_file_evals:
print("Next message in: %ds" %(next_sleep))
time.sleep(next_sleep)
print("Sleeping for 10 seconds before exiting...")
time.sleep(10)
except:
raise
finally: #cleanup
data_socket.close()
#cmd_socket.close()
#echo_socket.close()
ctx.destroy()
def main(s_in_file, mode, n_file_evals, n_pacman, n_messages_total, n_messages_group, group_interval, explain_modes):
if(explain_modes): print_explain_modes()
if(s_in_file == "ns"):
print("\n\n\nPlease specify an input file...")
sys.exit()
# Fetch messages and timestamps
word_lists = hdf5ToPackets(s_in_file)
print("Starting PACMAN card(s)")
start_time = time.time()
# Start PACMAN cards
def start(task, *args):
process = multiprocessing.Process(target=task, args=args)
process.daemon = True
process.start()
for i in range(n_pacman):
start(pacman(echo,cmd,data,word_lists,mode,n_messages_total,n_messages_group,group_interval,n_file_evals), i)
print("Total elapsed time:",time.time()-start_time)
if __name__ == "__main__":
parser = argparse.ArgumentParser();
parser.add_argument('--explain_modes', dest='explain_modes', action='store_true', help="Print an explanation of the running modes.")
parser.add_argument('--input_file', '-i', dest='input_file', type=str, default="ns", help='Input h5 file.')
parser.add_argument('--mode', dest='mode', type=int, default=0, help='Running mode, can take values [0-4]. Pass --explain_modes to this script for a full explanation of different modes.')
parser.add_argument('--n_file_evals', dest='n_file_evals', type=int, default=1, help='Number of times the input file is looped through.')
parser.add_argument('--n_pacman', dest='n_pacman', type=int, default=1, help='Number of PACMAN cards.')
parser.add_argument('--n_messages_total', dest='n_messages_total', type=int, default=10, help='To be used with --mode 1. Total number of messages sent during one loop of input file.')
parser.add_argument('--n_messages_group', dest='n_messages_group', type=int, default=1, help='To be used with --mode 1. Total number of messages sent at once at intervals of --group_interval.')
parser.add_argument('--group_interval', dest='group_interval', type=float, default=1.0, help='To be used with --mode 1. Time interval between groups of messages being sent.')
args = parser.parse_args();
main(args.input_file, args.mode, args.n_file_evals, args.n_pacman, args.n_messages_total, args.n_messages_group, args.group_interval, args.explain_modes);