瀏覽代碼

OFDM for optical channel

Tharmetharan Balendran 4 年之前
父節點
當前提交
af7ca6f522
共有 1 個文件被更改,包括 121 次插入0 次删除
  1. 121 0
      tests/ofdm_test.py

+ 121 - 0
tests/ofdm_test.py

@@ -0,0 +1,121 @@
+import itertools
+import math
+import numpy as np
+from models.custom_layers import OpticalChannel
+from matplotlib import pyplot as plt
+
+BANDWIDTH = 64e9
+
+CARDINALITY = 16
+DISPERSION_FACTOR = -21.7 * 1e-24
+FIBER_LENGTH = 50
+FIBER_LENGTH_STDDEV = 0
+RX_STDDEV = 0.01
+SIG_AVG = 0.5
+ENOB = 10
+
+# Number of OFDM symbols to simulate
+OFDM_N = 50
+# Number of OFDM subcarriers
+K = 16
+# length of the cyclic prefix: 25% of the block
+CP = K // 4
+# number of pilot carriers per OFDM block
+P = 8
+# The known value each pilot transmits
+pilotValue = 3 + 3j
+# DC offset used to ensure all values are positive
+DC_OFFSET = 50
+DC_OFFSET = np.asarray([DC_OFFSET])
+
+SHOW_PLOTS = True
+
+mapping_table = np.asarray([-3 - 3j, -3 - 1j, -3 + 3j, -3 + 1j,
+                            -1 - 3j, -1 - 1j, -1 + 3j, -1 + 1j,
+                            3 - 3j, 3 - 1j, 3 + 3j, 3 + 1j,
+                            1 - 3j, 1 - 1j, 1 + 3j, 1 + 1j])
+
+bits_per_symbol = int(math.log(CARDINALITY, 2))
+bits_lst = [list(i) for i in itertools.product([0, 1], repeat=bits_per_symbol)]
+
+# Set true to view plot of symbols as IQ plot
+if SHOW_PLOTS:
+    for idx, sym in enumerate(mapping_table):
+        plt.plot(sym.real, sym.imag, 'bo')
+        plt.text(sym.real, sym.imag + 0.2, str(bits_lst[idx])[1:-1], ha='center')
+
+    plt.title('Symbols used in each subcarrier')
+    plt.xlabel('I')
+    plt.ylabel('Q')
+    plt.xlim(-4, 4)
+    plt.ylim(-4, 4)
+    plt.show()
+
+
+# All subcarriers used
+allCarriers = np.arange(K)
+
+# Identifying pilot carriers (and adding final subcarrier as a pilot for convenience)
+pilotCarriers = allCarriers[::K // P]
+pilotCarriers = np.hstack([pilotCarriers, np.array([allCarriers[-1]])])
+P = P + 1
+
+# Removing pilot carriers to obtain data carriers
+dataCarriers = np.delete(allCarriers, pilotCarriers)
+
+if SHOW_PLOTS:
+    plt.plot(pilotCarriers, np.zeros_like(pilotCarriers), 'bo', label='pilot')
+    plt.plot(dataCarriers, np.zeros_like(dataCarriers), 'ro', label='data')
+    plt.show()
+
+# Generate random symbols as integers and then map symbol values onto them
+input_syms = np.random.randint(CARDINALITY, size=len(dataCarriers))
+mapped_syms = mapping_table[input_syms]
+
+# Generate the upper sideband of the OFDM symbol
+enc_stream_upper_f = np.zeros(K, dtype=complex)
+enc_stream_upper_f[pilotCarriers] = pilotValue
+enc_stream_upper_f[dataCarriers] = mapped_syms
+
+# Generate the lower sideband of the OFDM symbol
+enc_stream_lower_f = np.conjugate(np.flip(enc_stream_upper_f))
+
+# Combine the two sidebands with a DC offset to ensure values are always positive
+enc_stream_f = np.concatenate((DC_OFFSET, enc_stream_upper_f, enc_stream_lower_f), axis=None)
+
+if SHOW_PLOTS:
+    f = np.fft.fftfreq(enc_stream_f.shape[0], d=1/BANDWIDTH)
+    plt.plot(f, np.real(enc_stream_f), 'x')
+    plt.plot(f, np.imag(enc_stream_f), 'x')
+    # plt.xlim(-0.5e10, 0.5e10)
+    plt.show()
+
+# Take the inverse fourier transform
+enc_stream_t = np.fft.ifft(enc_stream_f)
+
+if SHOW_PLOTS:
+    t = np.arange(len(enc_stream_t))*(1/BANDWIDTH)
+    plt.plot(t, np.real(enc_stream_t))
+    plt.plot(t, np.imag(enc_stream_t))
+    plt.show()
+
+# Take the real part to be transmitted via the channel
+tx_stream = np.real(enc_stream_t)
+
+optical_channel = OpticalChannel(fs=BANDWIDTH,
+                                 num_of_samples=len(tx_stream),  # TODO: determine size of input to channel
+                                 dispersion_factor=DISPERSION_FACTOR,
+                                 fiber_length=FIBER_LENGTH,
+                                 fiber_length_stddev=FIBER_LENGTH_STDDEV,
+                                 lpf_cutoff=BANDWIDTH / 2,
+                                 rx_stddev=RX_STDDEV,
+                                 sig_avg=SIG_AVG,
+                                 enob=ENOB)
+
+# rx_stream = optical_channel(enc_stream_t)
+#
+# if SHOW_PLOTS:
+#     t = np.arange(len(tx_stream))*(1/BANDWIDTH)
+#     plt.plot(t, tx_stream)
+#     plt.plot(t, rx_stream)
+#     plt.show()