From 2c1db1312201ae00b1fbfd1c5ce813ea4a36cc89 Mon Sep 17 00:00:00 2001 From: Junzi Sun Date: Tue, 10 Sep 2019 23:25:21 +0200 Subject: [PATCH] reformat code with Black --- pyModeS/__init__.py | 1 + pyModeS/decoder/adsb.py | 125 ++++++++++++-------- pyModeS/decoder/bds/__init__.py | 77 +++++++++---- pyModeS/decoder/bds/bds06.py | 27 ++--- pyModeS/decoder/bds/bds08.py | 11 +- pyModeS/decoder/bds/bds09.py | 48 ++++---- pyModeS/decoder/bds/bds10.py | 8 +- pyModeS/decoder/bds/bds17.py | 40 ++++++- pyModeS/decoder/bds/bds20.py | 9 +- pyModeS/decoder/bds/bds30.py | 5 +- pyModeS/decoder/bds/bds44.py | 8 +- pyModeS/decoder/bds/bds45.py | 18 +-- pyModeS/decoder/bds/bds50.py | 24 ++-- pyModeS/decoder/bds/bds53.py | 23 ++-- pyModeS/decoder/bds/bds60.py | 23 ++-- pyModeS/decoder/common.py | 35 +----- pyModeS/decoder/describe.py | 1 + pyModeS/decoder/ehs.py | 13 ++- pyModeS/decoder/els.py | 7 +- pyModeS/decoder/uncertainty.py | 197 ++++++++++++++++++-------------- pyModeS/extra/aero.py | 69 +++++------ pyModeS/extra/tcpclient.py | 10 +- pyModeS/streamer/decode.py | 8 +- pyModeS/streamer/screen.py | 4 +- tests/sample_run_adsb.py | 7 +- tests/sample_run_commb.py | 39 +++++-- tests/test_bds_inference.py | 27 ++--- tests/test_commb.py | 16 +-- tests/test_common.py | 72 ++++++------ 29 files changed, 535 insertions(+), 417 deletions(-) create mode 100644 pyModeS/decoder/describe.py diff --git a/pyModeS/__init__.py b/pyModeS/__init__.py index fca2aa3..395354a 100644 --- a/pyModeS/__init__.py +++ b/pyModeS/__init__.py @@ -12,4 +12,5 @@ from .extra import tcpclient # from .decoder import ehs # depricated import os + dirpath = os.path.dirname(os.path.realpath(__file__)) diff --git a/pyModeS/decoder/adsb.py b/pyModeS/decoder/adsb.py index bd8daa4..42ffe6f 100644 --- a/pyModeS/decoder/adsb.py +++ b/pyModeS/decoder/adsb.py @@ -35,20 +35,32 @@ from pyModeS.decoder import common from pyModeS.decoder import uncertainty # from pyModeS.decoder.bds import bds05, bds06, bds09 -from pyModeS.decoder.bds.bds05 import airborne_position, airborne_position_with_ref, altitude -from pyModeS.decoder.bds.bds06 import surface_position, surface_position_with_ref, surface_velocity +from pyModeS.decoder.bds.bds05 import ( + airborne_position, + airborne_position_with_ref, + altitude, +) +from pyModeS.decoder.bds.bds06 import ( + surface_position, + surface_position_with_ref, + surface_velocity, +) from pyModeS.decoder.bds.bds08 import category, callsign from pyModeS.decoder.bds.bds09 import airborne_velocity, altitude_diff + def df(msg): return common.df(msg) + def icao(msg): return common.icao(msg) + def typecode(msg): return common.typecode(msg) + def position(msg0, msg1, t0, t1, lat_ref=None, lon_ref=None): """Decode position from a pair of even and odd position message (works with both airborne and surface position messages) @@ -65,19 +77,21 @@ def position(msg0, msg1, t0, t1, lat_ref=None, lon_ref=None): tc0 = typecode(msg0) tc1 = typecode(msg1) - if (5<=tc0<=8 and 5<=tc1<=8): + if 5 <= tc0 <= 8 and 5 <= tc1 <= 8: if (not lat_ref) or (not lon_ref): - raise RuntimeError("Surface position encountered, a reference \ + raise RuntimeError( + "Surface position encountered, a reference \ position lat/lon required. Location of \ - receiver can be used.") + receiver can be used." + ) else: return surface_position(msg0, msg1, t0, t1, lat_ref, lon_ref) - elif (9<=tc0<=18 and 9<=tc1<=18): + elif 9 <= tc0 <= 18 and 9 <= tc1 <= 18: # Airborne position with barometric height return airborne_position(msg0, msg1, t0, t1) - elif (20<=tc0<=22 and 20<=tc1<=22): + elif 20 <= tc0 <= 22 and 20 <= tc1 <= 22: # Airborne position with GNSS height return airborne_position(msg0, msg1, t0, t1) @@ -104,10 +118,10 @@ def position_with_ref(msg, lat_ref, lon_ref): tc = typecode(msg) - if 5<=tc<=8: + if 5 <= tc <= 8: return surface_position_with_ref(msg, lat_ref, lon_ref) - elif 9<=tc<=18 or 20<=tc<=22: + elif 9 <= tc <= 18 or 20 <= tc <= 22: return airborne_position_with_ref(msg, lat_ref, lon_ref) else: @@ -126,17 +140,17 @@ def altitude(msg): tc = typecode(msg) - if tc<5 or tc==19 or tc>22: + if tc < 5 or tc == 19 or tc > 22: raise RuntimeError("%s: Not a position message" % msg) - if tc>=5 and tc<=8: + if tc >= 5 and tc <= 8: # surface position, altitude 0 return 0 msgbin = common.hex2bin(msg) q = msgbin[47] if q: - n = common.bin2int(msgbin[40:47]+msgbin[48:52]) + n = common.bin2int(msgbin[40:47] + msgbin[48:52]) alt = n * 25 - 1000 return alt else: @@ -175,7 +189,9 @@ def velocity(msg, rtn_sources=False): return airborne_velocity(msg, rtn_sources) else: - raise RuntimeError("incorrect or inconsistant message types, expecting 4 18: - raise RuntimeError("%s: Not a airborne position message, expecting 8 t1): + if t0 > t1: lat = lat_even nl = common.cprNL(lat_even) ni = max(common.cprNL(lat_even) - 0, 1) - m = common.floor(cprlon_even * (nl-1) - cprlon_odd * nl + 0.5) + m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5) lon = (90.0 / ni) * (m % ni + cprlon_even) else: lat = lat_odd nl = common.cprNL(lat_odd) ni = max(common.cprNL(lat_odd) - 1, 1) - m = common.floor(cprlon_even * (nl-1) - cprlon_odd * nl + 0.5) + m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5) lon = (90.0 / ni) * (m % ni + cprlon_odd) # four possible longitude solutions @@ -112,17 +112,17 @@ def surface_position_with_ref(msg, lat_ref, lon_ref): (float, float): (latitude, longitude) of the aircraft """ - mb = common.hex2bin(msg)[32:] cprlat = common.bin2int(mb[22:39]) / 131072.0 cprlon = common.bin2int(mb[39:56]) / 131072.0 i = int(mb[21]) - d_lat = 90.0/59 if i else 90.0/60 + d_lat = 90.0 / 59 if i else 90.0 / 60 - j = common.floor(lat_ref / d_lat) \ - + common.floor(0.5 + ((lat_ref % d_lat) / d_lat) - cprlat) + j = common.floor(lat_ref / d_lat) + common.floor( + 0.5 + ((lat_ref % d_lat) / d_lat) - cprlat + ) lat = d_lat * (j + cprlat) @@ -133,8 +133,9 @@ def surface_position_with_ref(msg, lat_ref, lon_ref): else: d_lon = 90.0 - m = common.floor(lon_ref / d_lon) \ - + common.floor(0.5 + ((lon_ref % d_lon) / d_lon) - cprlon) + m = common.floor(lon_ref / d_lon) + common.floor( + 0.5 + ((lon_ref % d_lon) / d_lon) - cprlon + ) lon = d_lon * (m + cprlon) @@ -184,11 +185,11 @@ def surface_velocity(msg, rtn_sources=False): movs = [2, 9, 13, 39, 94, 109, 124] kts = [0.125, 1, 2, 15, 70, 100, 175] i = next(m[0] for m in enumerate(movs) if m[1] > mov) - step = (kts[i] - kts[i-1]) * 1.0 / (movs[i]-movs[i-1]) - spd = kts[i-1] + (mov-movs[i-1]) * step + step = (kts[i] - kts[i - 1]) * 1.0 / (movs[i] - movs[i - 1]) + spd = kts[i - 1] + (mov - movs[i - 1]) * step spd = round(spd, 2) if rtn_sources: - return spd, trk, 0, 'GS', 'true_north', None + return spd, trk, 0, "GS", "true_north", None else: - return spd, trk, 0, 'GS' + return spd, trk, 0, "GS" diff --git a/pyModeS/decoder/bds/bds08.py b/pyModeS/decoder/bds/bds08.py index 895e525..cd8068c 100644 --- a/pyModeS/decoder/bds/bds08.py +++ b/pyModeS/decoder/bds/bds08.py @@ -23,6 +23,7 @@ from __future__ import absolute_import, print_function, division from pyModeS.decoder import common + def category(msg): """Aircraft category number @@ -36,8 +37,8 @@ def category(msg): if common.typecode(msg) < 1 or common.typecode(msg) > 4: raise RuntimeError("%s: Not a identification message" % msg) - msgbin = common.hex2bin(msg) - mebin = msgbin[32:87] + msgbin = common.hex2bin(msg) + mebin = msgbin[32:87] return common.bin2int(mebin[5:8]) @@ -54,11 +55,11 @@ def callsign(msg): if common.typecode(msg) < 1 or common.typecode(msg) > 4: raise RuntimeError("%s: Not a identification message" % msg) - chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######' + chars = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######" msgbin = common.hex2bin(msg) csbin = msgbin[40:96] - cs = '' + cs = "" cs += chars[common.bin2int(csbin[0:6])] cs += chars[common.bin2int(csbin[6:12])] cs += chars[common.bin2int(csbin[12:18])] @@ -70,5 +71,5 @@ def callsign(msg): # clean string, remove spaces and marks, if any. # cs = cs.replace('_', '') - cs = cs.replace('#', '') + cs = cs.replace("#", "") return cs diff --git a/pyModeS/decoder/bds/bds09.py b/pyModeS/decoder/bds/bds09.py index 44d7a31..e98e13e 100644 --- a/pyModeS/decoder/bds/bds09.py +++ b/pyModeS/decoder/bds/bds09.py @@ -57,32 +57,32 @@ def airborne_velocity(msg, rtn_sources=False): return None if subtype in (1, 2): - v_ew_sign = -1 if mb[13]=='1' else 1 - v_ew = common.bin2int(mb[14:24]) - 1 # east-west velocity - if subtype == 2: # Supersonic + v_ew_sign = -1 if mb[13] == "1" else 1 + v_ew = common.bin2int(mb[14:24]) - 1 # east-west velocity + if subtype == 2: # Supersonic v_ew *= 4 - v_ns_sign = -1 if mb[24]=='1' else 1 - v_ns = common.bin2int(mb[25:35]) - 1 # north-south velocity - if subtype == 2: # Supersonic + v_ns_sign = -1 if mb[24] == "1" else 1 + v_ns = common.bin2int(mb[25:35]) - 1 # north-south velocity + if subtype == 2: # Supersonic v_ns *= 4 v_we = v_ew_sign * v_ew v_sn = v_ns_sign * v_ns - spd = math.sqrt(v_sn*v_sn + v_we*v_we) # unit in kts + spd = math.sqrt(v_sn * v_sn + v_we * v_we) # unit in kts spd = int(spd) trk = math.atan2(v_we, v_sn) - trk = math.degrees(trk) # convert to degrees - trk = trk if trk >= 0 else trk + 360 # no negative val + trk = math.degrees(trk) # convert to degrees + trk = trk if trk >= 0 else trk + 360 # no negative val - tag = 'GS' + tag = "GS" trk_or_hdg = round(trk, 2) - dir_type = 'true_north' + dir_type = "true_north" else: - if mb[13] == '0': + if mb[13] == "0": hdg = None else: hdg = common.bin2int(mb[14:24]) / 1024.0 * 360.0 @@ -91,27 +91,27 @@ def airborne_velocity(msg, rtn_sources=False): trk_or_hdg = hdg spd = common.bin2int(mb[25:35]) - spd = None if spd==0 else spd-1 - if subtype == 4: # Supersonic + spd = None if spd == 0 else spd - 1 + if subtype == 4: # Supersonic spd *= 4 - if mb[24]=='0': - tag = 'IAS' + if mb[24] == "0": + tag = "IAS" else: - tag = 'TAS' - - dir_type = 'mag_north' + tag = "TAS" - vr_source = 'GNSS' if mb[35]=='0' else 'Baro' - vr_sign = -1 if mb[36]=='1' else 1 + dir_type = "mag_north" + + vr_source = "GNSS" if mb[35] == "0" else "Baro" + vr_sign = -1 if mb[36] == "1" else 1 vr = common.bin2int(mb[37:46]) - rocd = None if vr==0 else int(vr_sign*(vr-1)*64) + rocd = None if vr == 0 else int(vr_sign * (vr - 1) * 64) if rtn_sources: return spd, trk_or_hdg, rocd, tag, dir_type, vr_source else: return spd, trk_or_hdg, rocd, tag - + def altitude_diff(msg): """Decode the differece between GNSS and barometric altitude @@ -135,4 +135,4 @@ def altitude_diff(msg): if value == 0 or value == 127: return None else: - return sign * (value - 1) * 25 # in ft. + return sign * (value - 1) * 25 # in ft. diff --git a/pyModeS/decoder/bds/bds10.py b/pyModeS/decoder/bds/bds10.py index 836a252..07a9467 100644 --- a/pyModeS/decoder/bds/bds10.py +++ b/pyModeS/decoder/bds/bds10.py @@ -21,6 +21,7 @@ from __future__ import absolute_import, print_function, division from pyModeS.decoder.common import hex2bin, bin2int, data, allzeros + def is10(msg): """Check if a message is likely to be BDS code 1,0 @@ -37,7 +38,7 @@ def is10(msg): d = hex2bin(data(msg)) # first 8 bits must be 0x10 - if d[0:8] != '00010000': + if d[0:8] != "00010000": return False # bit 10 to 14 are reserved @@ -45,13 +46,14 @@ def is10(msg): return False # overlay capabilty conflict - if d[14] == '1' and bin2int(d[16:23]) < 5: + if d[14] == "1" and bin2int(d[16:23]) < 5: return False - if d[14] == '0' and bin2int(d[16:23]) > 4: + if d[14] == "0" and bin2int(d[16:23]) > 4: return False return True + def ovc10(msg): """Return the overlay control capability diff --git a/pyModeS/decoder/bds/bds17.py b/pyModeS/decoder/bds/bds17.py index 937f8ff..e153c70 100644 --- a/pyModeS/decoder/bds/bds17.py +++ b/pyModeS/decoder/bds/bds17.py @@ -50,11 +50,12 @@ def is17(msg): # return False # at least you can respond who you are - if 'BDS20' not in caps: + if "BDS20" not in caps: return False return True + def cap17(msg): """Extract capacities from BDS 1,7 message @@ -64,12 +65,39 @@ def cap17(msg): Returns: list: list of suport BDS codes """ - allbds = ['05', '06', '07', '08', '09', '0A', '20', '21', '40', '41', - '42', '43', '44', '45', '48', '50', '51', '52', '53', '54', - '55', '56', '5F', '60', 'NA', 'NA', 'E1', 'E2'] + allbds = [ + "05", + "06", + "07", + "08", + "09", + "0A", + "20", + "21", + "40", + "41", + "42", + "43", + "44", + "45", + "48", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "5F", + "60", + "NA", + "NA", + "E1", + "E2", + ] d = hex2bin(data(msg)) - idx = [i for i, v in enumerate(d[:28]) if v=='1'] - capacity = ['BDS'+allbds[i] for i in idx if allbds[i] is not 'NA'] + idx = [i for i, v in enumerate(d[:28]) if v == "1"] + capacity = ["BDS" + allbds[i] for i in idx if allbds[i] is not "NA"] return capacity diff --git a/pyModeS/decoder/bds/bds20.py b/pyModeS/decoder/bds/bds20.py index 7e13636..63f28d6 100644 --- a/pyModeS/decoder/bds/bds20.py +++ b/pyModeS/decoder/bds/bds20.py @@ -21,6 +21,7 @@ from __future__ import absolute_import, print_function, division from pyModeS.decoder.common import hex2bin, bin2int, data, allzeros + def is20(msg): """Check if a message is likely to be BDS code 2,0 @@ -36,12 +37,12 @@ def is20(msg): d = hex2bin(data(msg)) - if d[0:8] != '00100000': + if d[0:8] != "00100000": return False cs = cs20(msg) - if '#' in cs: + if "#" in cs: return False return True @@ -56,11 +57,11 @@ def cs20(msg): Returns: string: callsign, max. 8 chars """ - chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######' + chars = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######" d = hex2bin(data(msg)) - cs = '' + cs = "" cs += chars[bin2int(d[8:14])] cs += chars[bin2int(d[14:20])] cs += chars[bin2int(d[20:26])] diff --git a/pyModeS/decoder/bds/bds30.py b/pyModeS/decoder/bds/bds30.py index 9032311..cb4d94c 100644 --- a/pyModeS/decoder/bds/bds30.py +++ b/pyModeS/decoder/bds/bds30.py @@ -21,6 +21,7 @@ from __future__ import absolute_import, print_function, division from pyModeS.decoder.common import hex2bin, bin2int, data, allzeros + def is30(msg): """Check if a message is likely to be BDS code 2,0 @@ -36,11 +37,11 @@ def is30(msg): d = hex2bin(data(msg)) - if d[0:8] != '00110000': + if d[0:8] != "00110000": return False # threat type 3 not assigned - if d[28:30] == '11': + if d[28:30] == "11": return False # reserved for ACAS III, in far future diff --git a/pyModeS/decoder/bds/bds44.py b/pyModeS/decoder/bds/bds44.py index 4c3fc35..adb4ff4 100644 --- a/pyModeS/decoder/bds/bds44.py +++ b/pyModeS/decoder/bds/bds44.py @@ -19,13 +19,7 @@ # ------------------------------------------ from __future__ import absolute_import, print_function, division -from pyModeS.decoder.common import ( - hex2bin, - bin2int, - data, - allzeros, - wrongstatus, -) +from pyModeS.decoder.common import hex2bin, bin2int, data, allzeros, wrongstatus def is44(msg): diff --git a/pyModeS/decoder/bds/bds45.py b/pyModeS/decoder/bds/bds45.py index 0fd40c5..3dd5c0a 100644 --- a/pyModeS/decoder/bds/bds45.py +++ b/pyModeS/decoder/bds/bds45.py @@ -87,7 +87,7 @@ def turb45(msg): """ d = hex2bin(data(msg)) - if d[0] == '0': + if d[0] == "0": return None turb = bin2int(d[1:3]) @@ -105,7 +105,7 @@ def ws45(msg): """ d = hex2bin(data(msg)) - if d[3] == '0': + if d[3] == "0": return None ws = bin2int(d[4:6]) @@ -123,7 +123,7 @@ def mb45(msg): """ d = hex2bin(data(msg)) - if d[6] == '0': + if d[6] == "0": return None mb = bin2int(d[7:9]) @@ -141,7 +141,7 @@ def ic45(msg): """ d = hex2bin(data(msg)) - if d[9] == '0': + if d[9] == "0": return None ic = bin2int(d[10:12]) @@ -159,7 +159,7 @@ def wv45(msg): """ d = hex2bin(data(msg)) - if d[12] == '0': + if d[12] == "0": return None ws = bin2int(d[13:15]) @@ -184,7 +184,7 @@ def temp45(msg): if sign: value = value - 512 - temp = value * 0.25 # celsius + temp = value * 0.25 # celsius temp = round(temp, 1) return temp @@ -201,9 +201,9 @@ def p45(msg): """ d = hex2bin(data(msg)) - if d[26] == '0': + if d[26] == "0": return None - p = bin2int(d[27:38]) # hPa + p = bin2int(d[27:38]) # hPa return p @@ -218,7 +218,7 @@ def rh45(msg): """ d = hex2bin(data(msg)) - if d[38] == '0': + if d[38] == "0": return None rh = bin2int(d[39:51]) * 16 return rh diff --git a/pyModeS/decoder/bds/bds50.py b/pyModeS/decoder/bds/bds50.py index 6bfedb2..ae65786 100644 --- a/pyModeS/decoder/bds/bds50.py +++ b/pyModeS/decoder/bds/bds50.py @@ -85,16 +85,16 @@ def roll50(msg): """ d = hex2bin(data(msg)) - if d[0] == '0': + if d[0] == "0": return None - sign = int(d[1]) # 1 -> left wing down + sign = int(d[1]) # 1 -> left wing down value = bin2int(d[2:11]) if sign: value = value - 512 - angle = value * 45.0 / 256.0 # degree + angle = value * 45.0 / 256.0 # degree return round(angle, 1) @@ -109,10 +109,10 @@ def trk50(msg): """ d = hex2bin(data(msg)) - if d[11] == '0': + if d[11] == "0": return None - sign = int(d[12]) # 1 -> west + sign = int(d[12]) # 1 -> west value = bin2int(d[13:23]) if sign: @@ -138,10 +138,10 @@ def gs50(msg): """ d = hex2bin(data(msg)) - if d[23] == '0': + if d[23] == "0": return None - spd = bin2int(d[24:34]) * 2 # kts + spd = bin2int(d[24:34]) * 2 # kts return spd @@ -156,18 +156,18 @@ def rtrk50(msg): """ d = hex2bin(data(msg)) - if d[34] == '0': + if d[34] == "0": return None if d[36:45] == "111111111": return None - sign = int(d[35]) # 1 -> negative value, two's complement + sign = int(d[35]) # 1 -> negative value, two's complement value = bin2int(d[36:45]) if sign: value = value - 512 - angle = value * 8.0 / 256.0 # degree / sec + angle = value * 8.0 / 256.0 # degree / sec return round(angle, 3) @@ -182,8 +182,8 @@ def tas50(msg): """ d = hex2bin(data(msg)) - if d[45] == '0': + if d[45] == "0": return None - tas = bin2int(d[46:56]) * 2 # kts + tas = bin2int(d[46:56]) * 2 # kts return tas diff --git a/pyModeS/decoder/bds/bds53.py b/pyModeS/decoder/bds/bds53.py index e48186e..962e260 100644 --- a/pyModeS/decoder/bds/bds53.py +++ b/pyModeS/decoder/bds/bds53.py @@ -85,16 +85,16 @@ def hdg53(msg): """ d = hex2bin(data(msg)) - if d[0] == '0': + if d[0] == "0": return None - sign = int(d[1]) # 1 -> west + sign = int(d[1]) # 1 -> west value = bin2int(d[2:12]) if sign: value = value - 1024 - hdg = value * 90.0 / 512.0 # degree + hdg = value * 90.0 / 512.0 # degree # convert from [-180, 180] to [0, 360] if hdg < 0: @@ -114,10 +114,10 @@ def ias53(msg): """ d = hex2bin(data(msg)) - if d[12] == '0': + if d[12] == "0": return None - ias = bin2int(d[13:23]) # knots + ias = bin2int(d[13:23]) # knots return ias @@ -132,7 +132,7 @@ def mach53(msg): """ d = hex2bin(data(msg)) - if d[23] == '0': + if d[23] == "0": return None mach = bin2int(d[24:33]) * 0.008 @@ -150,12 +150,13 @@ def tas53(msg): """ d = hex2bin(data(msg)) - if d[33] == '0': + if d[33] == "0": return None - tas = bin2int(d[34:46]) * 0.5 # kts + tas = bin2int(d[34:46]) * 0.5 # kts return round(tas, 1) + def vr53(msg): """Vertical rate @@ -167,16 +168,16 @@ def vr53(msg): """ d = hex2bin(data(msg)) - if d[46] == '0': + if d[46] == "0": return None - sign = int(d[47]) # 1 -> negative value, two's complement + sign = int(d[47]) # 1 -> negative value, two's complement value = bin2int(d[48:56]) if value == 0 or value == 255: # all zeros or all ones return 0 value = value - 256 if sign else value - roc = value * 64 # feet/min + roc = value * 64 # feet/min return roc diff --git a/pyModeS/decoder/bds/bds60.py b/pyModeS/decoder/bds/bds60.py index f143b24..2298c33 100644 --- a/pyModeS/decoder/bds/bds60.py +++ b/pyModeS/decoder/bds/bds60.py @@ -21,6 +21,7 @@ from __future__ import absolute_import, print_function, division from pyModeS.decoder.common import hex2bin, bin2int, data, allzeros, wrongstatus + def is60(msg): """Check if a message is likely to be BDS code 6,0 @@ -83,10 +84,10 @@ def hdg60(msg): """ d = hex2bin(data(msg)) - if d[0] == '0': + if d[0] == "0": return None - sign = int(d[1]) # 1 -> west + sign = int(d[1]) # 1 -> west value = bin2int(d[2:12]) if sign: @@ -112,10 +113,10 @@ def ias60(msg): """ d = hex2bin(data(msg)) - if d[12] == '0': + if d[12] == "0": return None - ias = bin2int(d[13:23]) # kts + ias = bin2int(d[13:23]) # kts return ias @@ -130,7 +131,7 @@ def mach60(msg): """ d = hex2bin(data(msg)) - if d[23] == '0': + if d[23] == "0": return None mach = bin2int(d[24:34]) * 2.048 / 512.0 @@ -148,10 +149,10 @@ def vr60baro(msg): """ d = hex2bin(data(msg)) - if d[34] == '0': + if d[34] == "0": return None - sign = int(d[35]) # 1 -> negative value, two's complement + sign = int(d[35]) # 1 -> negative value, two's complement value = bin2int(d[36:45]) if value == 0 or value == 511: # all zeros or all ones @@ -159,7 +160,7 @@ def vr60baro(msg): value = value - 512 if sign else value - roc = value * 32 # feet/min + roc = value * 32 # feet/min return roc @@ -174,10 +175,10 @@ def vr60ins(msg): """ d = hex2bin(data(msg)) - if d[45] == '0': + if d[45] == "0": return None - sign = int(d[46]) # 1 -> negative value, two's complement + sign = int(d[46]) # 1 -> negative value, two's complement value = bin2int(d[47:56]) if value == 0 or value == 511: # all zeros or all ones @@ -185,5 +186,5 @@ def vr60ins(msg): value = value - 512 if sign else value - roc = value * 32 # feet/min + roc = value * 32 # feet/min return roc diff --git a/pyModeS/decoder/common.py b/pyModeS/decoder/common.py index bd64c5d..08fdf4d 100644 --- a/pyModeS/decoder/common.py +++ b/pyModeS/decoder/common.py @@ -61,12 +61,7 @@ def crc(msg, encode=False): """ # the CRC generator - G = [ - int("11111111", 2), - int("11111010", 2), - int("00000100", 2), - int("10000000", 2), - ] + G = [int("11111111", 2), int("11111010", 2), int("00000100", 2), int("10000000", 2)] if encode: msg = msg[:-6] + "000000" @@ -101,33 +96,7 @@ def crc_legacy(msg, encode=False): """Mode-S Cyclic Redundancy Check. (Legacy code, 2x slow).""" # the polynominal generattor code for CRC [1111111111111010000001001] generator = np.array( - [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 1, - ] + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1] ) ng = len(generator) diff --git a/pyModeS/decoder/describe.py b/pyModeS/decoder/describe.py new file mode 100644 index 0000000..25edaa1 --- /dev/null +++ b/pyModeS/decoder/describe.py @@ -0,0 +1 @@ +import pyModeS as pms diff --git a/pyModeS/decoder/ehs.py b/pyModeS/decoder/ehs.py index da23b8e..8abf6ea 100644 --- a/pyModeS/decoder/ehs.py +++ b/pyModeS/decoder/ehs.py @@ -17,13 +17,20 @@ from pyModeS.decoder.bds.bds50 import * from pyModeS.decoder.bds.bds60 import * from pyModeS.decoder.bds import infer -warnings.simplefilter('once', DeprecationWarning) -warnings.warn("pms.ehs module is deprecated. Please use pms.commb instead.", DeprecationWarning) +warnings.simplefilter("once", DeprecationWarning) +warnings.warn( + "pms.ehs module is deprecated. Please use pms.commb instead.", DeprecationWarning +) + def BDS(msg): - warnings.warn("pms.ehs.BDS() is deprecated, use pms.bds.infer() instead.", DeprecationWarning) + warnings.warn( + "pms.ehs.BDS() is deprecated, use pms.bds.infer() instead.", DeprecationWarning + ) return infer(msg) + def icao(msg): from pyModeS.decoder.common import icao + return icao(msg) diff --git a/pyModeS/decoder/els.py b/pyModeS/decoder/els.py index 50915f6..a028c9c 100644 --- a/pyModeS/decoder/els.py +++ b/pyModeS/decoder/els.py @@ -18,5 +18,8 @@ from pyModeS.decoder.bds.bds20 import * from pyModeS.decoder.bds.bds30 import * import warnings -warnings.simplefilter('once', DeprecationWarning) -warnings.warn("pms.els module is deprecated. Please use pms.commb instead.", DeprecationWarning) + +warnings.simplefilter("once", DeprecationWarning) +warnings.warn( + "pms.els module is deprecated. Please use pms.commb instead.", DeprecationWarning +) diff --git a/pyModeS/decoder/uncertainty.py b/pyModeS/decoder/uncertainty.py index 1a4fbe7..cb74cb0 100644 --- a/pyModeS/decoder/uncertainty.py +++ b/pyModeS/decoder/uncertainty.py @@ -6,120 +6,147 @@ See source code at: https://github.com/junzis/pyModeS/blob/master/pyModeS/decode NA = None TC_NUCp_lookup = { - 0:0, 5:9, 6:8, 7:7, 8:6, - 9:9, 10:8, 11:7, 12:6, 13:5, 14:4, 15:3, 16:2, 17:1, 18:0, - 20:9, 21:8, 22:0 + 0: 0, + 5: 9, + 6: 8, + 7: 7, + 8: 6, + 9: 9, + 10: 8, + 11: 7, + 12: 6, + 13: 5, + 14: 4, + 15: 3, + 16: 2, + 17: 1, + 18: 0, + 20: 9, + 21: 8, + 22: 0, } TC_NICv1_lookup = { - 5:11, 6:10, 7:9, 8:0, - 9:11, 10:10, 11:{1:9, 0:8}, 12:7, 13:6, 14:5, 15:4, 16:{1:3, 0:2}, 17:1, 18:0, - 20:11, 21:10, 22:0 + 5: 11, + 6: 10, + 7: 9, + 8: 0, + 9: 11, + 10: 10, + 11: {1: 9, 0: 8}, + 12: 7, + 13: 6, + 14: 5, + 15: 4, + 16: {1: 3, 0: 2}, + 17: 1, + 18: 0, + 20: 11, + 21: 10, + 22: 0, } TC_NICv2_lookup = { - 5:11, 6:10, 7:{2:9, 0:8}, 8:{3:7, 2:6, 1:6, 0:0}, - 9:11, 10:10, 11:{3:9, 0:8}, 12:7, 13:6, 14:5, 15:4, 16:{3:3, 0:2}, 17:1, 18:0, - 20:11, 21:10, 22:0 + 5: 11, + 6: 10, + 7: {2: 9, 0: 8}, + 8: {3: 7, 2: 6, 1: 6, 0: 0}, + 9: 11, + 10: 10, + 11: {3: 9, 0: 8}, + 12: 7, + 13: 6, + 14: 5, + 15: 4, + 16: {3: 3, 0: 2}, + 17: 1, + 18: 0, + 20: 11, + 21: 10, + 22: 0, } NUCp = { - 9: {'HPL':7.5, 'RCu':3, 'RCv':4}, - 8: {'HPL':25, 'RCu':10, 'RCv':15}, - 7: {'HPL':185, 'RCu':93, 'RCv':NA}, - 6: {'HPL':370, 'RCu':185, 'RCv':NA}, - 5: {'HPL':926, 'RCu':463, 'RCv':NA}, - 4: {'HPL':1852, 'RCu':926, 'RCv':NA}, - 3: {'HPL':3704, 'RCu':1852, 'RCv':NA}, - 2: {'HPL':18520, 'RCu':9260, 'RCv':NA}, - 1: {'HPL':37040, 'RCu':18520, 'RCv':NA}, - 0: {'HPL':NA, 'RCu':NA, 'RCv':NA}, + 9: {"HPL": 7.5, "RCu": 3, "RCv": 4}, + 8: {"HPL": 25, "RCu": 10, "RCv": 15}, + 7: {"HPL": 185, "RCu": 93, "RCv": NA}, + 6: {"HPL": 370, "RCu": 185, "RCv": NA}, + 5: {"HPL": 926, "RCu": 463, "RCv": NA}, + 4: {"HPL": 1852, "RCu": 926, "RCv": NA}, + 3: {"HPL": 3704, "RCu": 1852, "RCv": NA}, + 2: {"HPL": 18520, "RCu": 9260, "RCv": NA}, + 1: {"HPL": 37040, "RCu": 18520, "RCv": NA}, + 0: {"HPL": NA, "RCu": NA, "RCv": NA}, } NUCv = { - 0: {'HVE':NA, 'VVE':NA}, - 1: {'HVE':10, 'VVE':15.2}, - 2: {'HVE':3, 'VVE':4.5}, - 3: {'HVE':1, 'VVE':1.5}, - 4: {'HVE':0.3, 'VVE':0.46}, + 0: {"HVE": NA, "VVE": NA}, + 1: {"HVE": 10, "VVE": 15.2}, + 2: {"HVE": 3, "VVE": 4.5}, + 3: {"HVE": 1, "VVE": 1.5}, + 4: {"HVE": 0.3, "VVE": 0.46}, } NACp = { - 11: {'EPU': 3, 'VEPU': 4}, - 10: {'EPU': 10, 'VEPU': 15}, - 9: {'EPU': 30, 'VEPU': 45}, - 8: {'EPU': 93, 'VEPU': NA}, - 7: {'EPU': 185, 'VEPU': NA}, - 6: {'EPU': 556, 'VEPU': NA}, - 5: {'EPU': 926, 'VEPU': NA}, - 4: {'EPU': 1852, 'VEPU': NA}, - 3: {'EPU': 3704, 'VEPU': NA}, - 2: {'EPU': 7408, 'VEPU': NA}, - 1: {'EPU': 18520, 'VEPU': NA}, - 0: {'EPU': NA, 'VEPU': NA}, + 11: {"EPU": 3, "VEPU": 4}, + 10: {"EPU": 10, "VEPU": 15}, + 9: {"EPU": 30, "VEPU": 45}, + 8: {"EPU": 93, "VEPU": NA}, + 7: {"EPU": 185, "VEPU": NA}, + 6: {"EPU": 556, "VEPU": NA}, + 5: {"EPU": 926, "VEPU": NA}, + 4: {"EPU": 1852, "VEPU": NA}, + 3: {"EPU": 3704, "VEPU": NA}, + 2: {"EPU": 7408, "VEPU": NA}, + 1: {"EPU": 18520, "VEPU": NA}, + 0: {"EPU": NA, "VEPU": NA}, } NACv = { - 0: {'HFOMr':NA, 'VFOMr':NA}, - 1: {'HFOMr':10, 'VFOMr':15.2}, - 2: {'HFOMr':3, 'VFOMr':4.5}, - 3: {'HFOMr':1, 'VFOMr':1.5}, - 4: {'HFOMr':0.3, 'VFOMr':0.46}, + 0: {"HFOMr": NA, "VFOMr": NA}, + 1: {"HFOMr": 10, "VFOMr": 15.2}, + 2: {"HFOMr": 3, "VFOMr": 4.5}, + 3: {"HFOMr": 1, "VFOMr": 1.5}, + 4: {"HFOMr": 0.3, "VFOMr": 0.46}, } SIL = { - 3: {'PE_RCu': 1e-7, 'PE_VPL': 2e-7}, - 2: {'PE_RCu': 1e-5, 'PE_VPL': 1e-5}, - 1: {'PE_RCu': 1e-3, 'PE_VPL': 1e-3}, - 0: {'PE_RCu': NA, 'PE_VPL': NA}, + 3: {"PE_RCu": 1e-7, "PE_VPL": 2e-7}, + 2: {"PE_RCu": 1e-5, "PE_VPL": 1e-5}, + 1: {"PE_RCu": 1e-3, "PE_VPL": 1e-3}, + 0: {"PE_RCu": NA, "PE_VPL": NA}, } NICv1 = { # NIC is used as the index at second Level - - 11: {0: {'Rc': 7.5, 'VPL': 11}}, - 10: {0: {'Rc': 25, 'VPL': 37.5}}, - 9: {1: {'Rc': 75, 'VPL': 112}}, - 8: {0: {'Rc': 185, 'VPL': NA}}, - 7: {0: {'Rc': 370, 'VPL': NA}}, - 6: { - 0: {'Rc': 926, 'VPL': NA}, - 1: {'Rc': 1111, 'VPL': NA}, - }, - 5: {0: {'Rc': 1852, 'VPL': NA}}, - 4: {0: {'Rc': 3702, 'VPL': NA}}, - 3: {1: {'Rc': 7408, 'VPL': NA}}, - 2: {0: {'Rc': 14008, 'VPL': NA}}, - 1: {0: {'Rc': 37000, 'VPL': NA}}, - 0: {0: {'Rc': NA, 'VPL': NA}}, + 11: {0: {"Rc": 7.5, "VPL": 11}}, + 10: {0: {"Rc": 25, "VPL": 37.5}}, + 9: {1: {"Rc": 75, "VPL": 112}}, + 8: {0: {"Rc": 185, "VPL": NA}}, + 7: {0: {"Rc": 370, "VPL": NA}}, + 6: {0: {"Rc": 926, "VPL": NA}, 1: {"Rc": 1111, "VPL": NA}}, + 5: {0: {"Rc": 1852, "VPL": NA}}, + 4: {0: {"Rc": 3702, "VPL": NA}}, + 3: {1: {"Rc": 7408, "VPL": NA}}, + 2: {0: {"Rc": 14008, "VPL": NA}}, + 1: {0: {"Rc": 37000, "VPL": NA}}, + 0: {0: {"Rc": NA, "VPL": NA}}, } NICv2 = { # Decimal value of [NICa NICb/NICc] is used as the index at second Level - - 11: {0: {'Rc': 7.5}}, - 10: {0: {'Rc': 25}}, - 9: { - 2: {'Rc': 75}, - 3: {'Rc': 75}, - }, - 8: {0: {'Rc': 185}}, - 7: { - 0: {'Rc': 370}, - 3: {'Rc': 370}, - }, - 6: { - 0: {'Rc': 926}, - 1: {'Rc': 556}, - 2: {'Rc': 556}, - 3: {'Rc': 1111}, - }, - 5: {0: {'Rc': 1852}}, - 4: {0: {'Rc': 3702}}, - 3: {3: {'Rc': 7408}}, - 2: {0: {'Rc': 14008}}, - 1: {0: {'Rc': 37000}}, - 0: {0: {'Rc': NA}}, + 11: {0: {"Rc": 7.5}}, + 10: {0: {"Rc": 25}}, + 9: {2: {"Rc": 75}, 3: {"Rc": 75}}, + 8: {0: {"Rc": 185}}, + 7: {0: {"Rc": 370}, 3: {"Rc": 370}}, + 6: {0: {"Rc": 926}, 1: {"Rc": 556}, 2: {"Rc": 556}, 3: {"Rc": 1111}}, + 5: {0: {"Rc": 1852}}, + 4: {0: {"Rc": 3702}}, + 3: {3: {"Rc": 7408}}, + 2: {0: {"Rc": 14008}}, + 1: {0: {"Rc": 37000}}, + 0: {0: {"Rc": NA}}, } diff --git a/pyModeS/extra/aero.py b/pyModeS/extra/aero.py index 9d9683b..dd807ef 100644 --- a/pyModeS/extra/aero.py +++ b/pyModeS/extra/aero.py @@ -30,31 +30,31 @@ Speed conversion at altitude H[m] in ISA import numpy as np """Aero and geo Constants """ -kts = 0.514444 # knot -> m/s -ft = 0.3048 # ft -> m -fpm = 0.00508 # ft/min -> m/s -inch = 0.0254 # inch -> m -sqft = 0.09290304 # 1 square foot -nm = 1852. # nautical mile -> m -lbs = 0.453592 # pound -> kg -g0 = 9.80665 # m/s2, Sea level gravity constant -R = 287.05287 # m2/(s2 x K), gas constant, sea level ISA -p0 = 101325. # Pa, air pressure, sea level ISA -rho0 = 1.225 # kg/m3, air density, sea level ISA -T0 = 288.15 # K, temperature, sea level ISA -gamma = 1.40 # cp/cv for air -gamma1 = 0.2 # (gamma-1)/2 for air -gamma2 = 3.5 # gamma/(gamma-1) for air -beta = -0.0065 # [K/m] ISA temp gradient below tropopause -r_earth = 6371000. # m, average earth radius -a0 = 340.293988 # m/s, sea level speed of sound ISA, sqrt(gamma*R*T0) +kts = 0.514444 # knot -> m/s +ft = 0.3048 # ft -> m +fpm = 0.00508 # ft/min -> m/s +inch = 0.0254 # inch -> m +sqft = 0.09290304 # 1 square foot +nm = 1852.0 # nautical mile -> m +lbs = 0.453592 # pound -> kg +g0 = 9.80665 # m/s2, Sea level gravity constant +R = 287.05287 # m2/(s2 x K), gas constant, sea level ISA +p0 = 101325.0 # Pa, air pressure, sea level ISA +rho0 = 1.225 # kg/m3, air density, sea level ISA +T0 = 288.15 # K, temperature, sea level ISA +gamma = 1.40 # cp/cv for air +gamma1 = 0.2 # (gamma-1)/2 for air +gamma2 = 3.5 # gamma/(gamma-1) for air +beta = -0.0065 # [K/m] ISA temp gradient below tropopause +r_earth = 6371000.0 # m, average earth radius +a0 = 340.293988 # m/s, sea level speed of sound ISA, sqrt(gamma*R*T0) def atmos(H): # H in metres T = np.maximum(288.15 - 0.0065 * H, 216.65) - rhotrop = 1.225 * (T / 288.15)**4.256848030018761 - dhstrat = np.maximum(0., H - 11000.0) + rhotrop = 1.225 * (T / 288.15) ** 4.256848030018761 + dhstrat = np.maximum(0.0, H - 11000.0) rho = rhotrop * np.exp(-dhstrat / 6341.552161) p = rho * R * T return p, rho, T @@ -101,11 +101,13 @@ def distance(lat1, lon1, lat2, lon2, H=0): theta1 = np.radians(lon1) theta2 = np.radians(lon2) - cos = np.sin(phi1) * np.sin(phi2) * np.cos(theta1 - theta2) + np.cos(phi1) * np.cos(phi2) - cos = np.where(cos>1, 1, cos) + cos = np.sin(phi1) * np.sin(phi2) * np.cos(theta1 - theta2) + np.cos(phi1) * np.cos( + phi2 + ) + cos = np.where(cos > 1, 1, cos) arc = np.arccos(cos) - dist = arc * (r_earth + H) # meters, radius of earth + dist = arc * (r_earth + H) # meters, radius of earth return dist @@ -114,9 +116,8 @@ def bearing(lat1, lon1, lat2, lon2): lon1 = np.radians(lon1) lat2 = np.radians(lat2) lon2 = np.radians(lon2) - x = np.sin(lon2-lon1) * np.cos(lat2) - y = np.cos(lat1) * np.sin(lat2) \ - - np.sin(lat1) * np.cos(lat2) * np.cos(lon2-lon1) + x = np.sin(lon2 - lon1) * np.cos(lat2) + y = np.cos(lat1) * np.sin(lat2) - np.sin(lat1) * np.cos(lat2) * np.cos(lon2 - lon1) initial_bearing = np.arctan2(x, y) initial_bearing = np.degrees(initial_bearing) bearing = (initial_bearing + 360) % 360 @@ -129,44 +130,44 @@ def bearing(lat1, lon1, lat2, lon2): def tas2mach(Vtas, H): """True Airspeed to Mach number""" a = vsound(H) - Mach = Vtas/a + Mach = Vtas / a return Mach def mach2tas(Mach, H): """Mach number to True Airspeed""" a = vsound(H) - Vtas = Mach*a + Vtas = Mach * a return Vtas def eas2tas(Veas, H): """Equivalent Airspeed to True Airspeed""" rho = density(H) - Vtas = Veas * np.sqrt(rho0/rho) + Vtas = Veas * np.sqrt(rho0 / rho) return Vtas def tas2eas(Vtas, H): """True Airspeed to Equivalent Airspeed""" rho = density(H) - Veas = Vtas * np.sqrt(rho/rho0) + Veas = Vtas * np.sqrt(rho / rho0) return Veas def cas2tas(Vcas, H): """Calibrated Airspeed to True Airspeed""" p, rho, T = atmos(H) - qdyn = p0*((1.+rho0*Vcas*Vcas/(7.*p0))**3.5-1.) - Vtas = np.sqrt(7.*p/rho*((1.+qdyn/p)**(2./7.)-1.)) + qdyn = p0 * ((1.0 + rho0 * Vcas * Vcas / (7.0 * p0)) ** 3.5 - 1.0) + Vtas = np.sqrt(7.0 * p / rho * ((1.0 + qdyn / p) ** (2.0 / 7.0) - 1.0)) return Vtas def tas2cas(Vtas, H): """True Airspeed to Calibrated Airspeed""" p, rho, T = atmos(H) - qdyn = p*((1.+rho*Vtas*Vtas/(7.*p))**3.5-1.) - Vcas = np.sqrt(7.*p0/rho0*((qdyn/p0+1.)**(2./7.)-1.)) + qdyn = p * ((1.0 + rho * Vtas * Vtas / (7.0 * p)) ** 3.5 - 1.0) + Vcas = np.sqrt(7.0 * p0 / rho0 * ((qdyn / p0 + 1.0) ** (2.0 / 7.0) - 1.0)) return Vcas diff --git a/pyModeS/extra/tcpclient.py b/pyModeS/extra/tcpclient.py index b70f917..1d8864a 100644 --- a/pyModeS/extra/tcpclient.py +++ b/pyModeS/extra/tcpclient.py @@ -59,9 +59,7 @@ class TcpClient(object): msg_stop = False self.current_msg = "" - if (not msg_stop) and ( - 48 <= b <= 57 or 65 <= b <= 70 or 97 <= b <= 102 - ): + if (not msg_stop) and (48 <= b <= 57 or 65 <= b <= 70 or 97 <= b <= 102): self.current_msg = self.current_msg + chr(b) self.buffer = [] @@ -234,11 +232,7 @@ class TcpClient(object): msg = "".join("%02X" % j for j in payload) i += 14 # Both message types use 14 bytes tsbin = self.buffer[i : i + 6] - sec = ( - ((tsbin[0] & 0x7F) << 10) - | (tsbin[1] << 2) - | (tsbin[2] >> 6) - ) + sec = ((tsbin[0] & 0x7F) << 10) | (tsbin[1] << 2) | (tsbin[2] >> 6) nano = ( ((tsbin[2] & 0x3F) << 24) | (tsbin[3] << 16) diff --git a/pyModeS/streamer/decode.py b/pyModeS/streamer/decode.py index bdfa7a0..6a3fcc6 100644 --- a/pyModeS/streamer/decode.py +++ b/pyModeS/streamer/decode.py @@ -108,9 +108,7 @@ class Decode: self.acs[icao][oe] = msg self.acs[icao]["t" + str(oe)] = t - if ("tpos" in self.acs[icao]) and ( - t - self.acs[icao]["tpos"] < 180 - ): + if ("tpos" in self.acs[icao]) and (t - self.acs[icao]["tpos"] < 180): # use single message decoding rlat = self.acs[icao]["lat"] rlon = self.acs[icao]["lon"] @@ -174,9 +172,7 @@ class Decode: ac["HFOMr"], ac["VFOMr"] = pms.adsb.nac_v(msg) if tc == 29: - ac["PE_RCu"], ac["PE_VPL"], ac["base"] = pms.adsb.sil( - msg, ac["ver"] - ) + ac["PE_RCu"], ac["PE_VPL"], ac["base"] = pms.adsb.sil(msg, ac["ver"]) ac["EPU"], ac["VEPU"] = pms.adsb.nac_p(msg) if tc == 31: diff --git a/pyModeS/streamer/screen.py b/pyModeS/streamer/screen.py index 022d9cc..5de1825 100644 --- a/pyModeS/streamer/screen.py +++ b/pyModeS/streamer/screen.py @@ -147,9 +147,7 @@ class Screen(object): total_page = len(icaos) // (self.scr_h - 4) + 1 current_page = self.offset // (self.scr_h - 4) + 1 - self.screen.addstr( - self.scr_h - 2, 1, "(%d / %d)" % (current_page, total_page) - ) + self.screen.addstr(self.scr_h - 2, 1, "(%d / %d)" % (current_page, total_page)) self.reset_cursor_pos() diff --git a/tests/sample_run_adsb.py b/tests/sample_run_adsb.py index 8b8ecfb..c6c7c16 100644 --- a/tests/sample_run_adsb.py +++ b/tests/sample_run_adsb.py @@ -4,10 +4,12 @@ from pyModeS import adsb, ehs # === Decode sample data file === + def adsb_decode_all(n=None): print("===== Decode ADS-B sample data=====") import csv - f = open('tests/data/sample_data_adsb.csv', 'rt') + + f = open("tests/data/sample_data_adsb.csv", "rt") msg0 = None msg1 = None @@ -37,5 +39,6 @@ def adsb_decode_all(n=None): alt = adsb.altitude(m) print(ts, m, icao, tc, pos, alt) -if __name__ == '__main__': + +if __name__ == "__main__": adsb_decode_all(n=100) diff --git a/tests/sample_run_commb.py b/tests/sample_run_commb.py index dde33ef..9049cad 100644 --- a/tests/sample_run_commb.py +++ b/tests/sample_run_commb.py @@ -3,12 +3,13 @@ from pyModeS import commb, common, bds # === Decode sample data file === + def bds_info(BDS, m): if BDS == "BDS10": info = [commb.ovc10(m)] elif BDS == "BDS17": - info = ([i[-2:] for i in commb.cap17(m)]) + info = [i[-2:] for i in commb.cap17(m)] elif BDS == "BDS20": info = [commb.cs20(m)] @@ -20,13 +21,30 @@ def bds_info(BDS, m): info = (commb.wind44(m), commb.temp44(m), commb.p44(m), commb.hum44(m)) elif BDS == "BDS44REV": - info = (commb.wind44(m, rev=True), commb.temp44(m, rev=True), commb.p44(m, rev=True), commb.hum44(m, rev=True)) + info = ( + commb.wind44(m, rev=True), + commb.temp44(m, rev=True), + commb.p44(m, rev=True), + commb.hum44(m, rev=True), + ) elif BDS == "BDS50": - info = (commb.roll50(m), commb.trk50(m), commb.gs50(m), commb.rtrk50(m), commb.tas50(m)) + info = ( + commb.roll50(m), + commb.trk50(m), + commb.gs50(m), + commb.rtrk50(m), + commb.tas50(m), + ) elif BDS == "BDS60": - info = (commb.hdg60(m), commb.ias60(m), commb.mach60(m), commb.vr60baro(m), commb.vr60ins(m)) + info = ( + commb.hdg60(m), + commb.ias60(m), + commb.mach60(m), + commb.vr60baro(m), + commb.vr60ins(m), + ) else: info = None @@ -39,8 +57,7 @@ def commb_decode_all(df, n=None): print("===== Decode Comm-B sample data (DF=%s)=====" % df) - f = open('tests/data/sample_data_commb_df%s.csv' % df, 'rt') - + f = open("tests/data/sample_data_commb_df%s.csv" % df, "rt") for i, r in enumerate(csv.reader(f)): if n and i > n: @@ -55,21 +72,21 @@ def commb_decode_all(df, n=None): code = common.altcode(m) if df == 20 else common.idcode(m) if not BDS: - print(ts, m, icao, df, '%5s'%code, 'UNKNOWN') + print(ts, m, icao, df, "%5s" % code, "UNKNOWN") continue if len(BDS.split(",")) > 1: - print(ts, m, icao, df, '%5s' % code, end=' ') + print(ts, m, icao, df, "%5s" % code, end=" ") for i, _bds in enumerate(BDS.split(",")): if i == 0: print(_bds, *bds_info(_bds, m)) else: - print(' ' * 55, _bds, *bds_info(_bds, m)) + print(" " * 55, _bds, *bds_info(_bds, m)) else: - print(ts, m, icao, df, '%5s'%code, BDS, *bds_info(BDS, m)) + print(ts, m, icao, df, "%5s" % code, BDS, *bds_info(BDS, m)) -if __name__ == '__main__': +if __name__ == "__main__": commb_decode_all(df=20, n=100) commb_decode_all(df=21, n=100) diff --git a/tests/test_bds_inference.py b/tests/test_bds_inference.py index f7b8f2f..7d5168c 100644 --- a/tests/test_bds_inference.py +++ b/tests/test_bds_inference.py @@ -1,20 +1,21 @@ from pyModeS import bds -def test_bds_infer(): - assert bds.infer("8D406B902015A678D4D220AA4BDA") == 'BDS08' - assert bds.infer("8FC8200A3AB8F5F893096B000000") == 'BDS06' - assert bds.infer("8D40058B58C901375147EFD09357") == 'BDS05' - assert bds.infer("8D485020994409940838175B284F") == 'BDS09' - assert bds.infer("A800178D10010080F50000D5893C") == 'BDS10' - assert bds.infer("A0000638FA81C10000000081A92F") == 'BDS17' - assert bds.infer("A0001838201584F23468207CDFA5") == 'BDS20' - assert bds.infer("A0001839CA3800315800007448D9") == 'BDS40' - assert bds.infer("A000139381951536E024D4CCF6B5") == 'BDS50' - assert bds.infer("A00004128F39F91A7E27C46ADC21") == 'BDS60' +def test_bds_infer(): + assert bds.infer("8D406B902015A678D4D220AA4BDA") == "BDS08" + assert bds.infer("8FC8200A3AB8F5F893096B000000") == "BDS06" + assert bds.infer("8D40058B58C901375147EFD09357") == "BDS05" + assert bds.infer("8D485020994409940838175B284F") == "BDS09" + + assert bds.infer("A800178D10010080F50000D5893C") == "BDS10" + assert bds.infer("A0000638FA81C10000000081A92F") == "BDS17" + assert bds.infer("A0001838201584F23468207CDFA5") == "BDS20" + assert bds.infer("A0001839CA3800315800007448D9") == "BDS40" + assert bds.infer("A000139381951536E024D4CCF6B5") == "BDS50" + assert bds.infer("A00004128F39F91A7E27C46ADC21") == "BDS60" def test_bds_is50or60(): assert bds.is50or60("A0001838201584F23468207CDFA5", 0, 0, 0) == None - assert bds.is50or60("A0000000FFDA9517000464000000", 182, 237, 1250) == 'BDS50' - assert bds.is50or60("A0000000919A5927E23444000000", 413, 54, 18700) == 'BDS60' + assert bds.is50or60("A0000000FFDA9517000464000000", 182, 237, 1250) == "BDS50" + assert bds.is50or60("A0000000919A5927E23444000000", 413, 54, 18700) == "BDS60" diff --git a/tests/test_commb.py b/tests/test_commb.py index 6c0117e..45cc1ec 100644 --- a/tests/test_commb.py +++ b/tests/test_commb.py @@ -1,12 +1,14 @@ from pyModeS import bds, commb + # from pyModeS import ehs, els # deprecated -def test_bds20_callsign(): - assert bds.bds20.cs20("A000083E202CC371C31DE0AA1CCF") == 'KLM1017_' - assert bds.bds20.cs20("A0001993202422F2E37CE038738E") == 'IBK2873_' - assert commb.cs20("A000083E202CC371C31DE0AA1CCF") == 'KLM1017_' - assert commb.cs20("A0001993202422F2E37CE038738E") == 'IBK2873_' +def test_bds20_callsign(): + assert bds.bds20.cs20("A000083E202CC371C31DE0AA1CCF") == "KLM1017_" + assert bds.bds20.cs20("A0001993202422F2E37CE038738E") == "IBK2873_" + + assert commb.cs20("A000083E202CC371C31DE0AA1CCF") == "KLM1017_" + assert commb.cs20("A0001993202422F2E37CE038738E") == "IBK2873_" def test_bds40_functions(): @@ -21,14 +23,14 @@ def test_bds40_functions(): def test_bds50_functions(): assert bds.bds50.roll50("A000139381951536E024D4CCF6B5") == 2.1 - assert bds.bds50.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 # signed value + assert bds.bds50.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 # signed value assert bds.bds50.trk50("A000139381951536E024D4CCF6B5") == 114.258 assert bds.bds50.gs50("A000139381951536E024D4CCF6B5") == 438 assert bds.bds50.rtrk50("A000139381951536E024D4CCF6B5") == 0.125 assert bds.bds50.tas50("A000139381951536E024D4CCF6B5") == 424 assert commb.roll50("A000139381951536E024D4CCF6B5") == 2.1 - assert commb.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 # signed value + assert commb.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 # signed value assert commb.trk50("A000139381951536E024D4CCF6B5") == 114.258 assert commb.gs50("A000139381951536E024D4CCF6B5") == 438 assert commb.rtrk50("A000139381951536E024D4CCF6B5") == 0.125 diff --git a/tests/test_common.py b/tests/test_common.py index fd5095a..df2ac36 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -2,57 +2,63 @@ from pyModeS import common def test_conversions(): - assert common.hex2bin('6E406B') == "011011100100000001101011" - assert common.bin2hex('011011100100000001101011') == "6E406B" + assert common.hex2bin("6E406B") == "011011100100000001101011" + assert common.bin2hex("011011100100000001101011") == "6E406B" assert common.int2hex(11160538) == "AA4BDA" + def test_crc_decode(): assert common.crc_legacy("8D406B902015A678D4D220AA4BDA") == 0 assert common.crc("8D406B902015A678D4D220AA4BDA") == 0 - assert common.crc('8d8960ed58bf053cf11bc5932b7d') == 0 - assert common.crc('8d45cab390c39509496ca9a32912') == 0 - assert common.crc('8d49d3d4e1089d00000000744c3b') == 0 - assert common.crc('8d74802958c904e6ef4ba0184d5c') == 0 - assert common.crc('8d4400cd9b0000b4f87000e71a10') == 0 - assert common.crc('8d4065de58a1054a7ef0218e226a') == 0 + assert common.crc("8d8960ed58bf053cf11bc5932b7d") == 0 + assert common.crc("8d45cab390c39509496ca9a32912") == 0 + assert common.crc("8d49d3d4e1089d00000000744c3b") == 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 - 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 common.int2hex(parity) == "AA4BDA" + def test_icao(): assert common.icao("8D406B902015A678D4D220AA4BDA") == "406B90" - assert common.icao("A0001839CA3800315800007448D9") == '400940' - assert common.icao("A000139381951536E024D4CCF6B5") == '3C4DD2' - assert common.icao("A000029CFFBAA11E2004727281F1") == '4243D0' + 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' + 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 + 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