speedup (#59)
* remove unused functions * cythonize common * add bds05 * separate cleanly cython and python, bds05, bds06, modulo issues * bds08 * bds09 * optimisations in bds09 * "make" things easier * clean up useless stuff * add make options * fix hidden altitude() call * minor updates to C code * update tests * update benchmark * consolidation * update clean script * reduce complexity and change default type to str Co-authored-by: Xavier Olive <1360812+xoolive@users.noreply.github.com>
This commit is contained in:
130
tests/benchmark.py
Normal file
130
tests/benchmark.py
Normal file
@@ -0,0 +1,130 @@
|
||||
import sys
|
||||
import time
|
||||
import pandas as pd
|
||||
from tqdm import tqdm
|
||||
from pyModeS.decoder import adsb
|
||||
|
||||
fin = sys.argv[1]
|
||||
|
||||
df = pd.read_csv(fin, names=["ts", "df", "icao", "msg"])
|
||||
df_adsb = df[df["df"] == 17].copy()
|
||||
|
||||
total = df_adsb.shape[0]
|
||||
|
||||
|
||||
def native():
|
||||
|
||||
from pyModeS.decoder import common
|
||||
|
||||
# airborne position
|
||||
m_air_0 = None
|
||||
m_air_1 = None
|
||||
|
||||
# surface position
|
||||
m_surf_0 = None
|
||||
m_surf_1 = None
|
||||
|
||||
for i, r in tqdm(df_adsb.iterrows(), total=total):
|
||||
ts = r.ts
|
||||
m = r.msg
|
||||
|
||||
downlink_format = common.df(m)
|
||||
crc = common.crc(m)
|
||||
icao = adsb.icao(m)
|
||||
tc = adsb.typecode(m)
|
||||
|
||||
if 1 <= tc <= 4:
|
||||
category = adsb.category(m)
|
||||
callsign = adsb.callsign(m)
|
||||
if tc == 19:
|
||||
velocity = adsb.velocity(m)
|
||||
|
||||
if 5 <= tc <= 8:
|
||||
if adsb.oe_flag(m):
|
||||
m_surf_1 = m
|
||||
t1 = ts
|
||||
else:
|
||||
m_surf_0 = m
|
||||
t0 = ts
|
||||
|
||||
if m_surf_0 and m_surf_1:
|
||||
position = adsb.surface_position(
|
||||
m_surf_0, m_surf_1, t0, t1, 50.01, 4.35
|
||||
)
|
||||
altitude = adsb.altitude(m)
|
||||
|
||||
if 9 <= tc <= 18:
|
||||
if adsb.oe_flag(m):
|
||||
m_air_1 = m
|
||||
t1 = ts
|
||||
else:
|
||||
m_air_0 = m
|
||||
t0 = ts
|
||||
|
||||
if m_air_0 and m_air_1:
|
||||
position = adsb.position(m_air_0, m_air_1, t0, t1)
|
||||
altitude = adsb.altitude(m)
|
||||
|
||||
|
||||
def cython():
|
||||
|
||||
from pyModeS.decoder import c_common as common
|
||||
|
||||
# airborne position
|
||||
m_air_0 = None
|
||||
m_air_1 = None
|
||||
|
||||
# surface position
|
||||
m_surf_0 = None
|
||||
m_surf_1 = None
|
||||
|
||||
for i, r in tqdm(df_adsb.iterrows(), total=total):
|
||||
ts = r.ts
|
||||
m = r.msg
|
||||
|
||||
downlink_format = common.df(m)
|
||||
crc = common.crc(m)
|
||||
icao = adsb.icao(m)
|
||||
tc = adsb.typecode(m)
|
||||
|
||||
if 1 <= tc <= 4:
|
||||
category = adsb.category(m)
|
||||
callsign = adsb.callsign(m)
|
||||
if tc == 19:
|
||||
velocity = adsb.velocity(m)
|
||||
|
||||
if 5 <= tc <= 8:
|
||||
if adsb.oe_flag(m):
|
||||
m_surf_1 = m
|
||||
t1 = ts
|
||||
else:
|
||||
m_surf_0 = m
|
||||
t0 = ts
|
||||
|
||||
if m_surf_0 and m_surf_1:
|
||||
position = adsb.surface_position(
|
||||
m_surf_0, m_surf_1, t0, t1, 50.01, 4.35
|
||||
)
|
||||
altitude = adsb.altitude(m)
|
||||
|
||||
if 9 <= tc <= 18:
|
||||
if adsb.oe_flag(m):
|
||||
m_air_1 = m
|
||||
t1 = ts
|
||||
else:
|
||||
m_air_0 = m
|
||||
t0 = ts
|
||||
|
||||
if m_air_0 and m_air_1:
|
||||
position = adsb.position(m_air_0, m_air_1, t0, t1)
|
||||
altitude = adsb.altitude(m)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
t1 = time.time()
|
||||
native()
|
||||
dt1 = time.time() - t1
|
||||
|
||||
t2 = time.time()
|
||||
cython()
|
||||
dt2 = time.time() - t2
|
||||
@@ -1,44 +1,46 @@
|
||||
from __future__ import print_function
|
||||
from pyModeS import adsb, ehs
|
||||
import sys
|
||||
import time
|
||||
import csv
|
||||
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "cython":
|
||||
from pyModeS.c_decoder import adsb
|
||||
else:
|
||||
from pyModeS.decoder import adsb
|
||||
|
||||
print("===== Decode ADS-B sample data=====")
|
||||
|
||||
f = open("tests/data/sample_data_adsb.csv", "rt")
|
||||
|
||||
msg0 = None
|
||||
msg1 = None
|
||||
|
||||
tstart = time.time()
|
||||
for i, r in enumerate(csv.reader(f)):
|
||||
|
||||
ts = int(r[0])
|
||||
m = r[1].encode()
|
||||
|
||||
icao = adsb.icao(m)
|
||||
tc = adsb.typecode(m)
|
||||
|
||||
if 1 <= tc <= 4:
|
||||
print(ts, m, icao, tc, adsb.category(m), adsb.callsign(m))
|
||||
if tc == 19:
|
||||
print(ts, m, icao, tc, adsb.velocity(m))
|
||||
if 5 <= tc <= 18:
|
||||
if adsb.oe_flag(m):
|
||||
msg1 = m
|
||||
t1 = ts
|
||||
else:
|
||||
msg0 = m
|
||||
t0 = ts
|
||||
|
||||
if msg0 and msg1:
|
||||
pos = adsb.position(msg0, msg1, t0, t1)
|
||||
alt = adsb.altitude(m)
|
||||
print(ts, m, icao, tc, pos, alt)
|
||||
|
||||
|
||||
# === Decode sample data file ===
|
||||
dt = time.time() - tstart
|
||||
|
||||
|
||||
def adsb_decode_all(n=None):
|
||||
print("===== Decode ADS-B sample data=====")
|
||||
import csv
|
||||
|
||||
f = open("tests/data/sample_data_adsb.csv", "rt")
|
||||
|
||||
msg0 = None
|
||||
msg1 = None
|
||||
|
||||
for i, r in enumerate(csv.reader(f)):
|
||||
if n and i > n:
|
||||
break
|
||||
|
||||
ts = r[0]
|
||||
m = r[1]
|
||||
icao = adsb.icao(m)
|
||||
tc = adsb.typecode(m)
|
||||
if 1 <= tc <= 4:
|
||||
print(ts, m, icao, tc, adsb.category(m), adsb.callsign(m))
|
||||
if tc == 19:
|
||||
print(ts, m, icao, tc, adsb.velocity(m))
|
||||
if 5 <= tc <= 18:
|
||||
if adsb.oe_flag(m):
|
||||
msg1 = m
|
||||
t1 = ts
|
||||
else:
|
||||
msg0 = m
|
||||
t0 = ts
|
||||
|
||||
if msg0 and msg1:
|
||||
pos = adsb.position(msg0, msg1, t0, t1)
|
||||
alt = adsb.altitude(m)
|
||||
print(ts, m, icao, tc, pos, alt)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
adsb_decode_all(n=100)
|
||||
print("Execution time: {} seconds".format(dt))
|
||||
|
||||
60
tests/test_c_common.py
Normal file
60
tests/test_c_common.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from pyModeS.decoder import c_common as common
|
||||
|
||||
|
||||
def test_conversions():
|
||||
assert common.hex2bin("6E406B") == "011011100100000001101011"
|
||||
|
||||
|
||||
def test_crc_decode():
|
||||
|
||||
assert common.crc("8D406B902015A678D4D220AA4BDA") == 0
|
||||
assert common.crc("8d8960ed58bf053cf11bc5932b7d") == 0
|
||||
assert common.crc("8d45cab390c39509496ca9a32912") == 0
|
||||
assert common.crc("8d74802958c904e6ef4ba0184d5c") == 0
|
||||
assert common.crc("8d4400cd9b0000b4f87000e71a10") == 0
|
||||
assert common.crc("8d4065de58a1054a7ef0218e226a") == 0
|
||||
|
||||
assert common.crc("c80b2dca34aa21dd821a04cb64d4") == 10719924
|
||||
assert common.crc("a800089d8094e33a6004e4b8a522") == 4805588
|
||||
assert common.crc("a8000614a50b6d32bed000bbe0ed") == 5659991
|
||||
assert common.crc("a0000410bc900010a40000f5f477") == 11727682
|
||||
assert common.crc("8d4ca251204994b1c36e60a5343d") == 16
|
||||
assert common.crc("b0001718c65632b0a82040715b65") == 353333
|
||||
|
||||
|
||||
def test_crc_encode():
|
||||
parity = common.crc("8D406B902015A678D4D220AA4BDA", encode=True)
|
||||
assert parity == 11160538
|
||||
|
||||
|
||||
def test_icao():
|
||||
assert common.icao("8D406B902015A678D4D220AA4BDA") == "406B90"
|
||||
assert common.icao("A0001839CA3800315800007448D9") == "400940"
|
||||
assert common.icao("A000139381951536E024D4CCF6B5") == "3C4DD2"
|
||||
assert common.icao("A000029CFFBAA11E2004727281F1") == "4243D0"
|
||||
|
||||
|
||||
def test_modes_altcode():
|
||||
assert common.altcode("A02014B400000000000000F9D514") == 32300
|
||||
|
||||
|
||||
def test_modes_idcode():
|
||||
assert common.idcode("A800292DFFBBA9383FFCEB903D01") == "1346"
|
||||
|
||||
|
||||
def test_graycode_to_altitude():
|
||||
assert common.gray2alt("00000000010") == -1000
|
||||
assert common.gray2alt("00000001010") == -500
|
||||
assert common.gray2alt("00000011011") == -100
|
||||
assert common.gray2alt("00000011010") == 0
|
||||
assert common.gray2alt("00000011110") == 100
|
||||
assert common.gray2alt("00000010011") == 600
|
||||
assert common.gray2alt("00000110010") == 1000
|
||||
assert common.gray2alt("00001001001") == 5800
|
||||
assert common.gray2alt("00011100100") == 10300
|
||||
assert common.gray2alt("01100011010") == 32000
|
||||
assert common.gray2alt("01110000100") == 46300
|
||||
assert common.gray2alt("01010101100") == 50200
|
||||
assert common.gray2alt("11011110100") == 73200
|
||||
assert common.gray2alt("10000000011") == 126600
|
||||
assert common.gray2alt("10000000001") == 126700
|
||||
@@ -1,10 +1,8 @@
|
||||
from pyModeS import common
|
||||
from pyModeS.decoder import common
|
||||
|
||||
|
||||
def test_conversions():
|
||||
assert common.hex2bin("6E406B") == "011011100100000001101011"
|
||||
assert common.bin2hex("011011100100000001101011") == "6E406B"
|
||||
assert common.int2hex(11160538) == "AA4BDA"
|
||||
|
||||
|
||||
def test_crc_decode():
|
||||
@@ -28,7 +26,7 @@ def test_crc_decode():
|
||||
|
||||
def test_crc_encode():
|
||||
parity = common.crc("8D406B902015A678D4D220AA4BDA", encode=True)
|
||||
assert common.int2hex(parity) == "AA4BDA"
|
||||
assert parity == 11160538
|
||||
|
||||
|
||||
def test_icao():
|
||||
|
||||
Reference in New Issue
Block a user