114 lines
3.4 KiB
Python
114 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import sys
|
|
import numpy as np
|
|
import encoder
|
|
import decoder
|
|
import channel
|
|
import subprocess
|
|
import tempfile
|
|
import pathlib
|
|
import os
|
|
|
|
|
|
def transmit(msg, C):
|
|
"""
|
|
Transmitter: encodes the message into real-valued samples using the codebook C.
|
|
"""
|
|
return encoder.encode_message(msg, C)
|
|
|
|
|
|
def receive_local(c):
|
|
"""
|
|
Sends the samples through the local channel simulation.
|
|
"""
|
|
return channel.channel(c)
|
|
|
|
|
|
def receive_server(c, hostname, port):
|
|
"""
|
|
Sends the samples to the remote server via client.py and retrieves the output.
|
|
"""
|
|
# Write input samples to a temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.txt', delete=False) as in_f:
|
|
np.savetxt(in_f.name, c)
|
|
in_name = in_f.name
|
|
# Prepare output file
|
|
out_fd, out_name = tempfile.mkstemp(suffix='.txt')
|
|
os.close(out_fd)
|
|
# Invoke client.py
|
|
cmd = [
|
|
sys.executable,
|
|
str(pathlib.Path(__file__).parent / 'client.py'),
|
|
'--input_file', in_name,
|
|
'--output_file', out_name,
|
|
'--srv_hostname', hostname,
|
|
'--srv_port', str(port)
|
|
]
|
|
try:
|
|
subprocess.run(cmd, check=True)
|
|
Y = np.loadtxt(out_name)
|
|
finally:
|
|
# Clean up temp files
|
|
os.remove(in_name)
|
|
os.remove(out_name)
|
|
return Y
|
|
|
|
|
|
def receive(c, mode, hostname, port):
|
|
"""
|
|
Wrapper to choose local or server channel.
|
|
"""
|
|
if mode == 'local':
|
|
return receive_local(c)
|
|
elif mode == 'server':
|
|
return receive_server(c, hostname, port)
|
|
else:
|
|
raise ValueError("Mode must be 'local' or 'server'")
|
|
|
|
|
|
def test_performance(msg, num_trials, mode, hostname, port):
|
|
"""
|
|
Runs num_trials transmissions of msg through the specified channel and reports accuracy.
|
|
"""
|
|
if len(msg) != 40:
|
|
raise ValueError("Message must be exactly 40 characters.")
|
|
# Build codebook for 64 symbols, 40 blocks
|
|
C = encoder.make_codebook(r=5, num_blocks=40)
|
|
successes = 0
|
|
for i in range(num_trials):
|
|
# Transmit
|
|
c = transmit(msg, C)
|
|
# Channel
|
|
Y = receive(c, mode, hostname, port)
|
|
# Decode
|
|
est = decoder.decode_blocks(Y, C)
|
|
if est == msg:
|
|
successes += 1
|
|
pct = successes / num_trials * 100
|
|
# Display results
|
|
print(f"Message: {msg}")
|
|
print(f"Trials: {num_trials}")
|
|
print(f"Mode: {mode}")
|
|
print(f"Correct decodings: {successes}")
|
|
print(f"Accuracy: {pct:.2f}%")
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(description="Test communication system performance.")
|
|
parser.add_argument('--message', '-m', type=str, required=True,
|
|
help="40-character message to send.")
|
|
parser.add_argument('--trials', '-n', type=int, default=1,
|
|
help="Number of trials.")
|
|
parser.add_argument('--mode', choices=['local','server'], default='local',
|
|
help="Channel mode: 'local' or 'server'.")
|
|
parser.add_argument('--hostname', type=str, default='iscsrv72.epfl.ch',
|
|
help="Server hostname for server mode.")
|
|
parser.add_argument('--port', type=int, default=80,
|
|
help="Server port for server mode.")
|
|
return parser.parse_args()
|
|
|
|
if __name__ == '__main__':
|
|
args = parse_args()
|
|
test_performance(args.message, args.trials, args.mode, args.hostname, args.port)
|