aboutsummaryrefslogtreecommitdiffstats
path: root/notebooks/FrameSynchronization.ipynb
blob: c3f1059f7053a39da9db8126904ec2085c615aff (plain)
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "57a55a8c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc4b9dfd",
   "metadata": {},
   "source": [
    "# Digital Frame Synchronization\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc118de2-937b-4157-a5a1-9b7f152bf59b",
   "metadata": {},
   "source": [
    "First we need to create the access code, a barker sequence which has a very good autocorrelation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "20dcd173-2889-4e21-9746-3d0a0ab060e8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Access code: 13 bit pattern [1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1] = left padded bytes [31, 53]\n"
     ]
    }
   ],
   "source": [
    "ac = [ 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, ]\n",
    "\n",
    "ac_pad = [0] * int(8 * np.ceil(len(ac) / 8) - len(ac)) + ac\n",
    "ac_bytes = list(np.packbits(ac_pad))\n",
    "\n",
    "print(f\"Access code: {len(ac)} bit pattern {ac} = left padded bytes {ac_bytes}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5cfd3c9a-d697-4462-bc26-26e82d25cbfd",
   "metadata": {},
   "source": [
    "To correlate with the access code we need its symbols, thus the functions to modulate the access code."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d328e765-e977-4de9-9694-35012193a0aa",
   "metadata": {},
   "source": [
    "### Symbols for QPSK"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "515891a9-dbd2-4088-9a41-b792d878f0fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "def modulate_qpsk(m):\n",
    "    ampl = 1\n",
    "    sym = {\n",
    "        0: ampl * (-1 -1j) / np.sqrt(2),\n",
    "        1: ampl * ( 1 -1j) / np.sqrt(2),\n",
    "        2: ampl * (-1 +1j) / np.sqrt(2),\n",
    "        3: ampl * ( 1 +1j) / np.sqrt(2)\n",
    "    }\n",
    "\n",
    "    return map(lambda k: sym[k], m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3a4c834f-7012-4e22-b9f3-865527d09c02",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Modulate chunks [0, 1, 3, 3, 0, 3, 1, 1] with QPSK into 8 symbols:\n",
      "[(-0.7071067811865475-0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (-0.7071067811865475-0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475-0.7071067811865475j)]\n",
      "\n",
      "Reversed complex conjugate list for FIR filter:\n",
      "[(0.7071067811865475+0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (-0.7071067811865475+0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475-0.7071067811865475j), (0.7071067811865475+0.7071067811865475j), (-0.7071067811865475+0.7071067811865475j)]\n"
     ]
    }
   ],
   "source": [
    "# convert into chunks of 2 bits for QPSK\n",
    "chunks = list(np.matmul(np.array(ac_pad).reshape((-1,2)), np.array([2, 1])))\n",
    "syms = list(modulate_qpsk(chunks))\n",
    "print(f\"Modulate chunks {chunks} with QPSK into {len(syms)} symbols:\\n{syms}\\n\")\n",
    "\n",
    "fir_syms = list(np.conj(syms[::-1]))\n",
    "print(f\"Reversed complex conjugate list for FIR filter:\\n{fir_syms}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d6155b2e-9405-4d20-8c05-72af45575a04",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABIkAAAEICAYAAADbZqSCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABFd0lEQVR4nO3de7heZX3n/883R85CQoQAgQQSoAngKUYcq0WFcgiHMNN2sCc6M9bya+3UX6cHZ35zslNnOp1Ox841tlwUa2m1UooSEVKsgo62iiRBBXNAEAgJCRAg4aCxSfb+/v5Y972zn519ftZa91rrfr+ua1/7kGc/z51FWM+d717vJ+buAgAAAAAAQN5mpF4AAAAAAAAA0mNIBAAAAAAAAIZEAAAAAAAAYEgEAAAAAAAAMSQCAAAAAACAGBIBAAAAAABADIkAZMzM3MyWpl4HAABAU5jZjWb2H8LHF5nZjtRrAlAfhkRA5szsy2a2x8zmpl7LZJjZT5vZBjN71cx2mdnfmtmPpl4XAABAFczsSTPbF/Y+8e0UM1scfuA1K9zuz81sf/j1F83sC2Z27jj3+5/N7MCI+/0td7/B3f/LOGu5uKrfK4D0GBIBGTOzxZLeLsklXZ12NRMzs1+X9BFJ/1XSSZJOl/THkq5JuCwAAICqXeXuxwx72znG7X7f3Y+RdKqkpyV9bIL7/esR9/v7pa56GCvw90+g4fifFMjbz0u6X9KfS7p++C+Y2SIz+4yZ7TazF8zs/wz7tV80sy1m9oqZbTazN4avn2Jmnw7f84SZ/eth37MqXAH0spk9a2Z/GL5+hJl9IjzGXjNbb2YnjVyomb1G0u9I+hV3/4y7f9/dD7j759z9N8Nt5prZR8xsZ3j7yPArpMzsN8PVRzvN7F+OuP+5ZvYHZvZUWN+NZnZk/4cYAACgXu6+T9Jtkl4/1e8NVyT97ihf/0sVP6D7XLzqKHz9QjP7WtjHfdvMLhr2PV82sw+b2T9I+oGkM6f1GwJQG4ZEQN5+XtInw9ulcThjZjMl3SVpm6TFKn4adWv4tZ+U9J/D9x6n4gqkF8JPhj4n6dvh9u+W9AEzuzQ81h9J+iN3P07SWSo2LlIxnHqNpEWS5ku6QdK+Udb6VklHSLpjnN/P/yfpQhUbotdJWiXp34d1XybpNyRdImmZpJGXSv93SWeH710afg//cZzHAgAAaCQzO1rSeyQ9VtZ9uvvPSXpKh65q+n0zO1XS3ZJ+V9I8FXutT5vZgmHf+nOS3ifpWBV7SwANxpAIyFR4HZ8zJN3m7hslfU/ST4dfXiXpFEm/Ga7Y+aG7/334tfequJR5vRcec/dtkt4saYG7/46773f3xyX9qaTrwvcdkLTUzE5091fd/f5hX58vaam7D7j7Rnd/eZQlz5f0vLsfHOe39TOSfsfdn3P33ZI+pGJjIkk/Jenj7v4dd/++ikFXPBYm6Rcl/b/u/qK7v6IiabtOAAAA6a0NV+rsNbO149zuN8xsr6RXJP2oDu2DxvJTw+53r5mdMsV1/aykde6+zt0H3f0LkjZIumLYbf7c3Te5+0F3PzDF+wdQM4ZEQL6ul/R37v58+PyvdCg5WyRp2xgDmUUqBkojnSHplOEbDUn/TsVrB0nSv1Jxpc7WkJRdGb7+l5I+L+nWkIH9vpnNHuX+X5B0YnxxxjGcot6fUG0LX4u/tn3Er0ULJB0laeOwtd8Tvg4AAJDaGnc/PrytGed2f+Dux6u4EnyfpHMmuN/bht3v8eO81tFYzpD0kyP2fz8qaeGw22wf9TsBNNJ4f9kC0FHhtXZ+StJMM3smfHmupOPN7HUqnsxPN7NZowyKtqvIxUbaLukJd1822mO6+6OS3hOytH8q6XYzmx+u6vmQpA+FF9JeJ+kRHf5Ci1+X9ENJayTdPsZvbaeKzcqm8Pnp4WuStEvFgEvDfi16XsVGaoW7Pz3GfQMAALSCuz9lZr8m6RYzuyu8RlEpdz3i8+2S/tLdf3EK3wOgwbiSCMjTGkkDkpareA2e10v6EUlfVfFaQw+oGKr8npkdHV5c+m3he29WcSnzm8K/UrHUzM4I3/Oymf22mR1pZjPN7Dwze7MkmdnPmtkCdx+UtDfc14CZvdPMzg+vg/SyivxsYOSC3f0lFa8R9FEzW2NmR5nZbDO73Mziv8TxKUn/3swWmNmJ4fafCL92m6RfMLPlZnaUpP807L4HVaRx/8vMXhvWe+qw11MCAABolZB+7VTxekBleVa9Lz79CUlXmdmlYe93hJldZGanlfiYAGrEkAjI0/UqXp/nKXd/Jr5J+j8qXtfHJF2l4gWcn5K0Q9I/lyR3/xtJH1aRp70iaa2kee4+EL7n9ZKeUHF1zs0qXpRaki6TtMnMXlXxItbXufsPJZ2s4sqglyVtkfR/dWiw08Pd/1DSr6t4MerdKn569f6wBql40cQNkh6S9LCkB8PX5O5/K+kjku5T8SKO9424+98OX7/fzF6W9EVNfIk2AABAk/0PSb81/F977dN/U/EDub1m9hvuvl3SNSpeYiDuzX5T/D0TaC1z5+o/AAAAAACA3DHhBQAAAAAAAEMiAAAAAAAAMCQCAAAAAACAGBIBAAAAAABA0qzUCxjPiSee6IsXL069DAAAUJGNGzc+7+4LUq8Dh7D/AgCg+8bagzV6SLR48WJt2LAh9TIAAEBFzGxb6jWgF/svAAC6b6w9GLkZAAAAAAAAGBIBAAAAAACAIREAAAAAAADEkAgAAAAAAABiSAQAAAAAAAAxJAIAAAAAAICkWakXgHQ2btuj+x9/QReeOV9vOuOE1MtJYuv6L2rP5vt0wvJ36dw3X5x6OclwHDAcfx4KnCMLHAeUhXNLgeNQ4NwSbH9AevKr0uK3S4tWpV5NMvx5KHAcCpwng0TnB3P32h5sqlauXOkbNmxIvYxOuv/x5/WzNz+ggUHXzBmma99wiha+5sjUy6rVnF3r9d7HP6A5OqABzdQ3T/hxDR5zSupl1W7Gqzv1hj1/pxka1H7N1rYrP5X3yThzW9d/UUvuuk6zdFD7NVsfO/N/af/CN6deVu12vbRPd3xzZ9bnSOnQcRh015xZM/TJ915Y+qbVzDa6+8pS7xR9qWL/Fc8ts3nO7XnO5Rzrmju7mnNLK2x/QPrzK6XBA9LMudL1d2Y5KNq4bY+uu+nrOjjAcy57D2nOzvX6pSf+tWZqQAOaqb3L/qkWnLIk9bLq9/LT0kN/LflgZeeHsfZgXEmUqb/42jYdHCwGhAcHXX+z8WmZJV5Uzf6fGV/RnFkHNMMk8wGt3PO30p7MDoIkyTUj/LZn+wHt2XyfxJAoW3s23atzdEBm0mw/qB989yv6k635bdyH//wk13Ok1HscDhwc1P2Pv5DnX+TQtz2b79MyHeQ5t+c5l3OslPm55YmvSgP/WHw8sL+4YiDDIdFXH92tAwN5/71EYu8RfXjm7Zo9a0BS8Xxx4mN/Iz2W4YHQsD8QNZ8fGBJl6rlXiiekmSbNruinw023df1c6a7b5O76oeZkewXN1vVf1OK7rtMRdkCuGTph+btSLwkJzTp+0dCGZEAzdPWan9JvZfj/xcZte/QzN9+vAwcHsz1HSocfhwvPnJ96SWipE5a/S/sf/1PN9oM6oFk859oBuSzrc+x7brpf+wcGNWOG5XtuOXrBoY9nzCqSkgzNDBuPGabKrlptA/YehRc//pfyJ4t96AHN0rbVeT5faPsD0i1XFwOimXNqPT8wJMrQS/sO6KEdL+mqCxbq3IXHZdu8nrv4dMlcT8x7u/7xrR/I8+Qj6dw3X6ytulWvufuXdHDGrGyPAwoHn39UAy7JZur7i3882z8PbzrjBH3yvRdm/7oAHAeUpXiu+VT2rzERn3NP+8INmnHU8dkehzedcYI+8d5V+oWPr9frFx2f77nlhe9KNlOSS8uvzvIqIkna+swres2Rs/WLb1+it551YrZ/HnjOlTQ4oHkvfFNPHvcG3fbi2Vr1zqt1UabnSS1aVSRmCV6TiCFRhr64+VntHxjUv/jRJXrj6RmefKLNayVJS37hJum4/F4XYbhz33yx7n/0F3Thd/9A2x/9thYte13qJSEBHxzUaU/foy1HvF7nLTlN83ZskAYHpRl5/kOYbzrjhDw3aCNwHFCWc998MTmzwnH44S9L935I2vuUdPzpqZeUxKol83XtG07VZx58Wvv2D+jIOTNTL6le7tKmz0pL3118/NQ3iveZ9UU/2H9Q9259Vj/5pkV6/7uWpV5Octk/5z51v/TqM5p35Yd046eP1czBpboo9ZpSWrQqyfA4z51/5tY9vEunvOYIvWHR8amXktamtdKiC7MfEEVL3vHTkqQd//CpxCtBKk9sXq9FvlPfX3qVtOJa6dVnpO33p14WAHTPijXF+82fTbqM1Fafv1D7DgzoS488l3op9Xv6Qemlp4rn2xXXFh/vfDD1qmr3pa279cMDg7ri/IWpl4Im2LxWmnWEjjv/Sl145nzd/fAuNfkf2uoqhkSZeWnfAX310ed1xfkLZZn9pKLH7u9Kz20qnpQhSTrptLO0dfZyvXb7PamXgkSevf9WDbhp2Tuuk86+TJp1RDFMBQCUa96Z0sLXZX+OXbVknk48Zo7ufnhX6qXUb/Md0ozZ0jlXSOdeUXyc4Z+HdQ/v0onHzNWqJfNSLwWpDQ5Im++Ull0izT1Gqy9YqMd3f1+PPPtK6pVlhyFRZmJqdsUFmU/rQ2qm5VcnXUbT7F1yhc4aeELbH/126qWgZodSs9dp3kmnSXOPkZZeXPyUe3Aw9fIAoHuWr5Ge3lAkZ5maNXOGLl1xsu7b8pz27R9IvZz6xNTsrHdKRx4vHXmCdOZFxZAoo6smYmp2+Xkna+aMjH94jUJIzbR8jSTp0hUna4ZJdz+U4RA5MYZEmSE1C0jNRkVylq+e1CwiOQOA6pCcSco0ORuemkUZJmekZugRUjOdfZkk6cRj5pKcJcKQKCOkZgGp2ZhIzvLVk5pFJGcAUB2SM0mZJmfDU7Mow+SM1AxDRqRmEclZGgyJMkJqFpCajYvkLD+HpWYRyRkAVIvkLL/kbGRqFmWWnJGaoceI1CwiOUuDIVFGSM0CUrNxkZzlZ9TULCI5A4DqkJxJyiw5Gy01izJKzkjN0GNEahaRnKXBkCgTpGYBqdmESM7yM2pqFpGcAUB1SM4kZZacjZaaRRklZ6RmGDJGahaRnNWvlCGRmV1mZo+Y2WNm9sExbnORmX3LzDaZ2f8t43ExeaRmAanZpJCc5WPM1CwiOQMajT1YB5Cc5ZOcjZWaRZkkZ6Rm6DFGahaRnNWv7yGRmc2U9FFJl0taLuk9ZrZ8xG2Ol/THkq529xWSfrLfx8XUkJoFpGaTQnKWj3FTs4jkDGgk9mAdQXImKZPkbLzULMogOSM1Q48xUrOI5Kx+ZVxJtErSY+7+uLvvl3SrpGtG3OanJX3G3Z+SJHfv8Nm/eUjNAlKzSSM5y8e4qVlEcgY0FXuwLiA5k5RJcjZeahZlkJyRmmHIBKlZRHJWrzKGRKdK2j7s8x3ha8OdLekEM/uymW00s58f687M7H1mtsHMNuzevbuE5YHULCA1mxKSs+6bMDWLSM6ApiptD8b+KzGSs+4nZxOlZlHHkzNSM/SYIDWLSM7qVcaQaLT/u0ee0WZJepOk1ZIulfQfzOzs0e7M3W9y95XuvnLBggUlLA+kZgGp2ZSQnHXfpFKziOQMaKLS9mDsvxIjOZPU8eRsMqlZ1OHkjNQMPSZIzSKSs3qVMSTaIWnRsM9Pk7RzlNvc4+7fd/fnJX1F0utKeGxMgNQsIDWbMpKz7ptUahaRnAFNxB6sK0jOJHU8OZtMahZ1ODkjNcOQSaZmEclZfcoYEq2XtMzMlpjZHEnXSbpzxG0+K+ntZjbLzI6S9BZJW0p4bEyA1CwgNZsWkrPumnRqFpGcAU3EHqxLSM66m5xNNjWLOpqckZqhxyRTs4jkrD59D4nc/aCk90v6vIpNx23uvsnMbjCzG8Jttki6R9JDkh6QdLO7f6ffx8bESM0CUrNpITnrrimlZhHJGdAo7ME6huRMUkeTs6mkZlEHkzNSM/SYZGoWkZzVp4wrieTu69z9bHc/y90/HL52o7vfOOw2/8Pdl7v7ee7+kTIeF+MjNQuef5TUbJpIzrorpmZLJ5OaRSRnQOOwB+uQeWdKJ1+Q/Tm2k8nZVFKzqIPJGakZhgwOTik1i0jO6lHKkAjNRGoWxCdXUrNpITnrnuGp2fzJpGYRyRkAVGvFtSRnXUvOppqaRTE527y2E8kZqRl6bJ9aahaRnNWDIVGHkZoFm+4gNesDyVn3TCs1i0jOAKA6JGeSOpacTSc1i1ZcWwwMO5CckZqhx6Y7ppSaRSRn9WBI1FGkZgGpWd9IzrpnWqlZRHIGANUhOZPUseRsOqlZ1KHkjNQMQ6aZmkVXnE9yVjWGRB1FahaQmpWC5Kw7pp2aRSRnAFAtkrPuJGfTTc2ijiRnpGboMc3ULLrsPJKzqjEk6ihSs4DUrBQkZ93RV2oWkZwBQHVIziR1JDnrJzWLOpCckZqhxzRTs4jkrHoMiTro5R+SmkkiNSsRyVl39JWaRSRnAFAdkjNJHUnO+knNog4kZ6RmGNJnahaRnFWLIVEHkZoFpGalIjlrPx8c1Kk7Pz/91CwiOQOAapGctT856zc1i1qenP1g/0Hdt/U5UjMU+kzNopicrSM5qwRDog66+yFSM0mkZiUjOWu/Jzav1+mDT+sHS6/s/85IzgCgOiRnklqenMXUrM+/DEsq/jy0NDn70tbd2ndggNQMhT5TsygmZ3eRnFWCIVHHkJoFQ6nZmtQr6YyTTjtLW2f9CMlZi8XU7Kx3vKf/Ozv7UpIzAKgKyZmkIjmbf3RLk7OYmp3bR2oWnbu6tckZqRmGxNRs6cV9pWYRyVl1GBJ1DKlZMJSaXZN0GV2z98zVJGctVVpqFs09luQMAKpEcqZZM2fosvNamJz1pGYn9H9/LU3OSM3QI6ZmJb1eLMlZdRgSdQypWUBqVgmSs/YqNTWLSM4AoDokZ5JampyVmZpFLUzOSM3Qo6TULCI5qw5Dog4hNQtIzSpDctZepaZmEckZAFSH5ExSS5OzMlOzqIXJGakZhpScmkUkZ9VgSNQhpGYBqVmlSM7ap/TULCI5A4BqkZy1LzkrOzWLWpackZqhR8mpWURyVg2GRB1CahaQmlWK5Kx9KknNIpIzAKgOyZmkliVnVaRmUYuSM1Iz9Cg5NYtIzqrBkKgjYmp2OakZqVnFSM7ap5LULCI5A4DqkJxJallyVkVqFrUoOSM1w5CKUrOI5Kx8DIk6IqZmq0nNivekZpUiOWuPylKziOQMAKpFctae5Kyq1CxqSXJGaoYeFaVmEclZ+RgSdQSpWUBqVguSs/aoNDWLSM4AoDokZ5JakpxVmZpFLUjOSM3Qo6LULCI5Kx9Dog4gNQtIzWpDctYelaZmEckZAFSH5ExSS5KzKlOzqAXJGakZhlScmkUkZ+ViSNQBpGYBqVmtSM6ar/LULIrJ2ZY7Sc4AoAokZ81PzqpOzaKGJ2ekZuhRcWoWkZyVq5QhkZldZmaPmNljZvbBcW73ZjMbMLOfKONxUSA1CzavJTWrEclZ89WSmkUrrpVe2SVt/0b1jwVgCHuwTJCcSWp4clZHahYNJWffrP6xpojUDD02ra00NYtIzsrV95DIzGZK+qikyyUtl/QeM1s+xu3+u6TP9/uYOITULHj+UenZ75Ca1YjkrPlqSc2ioeTsjuofC4Ak9mBZITmT1PDkrI7ULBpKzpr3nEtqhiGDg8Vgu+LULCI5K08ZVxKtkvSYuz/u7vsl3SpptN7nVyV9WlIDR//tRWoWkJolQXLWXLWlZhHJGZACe7CcrFhDctbU5Kyu1CxqaHIWU7PLzjuJ1Ay1pWYRyVl5yhgSnSpp+7DPd4SvDTGzUyVdK+nGie7MzN5nZhvMbMPu3btLWF63kZoFpGZJkJw1V62pWURyBtSttD0Y+68WiBkTyVnzkrM6U7OogclZTM1Wn89+HKotNYtIzspTxpBotDHxyP8qH5H02+4+4cjf3W9y95XuvnLBggUlLK+7SM0CUrNkSM6aq9bULCI5A+pW2h6M/VcLzD+L5EwNTc7qTM2iBiZnpGYYUnNqFpGclaOMIdEOSYuGfX6apJ0jbrNS0q1m9qSkn5D0x2a2poTHzhqpWUBqlhTJWfPUnppFJGdA3diD5YbkrHnJWd2pWdSw5IzUDD1qTs0ikrNylDEkWi9pmZktMbM5kq6TdOfwG7j7Endf7O6LJd0u6ZfdfW0Jj501UrOA1CwpkrPmSZKaRSRnQJ3Yg+WG5ExSw5KzFKlZ1KDkjNQMPWpOzSKSs3L0PSRy94OS3q/iX8zYIuk2d99kZjeY2Q393j9GR2oWkJolR3LWPElSs4jkDKgNe7AMkZxJalhyliI1ixqUnJGaYUii1CwiOetfGVcSyd3XufvZ7n6Wu384fO1Gdz/sRRLd/Rfc/fYyHjdnpGYBqVkjDCVnjz2ceinZS5aaRSRnQK3Yg2VoKDnbPuFNu6oxyVmq1CxqSHK2b/8AqRkOSZSaRSRn/StlSIT6kZoFpGaNEJOzp/+e5Cy1J7ckTM0ikjMAqA7JmaRDydmXUyZnOxOmZlEDkrMvPfIcqRkOSZSaRSRn/WNI1EKkZgGpWWPE5GzB9nWpl5K9Z76eMDWLSM4AoDpDyVne59iYnN2VMjnblDA1ixqQnN39EKkZgsSpWURy1h+GRC1EahaQmjUKyVl6yVOziOQMAKpFcpY+OUudmkWJkzNSM/RInJpFJGf9YUjUQuseJjWTRGrWMCRn6TUiNYtIzgCgOiRnkhInZ01IzaKEyRmpGXokTs2imJzdTXI2LQyJWublHx7QV75LakZq1jwkZ+k1IjWLzr5Umjk3+xwCACpBciYpcXLWhNQsOucKacasJH8eSM0wpCGpWXTF+Qv1PZKzaWFI1DKkZgGpWSORnKXTmNQsmnustOwSkjMAqArJWbrkrCmpWXTUPOnMd9aenJGaoUdDUrOI5Gz6GBK1DKlZQGrWSCRn6TQqNYtIzgCgOiRnkhIlZ01KzaIEyRmpGXo0JDWLSM6mjyFRi5CaBaRmjUVylk6jUrOI5AwAqkNyJilRctak1CxKkJyRmmFIw1KziORsehgStQipWRBTsx+5OukyMLq9S64gOatZ41KziOQMAKpFcqZZM2fo0jqTs6alZlHNyRmpGXo0LDWLSM6mhyFRi5CaBTE1e82pqVeCUSwmOatdI1OziOQMAKpDciZJurLO5KyJqVlUY3JGaoYeQ6nZpalX0oPkbHoYErUEqVlAatZ4Jy9aSnJWs0amZhHJGQBUh+RMUs3JWRNTs6jG5IzUDEN6UrNjU6/mMCRnU8eQqCVIzQJSs1YgOatPY1OziOQMAKpFclZfctbU1CyqKTkjNUOPhqZmEcnZ1DEkaglSs4DUrBVIzuoTU7Pvn9XA1CwiOQOA6pCcSaopOWtyahbVkJzF1OyK8zP/4TUKDU3NIpKzqWNI1AKkZgGpWWuQnNUnpmZLf6yBqVkUk7PNa1OvBAC6h+RMUk3JWZNTsygmZxU+5xap2Ry9Zcn8yh4DLdHw1CwiOZsahkQtQGoWkJq1CslZ9RqfmkUxOdv8WZIzAKgCyVn1yVnTU7MoJmeb7qgkOTuUmp1MaobGp2YRydnUMCRqAVKzgNSsVUjOqteK1CwiOQOA6pCcSao4OWtDahZVmJyRmqFHw1OziORsahgSNRypWUBq1jokZ9VrRWoWkZwBQHVIziRVnJy1ITWLKkzOSM0wpCWpWURyNnkMiRoupmbZT+tJzVqJ5Kw6rUnNIpIzAKgWyVl1yVlbUrOoouSM1Aw9WpKaRSRnk8eQqOFIzQJSs1YiOatOq1KziOQMAKpDciapouSsTalZVEFyRmqGHi1JzaITj5mrtywhOZuMUoZEZnaZmT1iZo+Z2QdH+fWfMbOHwtvXzOx1ZTxu1w1PzWbkPK0nNWstkrPqtCo1i0jOgNKxB8MQkjNJFSVnbUrNogqSM1IzDGlZahatvoDkbDL6HhKZ2UxJH5V0uaTlkt5jZstH3OwJST/m7hdI+i+Sbur3cXNAahaQmrUayVn5WpeaRSRnQKnYg+EwJGflJ2dtS82ikpMzUjP0aFlqFpGcTU4ZVxKtkvSYuz/u7vsl3SrpmuE3cPevufue8On9klr0t5p0SM0CUrNWIzkrXytTs4jkDCgTezD0IjmTVHJy1sbULCoxOSM1Q4+WpWYRydnklDEkOlXS8B9X7AhfG8u/kvS3Y/2imb3PzDaY2Ybdu3eXsLx2IjULSM1aj+SsfK1MzSKSM6BMpe3B2H91BMmZpJKTszamZlGJyRmpGYa0NDWLSM4mVsaQaLQJxqhjOTN7p4oNym+PdWfufpO7r3T3lQsWLChhee1EahaQmnUCyVl5WpuaRSRnQJlK24Ox/+oQkrPykrO2pmZRSckZqRl6tDQ1i0jOJlbGkGiHpEXDPj9N0s6RNzKzCyTdLOkad3+hhMftNFKzgNSsE0jOytPq1CwiOQPKwh4MhyM5k1RSctbm1CwqITkjNUOPlqZmEcnZxMoYEq2XtMzMlpjZHEnXSbpz+A3M7HRJn5H0c+7+3RIes9NIzQJSs844lJyNWZpikp79+l+3NzWLSM6AsrAHw+Ficpb5OTYmZ3f3k5xtWtve1CwqITm7+2FSMwQtT80ikrPx9T0kcveDkt4v6fOStki6zd03mdkNZnZDuNl/lDRf0h+b2bfMbEO/j9tlpGYBqVmnFMnZ4yRnffDBQZ2y8x5tnXtBO1OziOQMKAV7MIxpxRppx3qSs/NO1r3TTc7ci73omRe1MzWLjppX/B6mmZzt2z+g+7aQmiFoeWoWkZyNr4wrieTu69z9bHc/y90/HL52o7vfGD5+r7uf4O6vD28ry3jcriI1C0jNOoXkrH8xNXt16VWpl9I/kjOgFOzBMCqSM0l9JmcxNWv5X4YlFb+HaSZnpGbo0fLULCI5G18pQyKUh9QsIDXrHJKz/nUiNYtIzgCgOiRnkvpMzrqQmkV9JGekZhjSkdQsisnZd599NfVSGochUcOQmgWkZp1EcjZ9nUnNIpIzAKgWydn0k7OupGbRNJMzUjP06EhqFsXk7O6HDvv3HrLHkKhhSM0CUrNOIjmbvk6lZhHJGQBUh+RM0jSTsy6lZtE0kjNSM/ToSGoWkZyNjSFRg5CaBc8/RmrWUSRn09ep1CwiOQOA6sw/Szr5/OzPsdNKzrqUmkXTSM5IzTBkcFDacmdnUrOI5Gx0DIkahNQs2HxH8Z7UrJNIzqauc6lZRHIGANVacS3J2VSTs66lZtFQcrZ2UskZqRl6bP9GcfV3l66uE8nZWBgSNQipWbBpLalZh5GcTV0nU7OI5AwAqkNyJmmKyVkXU7NoxbXS3m2TSs5IzdBj0x2dSs0ikrPRMSRqCFKzgNSs80jOpq6TqVlEcgYA1SE5kzTF5KyLqVk0heSM1AxDOpqaRSRnh2NI1BCkZgGpWRZIziavs6lZRHIGANUiOZt8ctbV1CyaZHJGaoYeHU3NIpKzwzEkaghSs2DTWmnRW0jNOo7kbPI6nZpFJGcAUB2SM0nS6skkZ11OzaJJJGekZuix6Y7iqu+OpWYRydnhGBI1AKlZMJSadfiJGZJIzqai06lZRHIGANUhOZMkvWUyyVmXU7NoEskZqRmGxNRs2SWdTM0ikrNeDIkagNQsIDXLCsnZxDqfmkUkZwBQLZKziZOzrqdm0QTJGakZenQ8NYtIznoxJGoAUrOA1CwrJGcTyyI1i0jOAKA6JGeSJkjOckjNonGSM1Iz9Oh4ahaRnPViSJQYqVlAapYdkrOJZZGaRSRnAFAdkjNJEyRnOaRm0TjJGakZhmSSmkVXkJwNYUiUGKlZQGqWJZKzsWWTmkUkZwBQLZKzsZOzXFKzaIzkjNQMPTJJzaLLVpCcRQyJEiM1C0jNskRyNrasUrOI5AwAqkNyJmmM5Cyn1CwaJTkjNUOPTFKzaMGxJGcRQ6KESM0CUrNskZyNLavULCI5A4DqkJxJGiM5yyk1i0ZJzkjNMCSz1CwiOSswJEqI1CwgNcsaydnhskvNIpIzAKgWydnhyVluqVk0IjkjNUOPzFKziOSswJAoIVKzgNQsayRnh8syNYtIzgCgOiRnkkYkZzmmZtGw5IzUDD0yS80ikrMCQ6JESM0CUrPskZwdLsvULCI5A4DqkJxJGpGc5ZiaRcOSM1IzDMk0NYtIzkoaEpnZZWb2iJk9ZmYfHOXXzcz+d/j1h8zsjWU8bpuRmgWkZhDJ2XDZpmYRyRkwJezBMGUkZ8OSs2c1uOmO/FKzKCRng5vW6r4tz5KaoZBpahaRnJUwJDKzmZI+KulyScslvcfMlo+42eWSloW390n6k34ft+1IzQJSM4jkbLisU7OI5AyYFPZgmBaSM0lFcrbs4KOa8dL2bP8yLElaca1m7N2mpQcf44fXKGSamkUkZ+VcSbRK0mPu/ri775d0q6RrRtzmGkl/4YX7JR1vZtmehUjNAlIzBCRnh2SdmkUkZ8BksQfD1JGcSSqSs392xAYd1Kw8U7PonCs0oJn6iSPWk5oh+9Qsyj05K2NIdKqk4der7ghfm+ptJElm9j4z22BmG3bv3l3C8pqH1CwgNcMwJGdFarZw5+fzTc0ikjNgskrbg+Ww/8Iwy9eQnM0wXTX7AX3Nz9O+mcelXk4y+2a9Rv/g5+uq2Q9oZsY/u0aQeWoW5Z6clTEkGu10MvK6rMncpvii+03uvtLdVy5YsKDvxTXRuod3aSGpmbTps6RmGEJyVqRmZwzu0KtLr0y9lPSWryk2KTseSL0SoMlK24PlsP/CMPEvgDknZzsf1Lz9u/S5g6uKf+UsU1965Dl97uAqzdu/S9r1rdTLQWqb12admkW5J2dlDIl2SFo07PPTJI0cuU3mNlmIqdkVpGbSsw9nP6XGISRnpGY9zrms2KRsuiP1SoAmYw+G6SE5kzatlc+YrfVz/0nxr5xl6u6Hd2njEW+Vz5jFc27uBgeLwXHmqVmUc3JWxpBovaRlZrbEzOZIuk7SnSNuc6eknw//wsaFkl5y9yzPxvduITWTRGqGUeWcnPWmZosm/oauIzkDJoM9GKYv5+TMXdq8VnbmRfon5y/VfVuf0779A6lXVbt9+wd035bn9NbzlsnOvKj4B2UyvGoCAalZj6HkLMMhct9DInc/KOn9kj4vaYuk29x9k5ndYGY3hJutk/S4pMck/amkX+73cdvq7odIzSSRmmFUOSdnpGajIDkDxsUeDH3JOTnb+aC09ylpxRqtPn+hfrB/IMvk7EuPPKd9Bwa0+oKFxXPu3m0kZzkjNesxlJw9tDO75KyMK4nk7uvc/Wx3P8vdPxy+dqO73xg+dnf/lfDr57v7hjIet21IzQJSM4wh5+SM1GwUJGfAhNiDYdpyTs42rZVmzJbOXa23LJmn+UfPyfJqgbsf3qUTj5lT/Ktm566WSM7yRWo2qlyTs1KGRJgcUrOA1AzjyDE5IzUbA8kZAFQrx+QspGY68yLpyBM0a+YMXXreydklZzE1u3TFyZo5w6Sj5hXHhOQsT6Rmo8o1OWNIVCNSs4DUDOPIMTkjNRsHyRkAVCfH5GxYahblmJz1pGYRyVm+SM1GlWtyxpCoJqRmAakZJpBjckZqNg6SMwCoTo7J2bDULMoxOetJzSKSszyRmo0rx+SMIVFNSM0CUjNMQk7JGanZBEjOAKBaOSVnI1KzKLfk7LDULCI5yxOp2bhyTM4YEtWE1CwgNcMk5JSckZpNAskZAFQnp+RslNQsyik5GzU1i0jO8kNqNq4ckzOGRDUgNQtIzTBJOSVnpGaTQHIGANXJKTkbJTWLckrORk3NIpKzvJCaTUpuyRlDohqQmgWkZpiCHJIzUrNJIjkDgGrlkJyNkZpFuSRnY6ZmEclZXkjNJiW35IwhUQ1IzQJSM0xBDskZqdkUkJwBQHVySM7GSc2iHJKzcVOziOQsH6Rmk5JbcsaQqGKkZkFMzZavSb0StMTJi5bqkVnndjo5IzWbApIzAKhODsnZOKlZ9JYl8zSv48nZuKlZRHKWB1KzKckpOWNIVDFSsyCmZsuvSbsOtMqeJas7m5yRmk0RyRkAVKvLydkEqVk0a+YMXdbh5GzC1CwiOcsDqdmU5JScMSSqGKlZQGqGaehyckZqNg0kZwBQnS4nZ5NIzaIuJ2eTSs0ikrPuIzWbkpySM4ZEFSI1C0jNME1dTs5IzaaB5AwAqtPl5GwSqVnU5eRsUqlZRHLWbaRm05JLcsaQqEKkZgGpGfrQxeSM1GyaSM4AoFpdTM4mmZpFXU3OJp2aRSRn3UZqNi25JGcMiSpEahaQmqEPXUzOSM36QHIGANXpYnI2hdQs6mJyNqXULCI56y5Ss2nJJTljSFQRUrOA1Ax96mJyRmrWh6HkbG3qlQBA93QxOZtCahZ1MTmbUmoWDSVnaytbFxIgNetLDskZQ6KKkJoFpGYoQZeSM1KzPg0lZ2tJzgCgCl1KzqaYmkVdS86mnJpFQ8nZHSRnXUJq1pcckjOGRBUhNQtIzVCCLiVnpGYlIDkDgOp0KTmbRmoWdSk5G0rNpvPDa5Kz7iE160sOyRlDogqQmgWkZihJl5KzmJqd9Q5Ss2kjOQOA6nQpOZtGahZ1KTmLqdmqJfOm/s0kZ91CalaKridnDIkqQGoWkJqhRDE52/HYd1IvZdqGp2YnnkxqNm0kZwBQrZicvbQj9Uqmb5qpWTQ8OfvhgfYmZ8NTs1kzp/FXP5KzbiE1K0XXk7O+hkRmNs/MvmBmj4b3h52BzWyRmX3JzLaY2SYz+7V+HrMN7n7oGVIzidQMpYrJ2fZ/+KvEK5m+J7duJDUrC8kZMsceDJXqQnK285vTTs2iLiRnX+4nNYtIzrqD1KwUMTlb9/CuTiZn/V5J9EFJ97r7Mkn3hs9HOijp37j7j0i6UNKvmNnyPh+3sYrUbDepGakZShaTs9c+1d7k7NmvfYrUrCwkZwB7MFQnJmeb7ki9kunbdEeRSZ1zxbTvIiZndz3U3qsF7uonNYtIzrqB1KxUV1ywUI8992onk7N+h0TXSLolfHyLpDUjb+Duu9z9wfDxK5K2SOrspSWkZgGpGSrQ5uSM1KxkJGcAezBUq83J2VBq9s4il5qmtidnfadmEclZN5CalarLyVm/Q6KT3H2XVGxEJL12vBub2WJJb5D0jXFu8z4z22BmG3bv3t3n8upHahaQmqECbU7OSM0qQHKGvJW6B2v7/gsVaHNyVkJqFrU5OSslNYtIztqP1KxUXU7OJhwSmdkXzew7o7xN6RIRMztG0qclfcDdXx7rdu5+k7uvdPeVCxYsmMpDJEdqFpCaoSJtTs5IzSpAcoaOq3MP1ub9FyrS5uSshNQsanNyVkpqFpGctRupWSW6mpxNOCRy94vd/bxR3j4r6VkzWyhJ4f2oI3Yzm61ic/JJd/9Mmb+BJiE1C0jNUKE2JmekZhUhOUPHsQdDcm1MzkpKzaK2JmelpWYRyVm7kZpVoqvJWb9njDslXR8+vl7SYdejmplJ+pikLe7+h30+XqORmgWkZqhQG5MzUrMKkZwhX+zBUL02JmclpmZRG5OzUlOziOSsvUjNKtHV5KzfIdHvSbrEzB6VdEn4XGZ2ipmtC7d5m6Sfk/QuM/tWeOv/2s+GITULSM1QsTYmZ6RmFSI5Q77Yg6F6bUzOSkzNojYmZ6WmZhHJWTuRmlWqi8lZX0Mid3/B3d/t7svC+xfD13e6+xXh4793d3P3C9z99eFt3fj33D6kZgGpGWrQpuSM1KxiJGfIFHsw1KZNyVnJqVnUtuSs9NQsIjlrJ1KzSnUxOSvxrJE3UrOA1Aw1aFNyRmpWA5IzAKhOm5KzClKzqE3JWSWpWURy1j6kZpVacOxcrVoyr1PJGUOiEsTU7PLzSM1IzVCHNiVnpGY1IDkDgOq0KTmrIDWL2pScVZKaRSRn7UJqVovVF5zSqeSMIVEJYmq2+gJSM0mkZqhFG5IzUrOakJwBQLXakJxVlJpFbUnOKkvNIpKzdiE1q0XXkjOGRCUgNQtIzVCjNiRnpGY1IjkDgOq0ITmrMDWL2pCcVZqaRSRn7UFqVouuJWcMifpEahaQmqFmbUjOSM1qRHIGANVpQ3JWYWoWtSE5qzQ1i0jO2oHUrFZdSs4YEvWJ1CwgNUMCTU7OSM1qRnIGANVqcnJWcWoWNT05qzw1i0jO2oHUrFZdSs4YEvWJ1CwgNUMCTU7OSM0SIDkDgOo0OTmrITWLmpyc1ZKaRSRnzUdqVqsuJWcMifpAaha88D1SMyTR5OSM1CwBkjMAqM78s6STGpqc1ZCaRU1Ozu56eJfmH11xahaRnDUbqVkSXUnOGBL1gdQs2ERqhnT2LLmicckZqVkiQ8nZZ0nOAKAKK9Y0LzmrKTWLZs2coUtXNC85i6nZZedVnJpFMTnbvJbkrIl2PFBcXc0P8WvVleSMIVEfSM2CTWtJzZDM4rc3LzkjNUto+RrplZ0kZwBQhSYmZzWmZtGVFzQvOas1NYuWr5H2PEly1kSb7iiurj7nstQryUpXkjOGRNNEahaQmiGxk09f1rjkjNQsIZIzAKhOE5OzGlOzqInJWa2pWURy1kykZkl1ITljSDRNpGYBqRkaoEnJGalZYiRnAFCtJiVnNadmUdOSs9pTs4jkrJlIzZLqQnLGkGiaSM0CUjM0QJOSM1KzBiA5A4DqNCk5S5CaRU1KzpKkZhHJWfOQmiXVheSMIdE0kJoFpGZoiCYlZ6RmDUByBgDVaVJyliA1i5qUnCVJzSKSs2YhNWuEtidnDImmgdQsIDVDgzQhOSM1awiSMwCoVhOSs0SpWdSU5CxZahaRnDULqVkjtD05Y0g0DaRmAakZGqQJyRmpWYOQnAFAdZqQnCVMzaImJGdJU7OI5Kw5SM0aYXhy1kYMiaboFVKzAqkZGiYmZwueuifZGp75+q2kZk1BcgYA1RlKztamW8PmtclSsygmZ3c//EyyNdydMjWLSM6agdSsUQ4lZ6+kXsqUMSSaoi+SmhVIzdBAe5ZcoaUD30uSnPngoE55+h5tnXs+qVkTzD1WWnoxyRkAVGXFmuJqzRTJmXuxFz3zoiSpWRSTs3u3PJskOdu3f0D3pkzNoqPmSUt+jOQsNVKzRonJWRNet2yqGBJNEalZQGqGBkqZnB1Kza6q/bExhhXXkpwBQFVSJmdDqdm19T/2CCmTs0akZtGKa0nOUiM1a5Q2J2d9DYnMbJ6ZfcHMHg3vTxjntjPN7Jtmdlc/j5kSqVlAaoaGSpmckZo1EMkZOiy3PRgaKGVy1oDULEqZnDUiNYtIztIiNWuktiZn/V5J9EFJ97r7Mkn3hs/H8muStvT5eEmRmgWkZmiwFMkZqVlDkZyh27Lag6GhUiRnDUnNolTJWWNSs4jkLC1Ss0Zqa3LW7xnlGkm3hI9vkbRmtBuZ2WmSVku6uc/HS4rULCA1Q4OlSM5IzRqM5AzdldUeDA2VIjlrUGoWpUjOGpWaRSRn6ZCaNVJbk7N+h0QnufsuSQrvXzvG7T4i6bckTfijXDN7n5ltMLMNu3fv7nN55SE1C0jN0HApkjNSswYjOUN3lboHa+r+Cw2XIjlrUGoWpUjOGpWaRSRnaZCaNdrq8xe2LjmbcEhkZl80s++M8jap1sjMrpT0nLtvnMzt3f0md1/p7isXLFgwmW+pBalZQGqGFqgzOSM1aziSM7RYnXuwpu6/0AJ1JmcNS82iupOzxqVmEclZGqRmjXbpee1LziY8q7j7xe5+3ihvn5X0rJktlKTwfrRrLN8m6Woze1LSrZLeZWafKPH3UAtSs4DUDC1QZ3JGatYCJGdoKfZgaIU6k7MGpmZRnclZI1OziOSsfqRmjfbaY49oXXLW7+j5TknXh4+vl3TYs4O7/1t3P83dF0u6TtJ97v6zfT5urUjNAlIztESdyRmpWQuQnKGbstiDoQXqTM4amJpFdSZnjUzNIpKzepGatULbkrN+h0S/J+kSM3tU0iXhc5nZKWa2rt/FNQWpWUBqhhapIzkjNWsJkjN0UxZ7MLTEimuqT84amppFdSVnMTW7tGmpWURyVi9Ss1ZoW3LW15nF3V9w93e7+7Lw/sXw9Z3uftiI392/7O5X9vOYKZCaBZvXkpqhNepIzkjNWmQoOVufeiVAKXLZg6EllteQnDU4NYvqSM5ianZlE1OzaCg5+3bqlXTfprWkZi3QtuSsgePnZiE1C174nvQMqRnao47kjNSsRYaSsztSrwQAuufEpdUnZw1OzaI6krNGp2bRUHLGc26lBgeL/y9IzVqhTckZQ6IJkJoFpGZooSqTM1KzliE5A4BqVZmcNTw1i6pOzhqfmkUkZ/UgNWuVNiVnDT67NAOpWUBqhhaqMjkjNWshkjMAqE6VyVkLUrOoyuSsFalZRHJWPVKzVmlTcsaQaBykZgGpGVqqyuSM1KyFSM4AoDpVJmctSM2iKpOzVqRmEclZtUjNWqktyRlDonEcSs1OTr2UtEjN0GJVJGekZi1FcgYA1aoiOWtJahZVlZy1JjWLSM6qRWrWSm1JzlpwhknnUGp2QuqlpEVqhharIjkjNWsxkjMAqE4VyVmLUrOoiuSsValZRHJWHVKzVmpLcsaQaAykZgGpGVquiuSM1KzFSM4AoDpVJGctSs2iKpKzVqVmEclZNUjNWq0NyRlDojGQmgWkZuiAMpMzUrOWIzkDgGqVmZy1LDWLyk7OWpeaRSRn1SA1a7U2JGctOsvUi9Qs2LxWOm0VqRlarczkjNSsA0jOAKA6ZSZnLUzNotXnl5ectTI1i0jOykdq1mptSM4YEo2C1CyIqVkLn5iB4cpMzkjNOoDkDACqU2Zy1sLULLrwzPKSs1amZhHJWblIzTqh6ckZQ6JRkJoFpGbokDKSM1KzjiA5A4BqlZGctTQ1i8pKzlqbmkUkZ+UiNeuEpidnLTzTVI/ULCA1Q4eUkZyRmnUIyRkAVKeM5KzFqVlURnLW6tQsIjkrD6lZJzQ9OWNINMIrPzygrzxKakZqhq4pIzkjNesQkjMAqE4ZyVmLU7OojOSs1alZRHJWDlKzTmlycsaQaIR7tzyn/QdJzUjN0EX9JGdFavZ5UrOuIDkDgGr1k5y5FwOmlqZmUb/J2b79A7pva4tTs4jkrBykZp0Sk7O7G5ictfhsU427HtpFaiaRmqGT+knOitRsu15demXZy0IqK9aQnAFAVfpJznZ+U9q7rRN/Ge4nOfvyI8/pB/tbnppFK9aQnPWL1KxTYnJ2dwOTM4ZEw5CaBaRm6Kh+kjNSsw46m+QMACrTT3IWU7NzV5e9qtr1k5x1IjWLzr2S5KwfpGad1NTkjCHRMKRmAakZOmw6yVlvanZ6hatDrY44juQMAKo0neSsI6lZNN3krDOpWURy1h9Ss0669LyTZQ1MzjpwxikPqVlAaoYOm05yNpSanUVq1jkkZwBQnekkZx1KzaLpJGcxNVvdhdQsIjmbPlKzTnrtsUfoLQ1MzhgSBaRmAakZOm46ydlQavZjpGadE5OzzWtTrwQAumc6yVmHUrNoOslZTM3e0oXULIrJGc+5UzM4WAxaSc06qYnJWV9DIjObZ2ZfMLNHw/tRL8Exs+PN7HYz22pmW8zsrf08bhVIzQJSM2RgKskZqVnHxeRs01qSM7RKl/Zg6LipJGcdS82iqSZnnUvNopicbbqD5GwqdjxQXPXcoavrcEgTk7N+zzoflHSvuy+TdG/4fDR/JOkedz9X0uskbenzcUtHahaQmiEDU0nOSM0yQHKGdurMHgwdN5XkrIOpWTSV5KyTqVlEcjZ1pGad1sTkrN8h0TWSbgkf3yJpzcgbmNlxkt4h6WOS5O773X1vn49bKlKzgNQMmZhKckZqlgGSM7RTJ/ZgyMBUkrMOpmbRVJKzTqZmEcnZ1JCaZaFpyVm/Q6KT3H2XJIX3rx3lNmdK2i3p42b2TTO72cyOHusOzex9ZrbBzDbs3r27z+VNDqlZQGqGjEwmOSM1ywTJGdqp1D1Yiv0XMjKZ5KyjqVk02eSss6lZRHI2NaRmWWhacjbhmcfMvmhm3xnlbbKThFmS3ijpT9z9DZK+r7EviZa73+TuK9195YIFCyb5EP0hNQtIzZCRySRnpGYZITlDA9W5B0ux/0JGJpOcdTg1iyaTnHU6NYtIziaP1CwLTUvOJhwSufvF7n7eKG+flfSsmS2UpPB+tDPeDkk73P0b4fPbVWxYGoHULCA1Q2Ymk5yRmmWE5AwN1PU9GDIymeSsw6lZNJnkrNOpWURyNjmkZllpUnLW7zWMd0q6Pnx8vaTDfjzg7s9I2m5m54QvvVvS5j4ftzSkZgGpGTI0XnJGapYZkjO0T+v3YMjMeMlZx1OzaKLkrPOpWURyNjmkZllpUnLW79nn9yRdYmaPSrokfC4zO8XM1g273a9K+qSZPSTp9ZL+a5+PWxpSs4DUDBkaLzkjNcsQyRnapfV7MGRmvOQsg9QsGi85yyI1i0jOJkZqlpUmJWd9DYnc/QV3f7e7LwvvXwxf3+nuVwy73bdC536Bu69x9z39LrwMpGYBqRkyNV5yRmqWIZIztEjb92DI0HjJWQapWTRecpZFahaRnI2P1CxLTUnOOnwd48RIzQJSM2RstOSM1CxTJGcAUK3RkrNMUrNorOQsm9QsIjkbH6lZlpqSnGVwBhobqVlAaoaMjZackZpljOQMAKozWnKWUWoWjZacZZWaRSRnYyM1y1JTkrNsh0SkZgGpGTI3WnJGapYxkjMAqM5oyVlGqVk0WnKWVWoWkZyNjtQsa01IzrIdEpGaBaRmQE9yRmqWOZIzAKjW8OQss9QsGpmcZZeaRSRnoyM1y1oTkrOMzkK9SM0CUjOgJzkjNQPJGQBUaHhylmFqFg1PzrJMzSKSs8ORmmWtCclZlkMiUrOA1AyQ1JuckZqB5AwAKjQ8OcswNYuGJ2dZpmYRyVkvUjMofXKW5ZCI1CwgNQOGxORs2fbbSc1yR3IGANWKydm3/iq71CwanpxlmZpFJGe9SM2g9MlZhmci6YGv3KMPzP2cjnr2wdRLSetbn5SOO016+enUKwGSi8nZidqrV+adl3g1SC4mZ3f/urT9gdSrSWv7A9JX/yfHAUB5YnL2/d3SyRekXUtCMTn7wf4Bnf3aY1IvJ52YnK37TZ5r7r9RspnS0QtSrwQJxeTs9gd36KNfekwbt+2p9fFn1fpoDfCdL92q333x38jk8rtv1T9+5VTNPTLDk/L+H0gvPSXJpFuulq6/U1q0KvWqgGT2PrtNr3WTyfX6XX+jrev/mc5988Wpl4VU4uZs48eljX8uHX+6NPvIpEtK4sA+ae9TxcezjuC5AkA59r0oySS5dP8fS+dcnuW5Zc6sQy978Xv3bNX5px2vN52R4eulHntK8X79n0rrb878OXdb8fGnruM5N3Pnn/oa3f/4i/qff/eI5syaoU++98Lazg/ZDYleevTrklxmkrvr1cG5mrvgnNTLqt/z3w0fuDSwX3ryq5yEkLU9m++TS5ph0iwf0J7N90kMifK180EN/QVGLs05Sjrx7MSLSuD576o4BuK5AkB5nvyqhs6xAweyPbesf3LP0DPNgYODuv/xF/IcEj3zbfGcq2F/PxPPudDskJ8Oev3nh+yGRPPfcJX+8em/0mw/qAOapd3v/H3Nz/EvgtsfKK4gGtgvzZwjLX576hUBSZ2w/F3a//ifDp0bTlj+rtRLQkqL315cORPPkVf97zw3ajxXAKjC4rdLs+Zmf2658Mz5mjt7hg4cHNTsWTN04ZnzUy8pDZ5zCzznYph3/8hJ+rN/eCLJ+cG8wS8QtnLlSt+wYUPp97t1/Re1Z/N9OmH5u/LOSbY/UEyoF789zxMxMALnBvTgHFmo+DiY2UZ3X1n6HWPaqtp/AT04x0qSNm7bo/sff0EXnjk/z6uIIv48FDgOGKbq88NYe7Ash0QAAKAZGBI1D/svAAC6b6w9WJb/uhkAAAAAAAB6MSQCAAAAAAAAQyIAAAAAAAAwJAIAAAAAAIAYEgEAAAAAAEAMiQAAAAAAACDJ3D31GsZkZrslbavo7k+U9HxF990mHAeOQcRxKHAcChyHAsehUOVxOMPdF1R035gG9l+14DgUOA4FjkOB41DgOBQ4DoXa92CNHhJVycw2uPvK1OtIjePAMYg4DgWOQ4HjUOA4FDgOKAt/lgochwLHocBxKHAcChyHAsehkOI4kJsBAAAAAACAIREAAAAAAADyHhLdlHoBDcFx4BhEHIcCx6HAcShwHAocB5SFP0sFjkOB41DgOBQ4DgWOQ4HjUKj9OGT7mkQAAAAAAAA4JOcriQAAAAAAABAwJAIAAAAAAEB+QyIzu8zMHjGzx8zsg6nXk4KZ/ZmZPWdm30m9lpTMbJGZfcnMtpjZJjP7tdRrSsHMjjCzB8zs2+E4fCj1mlIxs5lm9k0zuyv1WlIysyfN7GEz+5aZbUi9nhTM7Hgzu93MtoZzxFtTr6luZnZO+DMQ3142sw+kXhfaiz0Ye7CIPViBPdgh7MHYf0XswdLvwbJ6TSIzmynpu5IukbRD0npJ73H3zUkXVjMze4ekVyX9hbufl3o9qZjZQkkL3f1BMztW0kZJazL882CSjnb3V81stqS/l/Rr7n5/4qXVzsx+XdJKSce5+5Wp15OKmT0paaW7P596LamY2S2SvuruN5vZHElHufvexMtKJjx/Pi3pLe6+LfV60D7swQrswQrswQrswQ5hD8b+K2IP1ivFHiy3K4lWSXrM3R939/2SbpV0TeI11c7dvyLpxdTrSM3dd7n7g+HjVyRtkXRq2lXVzwuvhk9nh7d8pseBmZ0mabWkm1OvBWmZ2XGS3iHpY5Lk7vtz3pwE75b0PQZE6AN7MLEHi9iDFdiDFdiDIWIPNqra92C5DYlOlbR92Oc7lOETEg5nZoslvUHSNxIvJYlwie+3JD0n6QvunuNx+Iik35I0mHgdTeCS/s7MNprZ+1IvJoEzJe2W9PFw6fvNZnZ06kUldp2kT6VeBFqNPRhGxR6MPZjYg0W5778k9mCjqX0PltuQyEb5WnbTevQys2MkfVrSB9z95dTrScHdB9z99ZJOk7TKzLK6BN7MrpT0nLtvTL2Whnibu79R0uWSfiXkETmZJemNkv7E3d8g6fuSsnz9FEkKl3pfLelvUq8FrcYeDIdhD8YejD1Yj9z3XxJ7sB6p9mC5DYl2SFo07PPTJO1MtBY0QOi/Py3pk+7+mdTrSS1czvllSZelXUnt3ibp6tCC3yrpXWb2ibRLSsfdd4b3z0m6Q0UmkpMdknYM+2nu7So2LLm6XNKD7v5s6oWg1diDoQd7sF7swdiDsf+SxB5spCR7sNyGROslLTOzJWEqd52kOxOvCYmEFwv8mKQt7v6HqdeTipktMLPjw8dHSrpY0taki6qZu/9bdz/N3RerOC/c5+4/m3hZSZjZ0eFFRBUu7/1xSVn9Kzzu/oyk7WZ2TvjSuyVl9WKqI7xHpGboH3swDGEPVmAPxh4sYv9VYA92mCR7sFl1P2BK7n7QzN4v6fOSZkr6M3fflHhZtTOzT0m6SNKJZrZD0n9y94+lXVUSb5P0c5IeDi24JP07d1+XbklJLJR0S3jl/BmSbnP3bP/5UegkSXcU+3fNkvRX7n5P2iUl8auSPhn+Mvu4pH+ReD1JmNlRKv41ql9KvRa0G3uwAnuwIezBCuzBELH/OoQ9mNLuwcydHBwAAAAAACB3ueVmAAAAAAAAGAVDIgAAAAAAADAkAgAAAAAAAEMiAAAAAAAAiCERAAAAAAAAxJAIAAAAAAAAYkgEAAAAAAAASf8/uBICd97O7i8AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 1440x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, (left, right) = plt.subplots(1, 2, figsize = (20, 4))\n",
    "\n",
    "left.plot(np.real(syms), \".-\")\n",
    "left.plot(np.imag(syms), \".-\")\n",
    "left.set_title(\"Access Code\")\n",
    "\n",
    "right.plot(np.real(fir_syms), \".-\")\n",
    "right.plot(np.imag(fir_syms), \".-\")\n",
    "right.set_title(\"FIR Filter\")\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "8163c2e0-0652-43c5-ad32-eaf0e94a638e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, (left, right) = plt.subplots(1, 2, figsize = (20, 4))\n",
    "\n",
    "left.plot(np.real(syms), np.imag(syms))\n",
    "left.set_title(\"AC Constellation Diagram\")\n",
    "\n",
    "xc = np.convolve(fir_syms, syms)\n",
    "right.plot(np.abs(xc))\n",
    "right.set_title(\"AC Autocorrelation\")\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc633da5-61b7-4569-adaf-3d019e0f1b17",
   "metadata": {},
   "source": [
    "## Symbols for 16-QAM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b56d782d-fcea-4fb9-b0c1-9c3933d5ce6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def modulate_16qam(m):\n",
    "    sym = {\n",
    "         0:  1 -1j,\n",
    "         1: -1 -1j,\n",
    "         2:  3 -3j,\n",
    "         3: -3 -3j,\n",
    "         4: -3 -1j,\n",
    "         5:  3 -1j,\n",
    "         6: -1 -3j,\n",
    "         7:  1 -3j,\n",
    "         8: -3 +3j,\n",
    "         9:  3 +3j,\n",
    "        10: -1 +1j,\n",
    "        11:  1 +1j,\n",
    "        12:  1 +3j,\n",
    "        13: -1 +3j,\n",
    "        14:  3 +1j,\n",
    "        15: -3 +1j,\n",
    "       \n",
    "    }\n",
    "    return map(lambda k: sym[k]*np.sqrt(0.1), m)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2fb687aa-0061-4626-bf6b-3ec7d628d739",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 10, 3, 4]\n",
      "[(-0.31622776601683794-0.31622776601683794j), (-0.31622776601683794+0.31622776601683794j), (-0.9486832980505138-0.9486832980505138j), (-0.9486832980505138-0.31622776601683794j)]\n"
     ]
    }
   ],
   "source": [
    "# convert into chunks of 4 bits for QPSK\n",
    "chunks = list(np.matmul(np.array(ac_pad).reshape((-1,4)), np.array([4, 3, 2, 1])))\n",
    "syms = list(modulate_16qam(chunks))\n",
    "\n",
    "print(chunks)\n",
    "print(syms)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5951be43",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}