# this is the template for Lab #3, Task #4 import matplotlib.pyplot as p import math,numpy,random import channel reload(channel) import lab3 reload(lab3) import lab1 reload(lab1) import lab1_1 reload(lab1_1) # Takes a numpy array of samples, a number of samples per bit, and a # threshold for turning a selected sample from each bit period in 0 # bit or a 1 bit. Returns a numpy array of the bits. def receive(samples,samples_per_bit,vth): """ Apply a statistical measure to samples to determine which sample in the bit period should be used to determine the transmitted message bit. vth is the digitization threshold. Return a numpy array of received message bits. """ pass # your code here # Compares two numpy arrays of bits (0's and 1's), # return percentage mismatch def bit_error_rate(seq1,seq2): """ Perform a bit-by-bit comparison of two numpy arrays of bits, returning the fraction of mismatches. """ pass # your code here # Sends bits through the channel, receive, remove sync and return bits. def xmit_and_rcv(bits, mychannel, samples_per_bit, sync): # Convert the bits to samples samples = lab1.bits_to_samples(bits,samples_per_bit=samples_per_bit) # Now send through the chane noisy_data = mychannel(samples) # Truncate received date to ensure an integral number of bit periods noisy_data = noisy_data[0:len(noisy_data) - len(noisy_data)%samples_per_bit] # Use the average of the min and max as the threshold. vth = 0.5*(numpy.max(noisy_data) + numpy.min(noisy_data)) #print "vth", vth # Call your receive function with numpy array of received noisy data rcvd = receive(noisy_data,samples_per_bit,vth) # Yank off the sync, here's that convolution trick again. # Why is the sync reversed before the convolution. Why didn't we # do that with the mark in lab2 task 4? (Hint: symmetry). zero_centered_sync = sync[::-1] - 0.5 # Reverse and 0.5='1', -0.5='0' convolved_with_rcvd = numpy.convolve(zero_centered_sync, rcvd) max_conv = numpy.max(convolved_with_rcvd) start_index = numpy.nonzero(convolved_with_rcvd == max_conv)[0][0] # Get the rcvd data after the sync rcvd = rcvd[start_index+1:] return rcvd if __name__ == '__main__': # Noise standard deviation noise = 0.2 # bits of leading and trailing zeros as padding. pad_bits = 10 # A start of transmission sync byte. sync_seq = [1,1,0,0,0,0,0,1,0,1] # Pick channel one with the given noise, with Gaussian # (normal) distrib. mychannel = channel.channel(channelid='1', noise=noise, use_normal=True) # Generate 10,000 random bits bit_seq = [random.randint(0,1) for i in xrange(10000)] # Generate bit sequence with a start sync, plus lead and trail # padding. Turn sequences into numpy arrays for ease of processing # later. bit_seq_pad = [0]*pad_bits + [1]*pad_bits + \ sync_seq + bit_seq + [0]*pad_bits sbits = numpy.array(bit_seq_pad) sync = numpy.array(sync_seq) bits = numpy.array(bit_seq) for samples_per_bit in [200,50]: # Send bits through the channel, receive, remove sync # and return bits. rcvd = xmit_and_rcv(sbits, mychannel, samples_per_bit, sync) # Eliminate trailing bits rcvd = rcvd[0:len(bits)] # Check that enough bits were received lr = len(rcvd) ls = len(bits) assert lr==ls,"Number of rcvd bits=%d, " \ "Number of sent bits=%d.\n" \ "Probably you were unlucky and had a " \ "bit error in the sync bits.\n" \ "Try running again." % (lr,ls) # Finally, use your procedure to compute the percentage of # bit errors, or bit error rate, of rcvd bits. ber = bit_error_rate(bits, rcvd) print "bit error rate = %g for %d samples/bit." % \ (ber,samples_per_bit) # when ready for checkoff, enable the following line #lab3.checkoff(bit_error_rate,'L3_4')