AcraNetwork 1.2.4__tar.gz → 1.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter7/Golay.py +63 -12
  2. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter7/__init__.py +1 -0
  3. acranetwork-1.2.6/AcraNetwork/IRIG106/Chapter7/golay_c.c +208 -0
  4. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/__version__.py +3 -1
  5. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork.egg-info/PKG-INFO +1 -1
  6. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork.egg-info/SOURCES.txt +1 -0
  7. {acranetwork-1.2.4 → acranetwork-1.2.6}/PKG-INFO +1 -1
  8. acranetwork-1.2.6/setup.py +16 -0
  9. acranetwork-1.2.6/test/test_golay.py +321 -0
  10. acranetwork-1.2.4/setup.py +0 -3
  11. acranetwork-1.2.4/test/test_golay.py +0 -102
  12. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IENA.py +0 -0
  13. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter10/Chapter10UDP.py +0 -0
  14. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter10/FileParser.py +0 -0
  15. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter10/__init__.py +0 -0
  16. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/ARINC429.py +0 -0
  17. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/Analog.py +0 -0
  18. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/CAN.py +0 -0
  19. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/ComputerData.py +0 -0
  20. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/MILSTD1553.py +0 -0
  21. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/PCM.py +0 -0
  22. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/TimeDataFormat.py +0 -0
  23. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/UART.py +0 -0
  24. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/Video.py +0 -0
  25. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/Chapter11/__init__.py +0 -0
  26. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/IRIG106/__init__.py +0 -0
  27. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/MPEG/ADTS.py +0 -0
  28. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/MPEG/H264.py +0 -0
  29. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/MPEG/PES.py +0 -0
  30. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/MPEG/PMT.py +0 -0
  31. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/MPEG/STANAG4609.py +0 -0
  32. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/MPEG/__init__.py +0 -0
  33. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/MPEGTS.py +0 -0
  34. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/McastSocket.py +0 -0
  35. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/NPD.py +0 -0
  36. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/ParserAligned.py +0 -0
  37. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/Pcap.py +0 -0
  38. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/SamDec008.py +0 -0
  39. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/SimpleEthernet.py +0 -0
  40. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/__init__.py +0 -0
  41. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/iNET.py +0 -0
  42. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/iNetX.py +0 -0
  43. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/nanotime.py +0 -0
  44. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork/ptptime.py +0 -0
  45. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork.egg-info/dependency_links.txt +0 -0
  46. {acranetwork-1.2.4 → acranetwork-1.2.6}/AcraNetwork.egg-info/top_level.txt +0 -0
  47. {acranetwork-1.2.4 → acranetwork-1.2.6}/LICENSE +0 -0
  48. {acranetwork-1.2.4 → acranetwork-1.2.6}/MANIFEST.in +0 -0
  49. {acranetwork-1.2.4 → acranetwork-1.2.6}/README.md +0 -0
  50. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/adau_to_ch10.py +0 -0
  51. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/ch10_recorder.py +0 -0
  52. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/ch10_to_pcap.py +0 -0
  53. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/pkg_gen.ini +0 -0
  54. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/tx_iena_udp.py +0 -0
  55. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/tx_inetx_udp.py +0 -0
  56. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/validate_ch10.py +0 -0
  57. {acranetwork-1.2.4 → acranetwork-1.2.6}/examples/validate_pcap.py +0 -0
  58. {acranetwork-1.2.4 → acranetwork-1.2.6}/setup.cfg +0 -0
  59. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/__init__.py +0 -0
  60. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_afdx.py +0 -0
  61. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_ch10.py +0 -0
  62. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_ch7.py +0 -0
  63. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_iena.py +0 -0
  64. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_inet.py +0 -0
  65. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_inetx.py +0 -0
  66. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_misc.py +0 -0
  67. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_mpegts.py +0 -0
  68. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_npd.py +0 -0
  69. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_paligned.py +0 -0
  70. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_pcap.py +0 -0
  71. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_ptptime.py +0 -0
  72. {acranetwork-1.2.4 → acranetwork-1.2.6}/test/test_simpleethernet.py +0 -0
@@ -17,24 +17,73 @@ __status__ = "Production"
17
17
  # This is a direct porting of the C code from the IRIG106 starndard.
18
18
  import struct
19
19
  from functools import lru_cache
20
+ import warnings
20
21
 
22
+ try:
23
+ from . import golay_c as _golay_native
21
24
 
22
- GOLAY_SIZE = 0x1000
25
+ _use_c_extension = True
26
+ except ImportError:
27
+ warnings.warn("C extension for Golay not found. Falling back to pure Python.", RuntimeWarning)
28
+ _use_c_extension = False
23
29
 
24
- G_P = [0xC75, 0x63B, 0xF68, 0x7B4, 0x3DA, 0xD99, 0x6CD, 0x367, 0xDC6, 0xA97, 0x93E, 0x8EB]
25
30
 
31
+ GOLAY_SIZE = 0x1000
32
+ G_P = [0xC75, 0x63B, 0xF68, 0x7B4, 0x3DA, 0xD99, 0x6CD, 0x367, 0xDC6, 0xA97, 0x93E, 0x8EB]
26
33
  H_P = [0xA4F, 0xF68, 0x7B4, 0x3DA, 0x1ED, 0xAB9, 0xF13, 0xDC6, 0x6E3, 0x93E, 0x49F, 0xC75]
27
34
 
28
35
 
29
- class Golay:
36
+ class Singleton(type):
37
+ _instances = {}
38
+
39
+ def __call__(cls, *args, **kwargs):
40
+ if cls not in cls._instances:
41
+ cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
42
+ return cls._instances[cls]
43
+
44
+
45
+ class Golay(object):
46
+ __metaclass__ = Singleton
30
47
  """
31
48
  Encode and Decode Golay numbers
32
49
  """
33
50
 
34
51
  def __init__(self):
35
- self.SyndromeTable = [0] * GOLAY_SIZE
36
- self.CorrectTable = [0] * GOLAY_SIZE
37
- self.ErrorTable = [0] * GOLAY_SIZE
52
+ if _use_c_extension:
53
+ _golay_native.golay_init_tables()
54
+ else:
55
+ self.SyndromeTable = [0] * GOLAY_SIZE
56
+ self.CorrectTable = [0] * GOLAY_SIZE
57
+ self.ErrorTable = [0] * GOLAY_SIZE
58
+ self._initgolaydecode()
59
+
60
+ def encode(self, raw, as_string=False):
61
+ if not (0 <= raw <= 0xFFF):
62
+ raise ValueError("Only 12-bit unsigned values allowed")
63
+
64
+ if _use_c_extension:
65
+ encoded = _golay_native.golay_encode(raw)
66
+ else:
67
+ encoded = self._encode_python(raw)
68
+
69
+ if as_string:
70
+ return struct.pack(">BH", encoded >> 16, encoded & 0xFFFF)
71
+ return encoded
72
+
73
+ def decode(self, encoded):
74
+ if _use_c_extension:
75
+ return _golay_native.golay_decode(encoded)
76
+ else:
77
+ if isinstance(encoded, bytes):
78
+ if len(encoded) != 3:
79
+ raise ValueError("3-byte input required")
80
+ (b, w) = struct.unpack(">BH", encoded)
81
+ v = w + (b << 16)
82
+ elif not (0 <= encoded <= 0xFFFFFF):
83
+ raise ValueError("Only 24-bit unsigned values supported")
84
+ else:
85
+ v = encoded
86
+ return self._decode_python(v)
38
87
 
39
88
  @staticmethod
40
89
  @lru_cache()
@@ -48,8 +97,7 @@ class Golay:
48
97
 
49
98
  return EncodeTable
50
99
 
51
- @lru_cache(maxsize=20)
52
- def encode(self, raw, as_string=False):
100
+ def _encode_python(self, raw, as_string=False):
53
101
  """
54
102
  Encode the value as a 24b code
55
103
 
@@ -66,8 +114,7 @@ class Golay:
66
114
  else:
67
115
  return encoded
68
116
 
69
- @lru_cache(maxsize=20)
70
- def decode(self, encoded):
117
+ def _decode_python(self, encoded):
71
118
  """
72
119
  Decode a 24b number as a golay
73
120
 
@@ -85,7 +132,6 @@ class Golay:
85
132
  else:
86
133
  v = encoded
87
134
 
88
- self._initgolaydecode()
89
135
  return self._decode2(((v) >> 12) & 0xFFF, (v) & 0xFFF)
90
136
 
91
137
  def _syndrome2(self, v1, v2):
@@ -103,6 +149,12 @@ class Golay:
103
149
  def _errors(self, v):
104
150
  return self._errors2(((v) >> 12) & 0xFFF, (v) & 0xFFF)
105
151
 
152
+ def errors(self, v):
153
+ if _use_c_extension:
154
+ return _golay_native.golay_errors(v)
155
+ else:
156
+ return self._errors(v)
157
+
106
158
  @staticmethod
107
159
  def _onesincode(code, size):
108
160
  """Optimised version of the code below. Runs 2x"""
@@ -118,7 +170,6 @@ class Golay:
118
170
 
119
171
  return ret
120
172
 
121
- @lru_cache()
122
173
  def _initgolaydecode(self):
123
174
  for x in range(GOLAY_SIZE):
124
175
  self.SyndromeTable[x] = 0
@@ -17,6 +17,7 @@ __email__ = "dcollins@curtisswright.com"
17
17
  __status__ = "Production"
18
18
 
19
19
  import struct
20
+
20
21
  from AcraNetwork.IRIG106.Chapter7 import Golay
21
22
  import math
22
23
  import logging
@@ -0,0 +1,208 @@
1
+ #include <Python.h>
2
+ #include <stdint.h>
3
+
4
+ #define GOLAY_SIZE 0x1000
5
+
6
+ // Generator matrix: parity sub-generator matrix P
7
+ static const uint16_t G_P[12] = {
8
+ 0x0C75, 0x063B, 0x0F68, 0x07B4,
9
+ 0x03DA, 0x0D99, 0x06CD, 0x0367,
10
+ 0x0DC6, 0x0A97, 0x093E, 0x08EB};
11
+
12
+ // Parity-check matrix H_P
13
+ static const uint16_t H_P[12] = {
14
+ 0x0A4F, 0x0F68, 0x07B4, 0x03DA,
15
+ 0x01ED, 0x0AB9, 0x0F13, 0x0DC6,
16
+ 0x06E3, 0x093E, 0x049F, 0x0C75};
17
+
18
+ // Lookup tables
19
+ static uint32_t EncodeTable[GOLAY_SIZE];
20
+ static uint16_t SyndromeTable[GOLAY_SIZE];
21
+ static uint32_t CorrectTable[GOLAY_SIZE];
22
+ static uint8_t ErrorTable[GOLAY_SIZE];
23
+
24
+ // Function to count the number of ones in a code
25
+ static int ones_in_code(uint32_t code, int size)
26
+ {
27
+ int count = 0;
28
+ for (int i = 0; i < size; i++)
29
+ {
30
+ if ((code >> i) & 1)
31
+ {
32
+ count++;
33
+ }
34
+ }
35
+ return count;
36
+ }
37
+
38
+ // Initialize the Golay encoding lookup table
39
+ static void InitGolayEncode(void)
40
+ {
41
+ for (uint32_t x = 0; x < GOLAY_SIZE; x++)
42
+ {
43
+ uint32_t code = x << 12;
44
+ for (int i = 0; i < 12; i++)
45
+ {
46
+ if ((x >> (11 - i)) & 1)
47
+ {
48
+ code ^= G_P[i];
49
+ }
50
+ }
51
+ EncodeTable[x] = code;
52
+ }
53
+ }
54
+
55
+ // Initialize the Golay decoding lookup tables
56
+ static void InitGolayDecode(void)
57
+ {
58
+ for (uint32_t x = 0; x < GOLAY_SIZE; x++)
59
+ {
60
+ SyndromeTable[x] = 0;
61
+
62
+ for (int i = 0; i < 12; i++)
63
+ {
64
+ if ((x >> (11 - i)) & 1)
65
+ {
66
+ SyndromeTable[x] ^= H_P[i];
67
+ ErrorTable[x] = 4;
68
+ CorrectTable[x] = 0x0FFF;
69
+ }
70
+ }
71
+ }
72
+
73
+ ErrorTable[0] = 0;
74
+ CorrectTable[0] = 0;
75
+
76
+ for (int i = 0; i < 24; i++)
77
+ {
78
+ for (int j = 0; j < 24; j++)
79
+ {
80
+ for (int k = 0; k < 24; k++)
81
+ {
82
+ uint32_t error = (1 << i) | (1 << j) | (1 << k);
83
+ uint16_t syndrome = SyndromeTable[(error >> 12) & 0x0FFF] ^ (error & 0x0FFF);
84
+ CorrectTable[syndrome] = (error >> 12) & 0x0FFF;
85
+ ErrorTable[syndrome] = ones_in_code(error, 24);
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ // Python wrapper for golay_init_tables
92
+ static PyObject *py_golay_init_tables(PyObject *self, PyObject *args)
93
+ {
94
+ InitGolayEncode();
95
+ InitGolayDecode();
96
+ Py_RETURN_NONE;
97
+ }
98
+
99
+ // Python wrapper for golay_encode
100
+ static PyObject *py_golay_encode(PyObject *self, PyObject *args)
101
+ {
102
+ uint16_t raw;
103
+ if (!PyArg_ParseTuple(args, "H", &raw))
104
+ {
105
+ return NULL;
106
+ }
107
+ if (raw > 0x0FFF)
108
+ {
109
+ PyErr_SetString(PyExc_ValueError, "Input must be a 12-bit unsigned integer.");
110
+ return NULL;
111
+ }
112
+ uint32_t encoded = EncodeTable[raw & 0x0FFF];
113
+ return PyLong_FromUnsignedLong(encoded);
114
+ }
115
+
116
+ // Python wrapper for golay_decode
117
+ static PyObject *py_golay_decode(PyObject *self, PyObject *args)
118
+ {
119
+ PyObject *input;
120
+ if (!PyArg_ParseTuple(args, "O", &input))
121
+ {
122
+ return NULL;
123
+ }
124
+
125
+ uint32_t encoded;
126
+
127
+ // Handle bytes input (should be 3 bytes)
128
+ if (PyBytes_Check(input))
129
+ {
130
+ if (PyBytes_Size(input) != 3)
131
+ {
132
+ PyErr_SetString(PyExc_ValueError, "3-byte input required");
133
+ return NULL;
134
+ }
135
+ const unsigned char *buf = (const unsigned char *)PyBytes_AsString(input);
136
+ // Convert big-endian bytes to 24-bit unsigned integer
137
+ encoded = ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2];
138
+ }
139
+ // Handle integer input
140
+ else if (PyLong_Check(input))
141
+ {
142
+ encoded = PyLong_AsUnsignedLong(input);
143
+ if (PyErr_Occurred())
144
+ {
145
+ return NULL; // Overflow or invalid conversion
146
+ }
147
+ if (encoded > 0xFFFFFF)
148
+ {
149
+ PyErr_SetString(PyExc_ValueError, "Input must be a 24-bit unsigned integer.");
150
+ return NULL;
151
+ }
152
+ }
153
+ else
154
+ {
155
+ PyErr_SetString(PyExc_TypeError, "Expected a 3-byte bytes object or 24-bit integer.");
156
+ return NULL;
157
+ }
158
+
159
+ // Decode logic
160
+ uint16_t v1 = (encoded >> 12) & 0x0FFF;
161
+ uint16_t v2 = encoded & 0x0FFF;
162
+ uint16_t syndrome = SyndromeTable[v2] ^ v1;
163
+ uint16_t corrected = v1 ^ CorrectTable[syndrome];
164
+
165
+ return PyLong_FromUnsignedLong(corrected);
166
+ }
167
+
168
+ static PyObject *py_golay_errors(PyObject *self, PyObject *args)
169
+ {
170
+ uint32_t v;
171
+ if (!PyArg_ParseTuple(args, "I", &v))
172
+ {
173
+ return NULL;
174
+ }
175
+ if (v > 0xFFFFFF)
176
+ {
177
+ PyErr_SetString(PyExc_ValueError, "Input must be a 24-bit unsigned integer.");
178
+ return NULL;
179
+ }
180
+
181
+ uint16_t v1 = (v >> 12) & 0x0FFF;
182
+ uint16_t v2 = v & 0x0FFF;
183
+ uint16_t syndrome = SyndromeTable[v2] ^ v1;
184
+ uint8_t errors = ErrorTable[syndrome];
185
+ return PyLong_FromUnsignedLong(errors);
186
+ }
187
+
188
+ // Module method definitions
189
+ static PyMethodDef GolayMethods[] = {
190
+ {"golay_init_tables", py_golay_init_tables, METH_NOARGS, "Initialize Golay encoding and decoding tables."},
191
+ {"golay_encode", py_golay_encode, METH_VARARGS, "Encode a 12-bit value using Golay code."},
192
+ {"golay_decode", py_golay_decode, METH_VARARGS, "Decode a 24-bit Golay codeword."},
193
+ {"golay_errors", py_golay_errors, METH_VARARGS, "Get the number of bit errors in a 24-bit Golay codeword."},
194
+ {NULL, NULL, 0, NULL}};
195
+
196
+ // Module definition
197
+ static struct PyModuleDef golay_c_module = {
198
+ PyModuleDef_HEAD_INIT,
199
+ "golay_c",
200
+ "C extension module for Golay encoding and decoding.",
201
+ -1,
202
+ GolayMethods};
203
+
204
+ // Module initialization function
205
+ PyMODINIT_FUNC PyInit_golay_c(void)
206
+ {
207
+ return PyModule_Create(&golay_c_module);
208
+ }
@@ -109,4 +109,6 @@
109
109
  # 1.2.2 - Fixed chapter 7 packet generation
110
110
  # 1.2.3 - Last release was nto successful
111
111
  # 1.2.4 - Removed exit in the ch7
112
- __version__ = "1.2.4"
112
+ # 1.2.5 - Added C implementation of Golay. Also improved the existing python impl
113
+ # 1.2.6 - Further optimisation of the C Golay implementation
114
+ __version__ = "1.2.6"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AcraNetwork
3
- Version: 1.2.4
3
+ Version: 1.2.6
4
4
  Summary: Classes and utilities to support Flight Test Instrumentation Ethernet networks
5
5
  Home-page: https://github.com/diarmuidcwc/AcraNetwork
6
6
  Author: Diarmuid Collins
@@ -37,6 +37,7 @@ AcraNetwork/IRIG106/Chapter11/Video.py
37
37
  AcraNetwork/IRIG106/Chapter11/__init__.py
38
38
  AcraNetwork/IRIG106/Chapter7/Golay.py
39
39
  AcraNetwork/IRIG106/Chapter7/__init__.py
40
+ AcraNetwork/IRIG106/Chapter7/golay_c.c
40
41
  AcraNetwork/MPEG/ADTS.py
41
42
  AcraNetwork/MPEG/H264.py
42
43
  AcraNetwork/MPEG/PES.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AcraNetwork
3
- Version: 1.2.4
3
+ Version: 1.2.6
4
4
  Summary: Classes and utilities to support Flight Test Instrumentation Ethernet networks
5
5
  Home-page: https://github.com/diarmuidcwc/AcraNetwork
6
6
  Author: Diarmuid Collins
@@ -0,0 +1,16 @@
1
+ from setuptools import setup, Extension
2
+ import os
3
+
4
+ # Define the C extension
5
+ golay_extension = Extension(
6
+ "AcraNetwork.IRIG106.Chapter7.golay_c",
7
+ sources=["AcraNetwork/IRIG106/Chapter7/golay_c.c"],
8
+ include_dirs=[],
9
+ extra_compile_args=[],
10
+ language="c",
11
+ )
12
+
13
+ # Load configuration from setup.cfg
14
+ setup(
15
+ ext_modules=[golay_extension],
16
+ )
@@ -0,0 +1,321 @@
1
+ import unittest
2
+ import AcraNetwork.IRIG106.Chapter7.Golay as Golay
3
+ from pstats import Stats
4
+ import cProfile
5
+ import random
6
+ import logging
7
+ import timeit
8
+
9
+ logging.basicConfig(level=logging.DEBUG)
10
+
11
+
12
+ vectors = [
13
+ (137, 562935),
14
+ (2513, 10296846),
15
+ (1614, 6613669),
16
+ (3049, 12491018),
17
+ (3151, 12906835),
18
+ (2962, 12135722),
19
+ (3708, 15190596),
20
+ (1833, 7511303),
21
+ (1498, 6137939),
22
+ (735, 3011784),
23
+ (730, 2991796),
24
+ (3951, 16187202),
25
+ (3638, 14902053),
26
+ (1344, 5508118),
27
+ (2098, 8593633),
28
+ (1865, 7640659),
29
+ (997, 4084270),
30
+ (1064, 4361520),
31
+ (2877, 11787961),
32
+ (2249, 9213723),
33
+ (1380, 5652556),
34
+ (1452, 5948361),
35
+ (2425, 9934559),
36
+ (545, 2232654),
37
+ (3946, 16166206),
38
+ (412, 1687640),
39
+ (461, 1889869),
40
+ (2184, 8946281),
41
+ (788, 3227948),
42
+ (3083, 12629597),
43
+ (2032, 8324366),
44
+ (1647, 6747267),
45
+ (3374, 13821272),
46
+ (3837, 15716725),
47
+ (423, 1735137),
48
+ (509, 2085863),
49
+ (2274, 9317829),
50
+ (1078, 4415544),
51
+ (3642, 14918772),
52
+ (1872, 7667737),
53
+ (2791, 11432145),
54
+ (3293, 13490384),
55
+ (1724, 7063666),
56
+ (1678, 6874342),
57
+ (184, 756662),
58
+ (696, 2852062),
59
+ (4070, 16673205),
60
+ (1843, 7551640),
61
+ (3993, 16357122),
62
+ (3192, 13078459),
63
+ (1468, 6013102),
64
+ (919, 3765027),
65
+ (2946, 12070477),
66
+ (1280, 5243279),
67
+ (1220, 4997871),
68
+ (774, 3173237),
69
+ (1084, 4441280),
70
+ (2609, 10690140),
71
+ (459, 1881572),
72
+ (2261, 9261869),
73
+ (3301, 13521084),
74
+ (159, 652857),
75
+ (391, 1605420),
76
+ (2074, 8498154),
77
+ (1927, 7894655),
78
+ (2079, 8518038),
79
+ (470, 1927481),
80
+ (2780, 11389288),
81
+ (1507, 6174932),
82
+ (3026, 12394675),
83
+ (1354, 5548270),
84
+ (338, 1384564),
85
+ (2239, 9174145),
86
+ (3098, 12692945),
87
+ (2216, 9077924),
88
+ (310, 1270199),
89
+ (2393, 9801746),
90
+ (597, 2446314),
91
+ (2208, 9046370),
92
+ (2443, 10007560),
93
+ (2704, 11076512),
94
+ (1162, 4759833),
95
+ (2032, 8324366),
96
+ (2023, 8289579),
97
+ (3925, 16080400),
98
+ (2922, 11971333),
99
+ (3804, 15585107),
100
+ (3219, 13187878),
101
+ (3018, 12365330),
102
+ (4006, 16409644),
103
+ (3230, 13231260),
104
+ (1846, 7563492),
105
+ (1107, 4536592),
106
+ (3734, 15296050),
107
+ (851, 3487735),
108
+ (420, 1722420),
109
+ (2863, 11728096),
110
+ (2480, 10161585),
111
+ (3151, 12906835),
112
+ (2070, 8481979),
113
+ (2998, 12280176),
114
+ (1761, 7215414),
115
+ (2206, 9036455),
116
+ (4025, 16486863),
117
+ (1393, 5706071),
118
+ (1643, 6733332),
119
+ (3568, 14616083),
120
+ (524, 2148409),
121
+ (308, 1263753),
122
+ (3881, 15896946),
123
+ (2813, 11523918),
124
+ (141, 580704),
125
+ (1513, 6200364),
126
+ (2528, 10355535),
127
+ (2814, 11527835),
128
+ (3189, 13062145),
129
+ (1648, 6750560),
130
+ (4039, 16545683),
131
+ (1475, 6045209),
132
+ (813, 3330475),
133
+ (2210, 9052252),
134
+ (2682, 10989526),
135
+ (2011, 8241104),
136
+ (886, 3629894),
137
+ (626, 2567781),
138
+ (1522, 6234968),
139
+ (4020, 16469621),
140
+ (166, 681662),
141
+ (2145, 8789962),
142
+ (1855, 7601609),
143
+ (3758, 15396446),
144
+ (2886, 11823769),
145
+ (258, 1060490),
146
+ (1049, 4296817),
147
+ (343, 1405448),
148
+ (2479, 10156114),
149
+ (523, 2143099),
150
+ (944, 3870380),
151
+ (2698, 11052095),
152
+ (935, 3831433),
153
+ (4019, 16463159),
154
+ (2339, 9583833),
155
+ (3916, 16042074),
156
+ (509, 2085863),
157
+ (1693, 6936148),
158
+ (388, 1593081),
159
+ (2773, 11361349),
160
+ (1936, 7933530),
161
+ (1759, 7205619),
162
+ (2816, 11535529),
163
+ (1141, 4676724),
164
+ (2264, 9276567),
165
+ (3630, 14871940),
166
+ (2891, 11842851),
167
+ (475, 1947267),
168
+ (2224, 9112069),
169
+ (371, 1523282),
170
+ (1942, 7958003),
171
+ (894, 3665536),
172
+ (92, 379311),
173
+ (477, 1955114),
174
+ (120, 493045),
175
+ (1959, 8024242),
176
+ (1483, 6075359),
177
+ (766, 3140334),
178
+ (1043, 4273289),
179
+ (2056, 8421811),
180
+ (3520, 14418873),
181
+ (1773, 7265895),
182
+ (2736, 11208045),
183
+ (2854, 11690445),
184
+ (1115, 4568278),
185
+ (4052, 16598305),
186
+ (993, 4069561),
187
+ (1472, 6033356),
188
+ (3170, 12986404),
189
+ (3997, 16375189),
190
+ (3554, 14560330),
191
+ (2667, 10925146),
192
+ (833, 3415470),
193
+ (1862, 7626967),
194
+ (206, 843820),
195
+ (2687, 11009450),
196
+ (2781, 11391363),
197
+ (2535, 10385421),
198
+ (366, 1499791),
199
+ (2783, 11401405),
200
+ (2990, 12251089),
201
+ (276, 1134148),
202
+ (1748, 7163616),
203
+ (760, 3115335),
204
+ (1261, 5165327),
205
+ (2148, 8801718),
206
+ (2842, 11641654),
207
+ (3912, 16024269),
208
+ (1626, 6660949),
209
+ (2385, 9772500),
210
+ (704, 2883883),
211
+ (2593, 10624315),
212
+ (1178, 4825726),
213
+ ]
214
+
215
+
216
+ class GolayTestCase(unittest.TestCase):
217
+
218
+ def test_encode(self):
219
+ g = Golay.Golay()
220
+ for attempt in range(200):
221
+ input = random.randint(0, 0xFFF)
222
+ # print("{:0X}".format(g2.decode(g.encode(raw))))
223
+ self.assertEqual(input, g.decode(g.encode(input)))
224
+ # print(f"({input}, {g.encode(input)}),", end="")
225
+
226
+ def test_encode_vectors(self):
227
+ g = Golay.Golay()
228
+ for input, output in vectors:
229
+ self.assertEqual(output, g.encode(input))
230
+
231
+ def test_encode_string(self):
232
+ g = Golay.Golay()
233
+ v = 0x101
234
+ s = g.encode(v, as_string=True)
235
+ self.assertEqual(3, len(s))
236
+ dec = g.decode(s)
237
+ self.assertEqual(v, dec)
238
+
239
+ def test_decode(self):
240
+ g = Golay.Golay()
241
+ v = 0x1007B408A722
242
+ # print(repr(g.decode(v)))
243
+
244
+ @unittest.skip("Not working in c")
245
+ def test_with_error(self):
246
+ g = Golay.Golay()
247
+ for attempt in range(6):
248
+ for error_bits in range(0, 7):
249
+ logging.debug("----{}----".format(error_bits))
250
+ input = random.randint(0, 0xFFF)
251
+ encoded = g.encode(input)
252
+ logging.debug("Raw={:#0X} Encoded={:#0X}".format(input, encoded))
253
+ # Introduce errors
254
+ bits_to_flip = random.sample(range(16), error_bits)
255
+ for b in bits_to_flip:
256
+ encoded ^= 1 << b
257
+ logging.debug("Errorbits={} {:#0X}".format(bits_to_flip, encoded))
258
+ decoded = g.decode(encoded)
259
+ logging.debug("Decoded={:#X} Errors={}".format(g.decode(encoded), g.errors(encoded)))
260
+ if error_bits < 4:
261
+ self.assertEqual(input, decoded)
262
+ else:
263
+ self.assertNotEqual(input, decoded)
264
+
265
+
266
+ class GolayProfile(unittest.TestCase):
267
+
268
+ def setUp(self):
269
+ self.pr = cProfile.Profile()
270
+ self.pr.enable()
271
+
272
+ def tearDown(self):
273
+ p = Stats(self.pr)
274
+ p.sort_stats("cumtime")
275
+ # p.print_stats()
276
+
277
+ def test_profile(self):
278
+ g = Golay.Golay()
279
+ g2 = Golay.Golay()
280
+ for val in range(100, 2000):
281
+ # val = 100
282
+
283
+ # print("{:0X}".format(g2.decode(g.encode(raw))))
284
+ self.assertEqual(val, g2.decode(g.encode(val)))
285
+ # Original implementation
286
+ # ncalls tottime percall cumtime percall filename:lineno(function)
287
+ # 1 0.002 0.002 1.063 1.063 C:\ACRA\WORK\AXN_ENC_402\TICAD021\TICAD021\testbench\AcraNetwork\test\test_golay.py:69(test_profile)
288
+ # 20 0.000 0.000 0.847 0.042 ..\AcraNetwork\Golay.py:70(decode)
289
+ # 20 0.511 0.026 0.847 0.042 ..\AcraNetwork\Golay.py:121(_initgolaydecode)
290
+ # 20 0.000 0.000 0.213 0.011 ..\AcraNetwork\Golay.py:53(encode)
291
+ # 20 0.213 0.011 0.213 0.011 ..\AcraNetwork\Golay.py:42(_init_Table)
292
+ # 276480 0.111 0.000 0.194 0.000 ..\AcraNetwork\Golay.py:106(_onesincode)
293
+ # 276480 0.097 0.000 0.142 0.000 ..\AcraNetwork\Golay.py:94(_syndrome)
294
+ # 276480 0.046 0.000 0.046 0.000 {method 'count' of 'str' objects}
295
+ # 276500 0.045 0.000 0.045 0.000 ..\AcraNetwork\Golay.py:91(_syndrome2)
296
+ # 276480 0.037 0.000 0.037 0.000 {built-in method builtins.bin}
297
+ # 40 0.001 0.000 0.001 0.000 ..\AcraNetwork\Golay.py:37(__init__)
298
+
299
+ def test_bits(self):
300
+ error = 0x3
301
+ size = 24
302
+ for code in [0x0, 0x1, 0x37, 0xFFFFFF]:
303
+ self.assertEqual(Golay.Golay._onesincode_old(code, size), Golay.Golay._onesincode(code, size))
304
+
305
+ # print timeit.timeit('import AcraNetwork.Golay as Golay; Golay.Golay._onesincode(0x2, 24)', number=10000)
306
+ # print timeit.timeit('import AcraNetwork.Golay as Golay; Golay.Golay._onesincode2(0x2, 24)', number=10000)
307
+
308
+ @unittest.skip("Don't include profiling")
309
+ def test_timeit(self):
310
+ print("timed=")
311
+ print(
312
+ timeit.timeit(
313
+ "g.decode(g.encode(100))",
314
+ setup="import AcraNetwork.IRIG106.Chapter7.Golay as Golay; g=Golay.Golay()",
315
+ number=100000,
316
+ )
317
+ )
318
+
319
+
320
+ if __name__ == "__main__":
321
+ unittest.main()
@@ -1,3 +0,0 @@
1
- from setuptools import setup
2
-
3
- setup()
@@ -1,102 +0,0 @@
1
- import sys
2
-
3
- sys.path.append("..")
4
- import unittest
5
- import AcraNetwork.IRIG106.Chapter7.Golay as Golay
6
- from pstats import Stats
7
- import cProfile
8
- import random
9
- import logging
10
- import timeit
11
-
12
- logging.basicConfig(level=logging.INFO)
13
-
14
-
15
- class GolayTestCase(unittest.TestCase):
16
-
17
- def test_encode(self):
18
- g = Golay.Golay()
19
- for attempt in range(20):
20
- input = random.randint(0, 0xFFF)
21
- # print("{:0X}".format(g2.decode(g.encode(raw))))
22
- self.assertEqual(input, g.decode(g.encode(input)))
23
-
24
- def test_encode_string(self):
25
- g = Golay.Golay()
26
- v = 0x101
27
- s = g.encode(v, as_string=True)
28
- self.assertEqual(3, len(s))
29
- dec = g.decode(s)
30
- self.assertEqual(v, dec)
31
-
32
- def test_decode(self):
33
- g = Golay.Golay()
34
- v = 0x1007B408A722
35
- # print(repr(g.decode(v)))
36
-
37
- def test_with_error(self):
38
- g = Golay.Golay()
39
- for attempt in range(6):
40
- for error_bits in range(0, 7):
41
- logging.debug("----{}----".format(error_bits))
42
- input = random.randint(0, 0xFFF)
43
- encoded = g.encode(input)
44
- logging.debug("Raw={:#0X} Encoded={:#0X}".format(input, encoded))
45
- # Introduce errors
46
- bits_to_flip = random.sample(range(16), error_bits)
47
- for b in bits_to_flip:
48
- encoded ^= 1 << b
49
- logging.debug("Errorbits={} {:#0X}".format(bits_to_flip, encoded))
50
- decoded = g.decode(encoded)
51
- logging.debug("Decoded={:#X} Errors={}".format(g.decode(encoded), g._errors(encoded)))
52
- if error_bits < 4:
53
- self.assertEqual(input, decoded)
54
- else:
55
- self.assertNotEqual(input, decoded)
56
-
57
-
58
- class GolayProfile(unittest.TestCase):
59
-
60
- def setUp(self):
61
- self.pr = cProfile.Profile()
62
- self.pr.enable()
63
-
64
- def tearDown(self):
65
- p = Stats(self.pr)
66
- p.sort_stats("cumtime")
67
- # p.print_stats()
68
-
69
- def test_profile(self):
70
- g = Golay.Golay()
71
- g2 = Golay.Golay()
72
- for val in range(100, 2000):
73
- # val = 100
74
-
75
- # print("{:0X}".format(g2.decode(g.encode(raw))))
76
- self.assertEqual(val, g2.decode(g.encode(val)))
77
- # Original implementation
78
- # ncalls tottime percall cumtime percall filename:lineno(function)
79
- # 1 0.002 0.002 1.063 1.063 C:\ACRA\WORK\AXN_ENC_402\TICAD021\TICAD021\testbench\AcraNetwork\test\test_golay.py:69(test_profile)
80
- # 20 0.000 0.000 0.847 0.042 ..\AcraNetwork\Golay.py:70(decode)
81
- # 20 0.511 0.026 0.847 0.042 ..\AcraNetwork\Golay.py:121(_initgolaydecode)
82
- # 20 0.000 0.000 0.213 0.011 ..\AcraNetwork\Golay.py:53(encode)
83
- # 20 0.213 0.011 0.213 0.011 ..\AcraNetwork\Golay.py:42(_init_Table)
84
- # 276480 0.111 0.000 0.194 0.000 ..\AcraNetwork\Golay.py:106(_onesincode)
85
- # 276480 0.097 0.000 0.142 0.000 ..\AcraNetwork\Golay.py:94(_syndrome)
86
- # 276480 0.046 0.000 0.046 0.000 {method 'count' of 'str' objects}
87
- # 276500 0.045 0.000 0.045 0.000 ..\AcraNetwork\Golay.py:91(_syndrome2)
88
- # 276480 0.037 0.000 0.037 0.000 {built-in method builtins.bin}
89
- # 40 0.001 0.000 0.001 0.000 ..\AcraNetwork\Golay.py:37(__init__)
90
-
91
- def test_bits(self):
92
- error = 0x3
93
- size = 24
94
- for code in [0x0, 0x1, 0x37, 0xFFFFFF]:
95
- self.assertEqual(Golay.Golay._onesincode_old(code, size), Golay.Golay._onesincode(code, size))
96
-
97
- # print timeit.timeit('import AcraNetwork.Golay as Golay; Golay.Golay._onesincode(0x2, 24)', number=10000)
98
- # print timeit.timeit('import AcraNetwork.Golay as Golay; Golay.Golay._onesincode2(0x2, 24)', number=10000)
99
-
100
-
101
- if __name__ == "__main__":
102
- unittest.main()
File without changes
File without changes
File without changes
File without changes