ofdm_test.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import itertools
  2. import math
  3. import numpy as np
  4. from models.custom_layers import OpticalChannel
  5. from matplotlib import pyplot as plt
  6. BANDWIDTH = 64e9
  7. CARDINALITY = 16
  8. DISPERSION_FACTOR = -21.7 * 1e-24
  9. FIBER_LENGTH = 50
  10. FIBER_LENGTH_STDDEV = 0
  11. RX_STDDEV = 0.01
  12. SIG_AVG = 0.5
  13. ENOB = 10
  14. # Number of OFDM symbols to simulate
  15. OFDM_N = 50
  16. # Number of OFDM subcarriers
  17. K = 16
  18. # length of the cyclic prefix: 25% of the block
  19. CP = K // 4
  20. # number of pilot carriers per OFDM block
  21. P = 8
  22. # The known value each pilot transmits
  23. pilotValue = 3 + 3j
  24. # DC offset used to ensure all values are positive
  25. DC_OFFSET = 50
  26. DC_OFFSET = np.asarray([DC_OFFSET])
  27. SHOW_PLOTS = True
  28. mapping_table = np.asarray([-3 - 3j, -3 - 1j, -3 + 3j, -3 + 1j,
  29. -1 - 3j, -1 - 1j, -1 + 3j, -1 + 1j,
  30. 3 - 3j, 3 - 1j, 3 + 3j, 3 + 1j,
  31. 1 - 3j, 1 - 1j, 1 + 3j, 1 + 1j])
  32. bits_per_symbol = int(math.log(CARDINALITY, 2))
  33. bits_lst = [list(i) for i in itertools.product([0, 1], repeat=bits_per_symbol)]
  34. # Set true to view plot of symbols as IQ plot
  35. if SHOW_PLOTS:
  36. for idx, sym in enumerate(mapping_table):
  37. plt.plot(sym.real, sym.imag, 'bo')
  38. plt.text(sym.real, sym.imag + 0.2, str(bits_lst[idx])[1:-1], ha='center')
  39. plt.title('Symbols used in each subcarrier')
  40. plt.xlabel('I')
  41. plt.ylabel('Q')
  42. plt.xlim(-4, 4)
  43. plt.ylim(-4, 4)
  44. plt.show()
  45. # All subcarriers used
  46. allCarriers = np.arange(K)
  47. # Identifying pilot carriers (and adding final subcarrier as a pilot for convenience)
  48. pilotCarriers = allCarriers[::K // P]
  49. pilotCarriers = np.hstack([pilotCarriers, np.array([allCarriers[-1]])])
  50. P = P + 1
  51. # Removing pilot carriers to obtain data carriers
  52. dataCarriers = np.delete(allCarriers, pilotCarriers)
  53. if SHOW_PLOTS:
  54. plt.plot(pilotCarriers, np.zeros_like(pilotCarriers), 'bo', label='pilot')
  55. plt.plot(dataCarriers, np.zeros_like(dataCarriers), 'ro', label='data')
  56. plt.show()
  57. # Generate random symbols as integers and then map symbol values onto them
  58. input_syms = np.random.randint(CARDINALITY, size=len(dataCarriers))
  59. mapped_syms = mapping_table[input_syms]
  60. # Generate the upper sideband of the OFDM symbol
  61. enc_stream_upper_f = np.zeros(K, dtype=complex)
  62. enc_stream_upper_f[pilotCarriers] = pilotValue
  63. enc_stream_upper_f[dataCarriers] = mapped_syms
  64. # Generate the lower sideband of the OFDM symbol
  65. enc_stream_lower_f = np.conjugate(np.flip(enc_stream_upper_f))
  66. # Combine the two sidebands with a DC offset to ensure values are always positive
  67. enc_stream_f = np.concatenate((DC_OFFSET, enc_stream_upper_f, enc_stream_lower_f), axis=None)
  68. if SHOW_PLOTS:
  69. f = np.fft.fftfreq(enc_stream_f.shape[0], d=1/BANDWIDTH)
  70. plt.plot(f, np.real(enc_stream_f), 'x')
  71. plt.plot(f, np.imag(enc_stream_f), 'x')
  72. # plt.xlim(-0.5e10, 0.5e10)
  73. plt.show()
  74. # Take the inverse fourier transform
  75. enc_stream_t = np.fft.ifft(enc_stream_f)
  76. if SHOW_PLOTS:
  77. t = np.arange(len(enc_stream_t))*(1/BANDWIDTH)
  78. plt.plot(t, np.real(enc_stream_t))
  79. plt.plot(t, np.imag(enc_stream_t))
  80. plt.show()
  81. # Take the real part to be transmitted via the channel
  82. tx_stream = np.real(enc_stream_t)
  83. optical_channel = OpticalChannel(fs=BANDWIDTH,
  84. num_of_samples=len(tx_stream), # TODO: determine size of input to channel
  85. dispersion_factor=DISPERSION_FACTOR,
  86. fiber_length=FIBER_LENGTH,
  87. fiber_length_stddev=FIBER_LENGTH_STDDEV,
  88. lpf_cutoff=BANDWIDTH / 2,
  89. rx_stddev=RX_STDDEV,
  90. sig_avg=SIG_AVG,
  91. enob=ENOB)
  92. # rx_stream = optical_channel(enc_stream_t)
  93. #
  94. # if SHOW_PLOTS:
  95. # t = np.arange(len(tx_stream))*(1/BANDWIDTH)
  96. # plt.plot(t, tx_stream)
  97. # plt.plot(t, rx_stream)
  98. # plt.show()