Module ammosreader.PDW
I store the information of a single PDW block.
Expand source code
"""I store the information of a single PDW block."""
import struct
import math
import numpy as np
class PDW():
"""
I store information from a single ppdw data block.
.. automethod:: __init__
"""
@classmethod
def from_bytes(cls, byte_string):
"""
I create an instance of class PDW from data body (8 * 32 bits).
:param byte_string: a byte string containing a single data body read from a ppdw file
:type byte_string: byte string
:return: an instance of class PDW with attributes set according to the data of a data body
:rtype: PDW
"""
assert(len(byte_string) == 32)
parts = struct.unpack('<Q4s4s4s4s4s4s', byte_string)
nanoseconds = (parts[0])
time_of_arrival = np.datetime64(nanoseconds, 'ns')
third_entry = bin(int.from_bytes(parts[1], byteorder='little'))
padding = 32-len(str(third_entry)[2:])
third_entry_bit_string = "0" * padding + str(third_entry)[2:]
pdw_format_identifier = int(third_entry_bit_string[0:6], 2)
center_frequency = int(third_entry_bit_string[5:32], 2)
fourth_entry = bin(int.from_bytes(parts[2], byteorder='little'))
padding = 32-len(str(fourth_entry)[2:])
fourth_entry_bit_string = "0" * padding + str(fourth_entry)[2:]
is_valid = bool(int(fourth_entry_bit_string[0]))
is_pulse = bool(int(fourth_entry_bit_string[1]))
level_unit = int(fourth_entry_bit_string[2])
signal_start_missing = bool(int(fourth_entry_bit_string[3]))
signal_end_missing = bool(int(fourth_entry_bit_string[4]))
pulse_width = int(fourth_entry_bit_string[7:33], 2)
fifth_entry = bin(int.from_bytes(parts[3], byteorder='little'))
padding = 32-len(str(fifth_entry)[2:])
fifth_entry_bit_string = "0" * padding + str(fifth_entry)[2:]
frequency_shift_or_bandwidth = int(fifth_entry_bit_string[0:20], 2)
# FIXME: You have to scale me to the range from -200.0 to 200.0 in 0.1 steps
pulse_level_or_pulse_field_strength = math.ceil(int(fifth_entry_bit_string[20:32], 2)) / 10
sixth_entry = bin(int.from_bytes(parts[4], byteorder='little'))
padding = 32-len(str(sixth_entry)[2:])
sixth_entry_bit_string = "0" * padding + str(sixth_entry)[2:]
region_of_interest = bool(int(sixth_entry_bit_string[0]))
# FIXME: You have to scale me to a range from 0.0 to 6.2 in steps of 0.1 - 6.3 means unknown
azimuth_confidence = math.ceil(int(sixth_entry_bit_string[1:7], 2)) / 10
modulations = {0: 'Unknown', 1: 'Unmodulated', 2: 'FM', 3: 'LFM', 4: 'PSK-2', 5: 'PSK-3', 6: 'PSK-4',
7: 'PSK-m', 8: 'NLFM', 9: 'SFM', 10: 'TFM', 11: 'Pulse too short'}
modulation = modulations[int(sixth_entry_bit_string[7:12], 2)]
sector = int(sixth_entry_bit_string[28:32], 2)
seventh_entry = bin(int.from_bytes(parts[5], byteorder='little'))
padding = 32-len(str(seventh_entry)[2:])
seventh_entry_bit_string = "0" * padding + str(seventh_entry)[2:]
polarities = {0: 'Horizontal/Unknown', 1: 'Vertical', 2: 'Counter clockwise', 3: 'Clockwise'}
polarity = polarities[int(seventh_entry_bit_string[0:2], 2)]
df_quality = int(seventh_entry_bit_string[2:9], 2)
# FIXME: You have to scale me from -90 to 90 in 0.1 degree steps
elevation = int(seventh_entry_bit_string[9:20], 2)
# FIXME: You have to check me for a range from 0.0 to 359.9 in steps of 0.1
azimuth = 0.1 * (int(seventh_entry_bit_string[20:32], 2))
eighth_entry = bin(int.from_bytes(parts[5], byteorder='little'))
padding = 32-len(str(eighth_entry)[2:])
eighth_entry_bit_string = "0" * padding + str(eighth_entry)[2:]
channel = int(eighth_entry_bit_string[0:4], 2)
return PDW(time_of_arrival, pdw_format_identifier, center_frequency, is_valid, is_pulse, level_unit,
signal_start_missing, signal_end_missing, pulse_width, frequency_shift_or_bandwidth,
pulse_level_or_pulse_field_strength, region_of_interest, azimuth_confidence, modulation,
sector, polarity, df_quality, elevation, azimuth, channel)
def __init__(self, time_of_arrival, pdw_format_identifier, center_frequency, is_valid, is_pulse,
level_unit, signal_start_missing, signal_end_missing, pulse_width, frequency_shift_or_bandwidth,
pulse_level_or_pulse_field_strength, region_of_interest, azimuth_confidence, modulation,
sector, polarity, df_quality, elevation, azimuth, channel):
r"""
I return an instance of an Pulse Data word.
:param time_of_arrival: nanoseconds since 1970-01-01 00:00:00
:type time_of_arrival: Integer
:param pdw_format: format code
:type pdw_format: Integer
:param center_frequency: center frequency in KHz
:type center_frequency: Integer
:param is_valid: flag to mark if pdw data body is valid
:type is_valid: Boolean
:param is_pulse: flag to mark if pdw data body contains a pulse or a continuous wave signal
:type is_pulse: Boolean
:param level_unit: 0 means dBµV - 1 means dBµV/m
:type level_unit: Integer
:param signal_start_missing: signal started before time of arrival
:type signal_start_missing: Boolean
:param signal_end_missing: signal stops after time of arrival
:type signal_end_missing: Boolean
:param pulse_width: pulse width in nanoseconds - Zero if no valid pulse detected
:type pulse_width: Integer
:param frequency_shift_or_bandwidth: Value in KHz - Value set to 1048575 means Unknown
:type frequency_shift_or_bandwidth: Integer
:param pulse_level_or_pulse_field_strength: Pulse level or Pulse Field Strength depending on level_unit \
(-200.0...200.0) in 0.1 steps / minus 204.8 means no valid level detected
:type pulse_level_or_pulse_field_strength: Float
:param region_of_interest: Marks if signal is from region of interest
:type region_of_interest: Boolean
:param azimuth_confidence: degree in steps of 0.1 (0.0-6.2) / 6.3 means confidence unknown
:type azimuth_confidence: Float
:param modulation: type of modulation (e.g. PSK-2, PSK-4, FM etc.)
:type modulation: String
:param sector: reference antenna sector (0-15)
:type sector: Integer
:param polarity: Horizontal, Vertical, Clockwise, Counter clockwise
:type polarity: String
:param df_quality: Direction finding quality in percent (0-100) - Zero means unknown
:type df_quality: Integer
:param elevation: elevation of incoming signal (from -90 to 90 degree) in steps of 0.1 degree \
minus 102.4 means unknown
:type elevation: Float
:param azimuth: azimuth of incoming signal (from 0 to 359.9 degree) in steps of 0.1 degree \
plus 409.5 means unknown
:type azimuth: Float
:param channel: detecting channel (0-16) - Zero means unknown
:type channel: Integer
:return: An instance of class PDW with attributes set according to the data of a data body
:rtype: PDW
"""
self.time_of_arrival = time_of_arrival #
self.pdw_format_identifier = pdw_format_identifier
self.center_frequency = center_frequency #
self.__is_valid = is_valid #
self.is_pulse = is_pulse #
self.level_unit = level_unit #
self.signal_start_missing = signal_start_missing
self.signal_end_missing = signal_end_missing
self.pulse_width = pulse_width #
self.frequency_shift_or_bandwidth = frequency_shift_or_bandwidth #
self.pulse_level_or_pulse_field_strength = pulse_level_or_pulse_field_strength #
self.region_of_interest = region_of_interest
self.azimuth_confidence = azimuth_confidence
self.modulation = modulation #
self.sector = sector
self.polarity = polarity
self.df_quality = df_quality #
self.elevation = elevation #
self.azimuth = azimuth
self.channel = channel #
def __str__(self):
"""
I return the string representation of myself.
:rtype: str
"""
output = ("Time of arrival: " + str(self.time_of_arrival) + "\n" +
"PDW Format identifier: " + str(self.pdw_format_identifier) + "\n" +
"Center frequency: " + str(self.center_frequency) + " KHz\n")
if self.__is_valid:
output += "Signal: Valid\n"
else:
output += "Signal: Invalid\n"
if self.is_pulse:
output += "Signal type: Pulse\n"
else:
output += "Signal type: Continuous wave\n"
if self.level_unit == 1:
output += "Pulse level: " + str(self.pulse_level_or_pulse_field_strength) + " dbµV\n"
else:
output += "Pulse field strength: " + str(self.pulse_level_or_pulse_field_strength) + " dbµV/meter\n"
output += ("Pulse width: " + str(self.pulse_width) + " nanoseconds\n" +
"Frequency shift or bandwidth: " + str(self.frequency_shift_or_bandwidth) + " KHz\n")
if self.region_of_interest:
output += "Region of interest: Yes\n"
else:
output += "Region of interest: No\n"
if self.azimuth_confidence == 6.3:
output += "Azimuth confidence: Invalid\n"
else:
output += "Azimuth confidence: " + str(self.azimuth_confidence) + " degree\n"
output += "Modulation: " + str(self.modulation) + "\n"
if self.sector == 0:
output += "Sector: Unknown\n"
else:
output += "Sector:" + str(self.sector) + "\n"
output += "Polarity: " + str(self.polarity) + "\n"
output += "DF quality: " + str(self.df_quality) + " %\n"
if self.elevation == 1024:
output += "Elevation: Unknown\n"
else:
output += "Elevation: " + str(self.elevation) + " degree\n"
if self.azimuth == 409.5:
output += "Azimuth: Unknown\n"
else:
output += "Azimuth: " + str(self.azimuth) + " degree\n"
output += "Channel: " + str(self.channel) + "\n"
return output
def is_valid(self):
return self.__is_valid
def to_json(self):
return {'time of arrival': self.time_of_arrival,
'FORMATIDENTIFIER': self.pdw_format_identifier,
'center frequency': self.center_frequency,
'VALID': self.__is_valid,
'PULSE': self.is_pulse,
'PULSELEVEL': self.pulse_level_or_pulse_field_strength,
'PULSEWIDTH': self.pulse_width,
'BANDWIDTH': self.frequency_shift_or_bandwidth,
'REGIONOFINTEREST': self.region_of_interest,
'AZIMUTHCONFIDENCE': self.azimuth_confidence,
'MODULATION': self.modulation,
'SECTOR': self.sector,
'POLARITY': self.polarity,
'DFQUALITY': self.df_quality,
'ELEVATION': self.elevation,
'AZIMUTH': self.azimuth,
'CHANNEL': self.channel
}
if __name__ == '__main__':
pass
Classes
class PDW (time_of_arrival, pdw_format_identifier, center_frequency, is_valid, is_pulse, level_unit, signal_start_missing, signal_end_missing, pulse_width, frequency_shift_or_bandwidth, pulse_level_or_pulse_field_strength, region_of_interest, azimuth_confidence, modulation, sector, polarity, df_quality, elevation, azimuth, channel)
-
I store information from a single ppdw data block.
Automethod: init
I return an instance of an Pulse Data word.
:param time_of_arrival: nanoseconds since 1970-01-01 00:00:00 :type time_of_arrival: Integer :param pdw_format: format code :type pdw_format: Integer :param center_frequency: center frequency in KHz :type center_frequency: Integer :param is_valid: flag to mark if pdw data body is valid :type is_valid: Boolean :param is_pulse: flag to mark if pdw data body contains a pulse or a continuous wave signal :type is_pulse: Boolean :param level_unit: 0 means dBµV - 1 means dBµV/m :type level_unit: Integer :param signal_start_missing: signal started before time of arrival :type signal_start_missing: Boolean :param signal_end_missing: signal stops after time of arrival :type signal_end_missing: Boolean :param pulse_width: pulse width in nanoseconds - Zero if no valid pulse detected :type pulse_width: Integer :param frequency_shift_or_bandwidth: Value in KHz - Value set to 1048575 means Unknown :type frequency_shift_or_bandwidth: Integer :param pulse_level_or_pulse_field_strength: Pulse level or Pulse Field Strength depending on level_unit \ (-200.0…200.0) in 0.1 steps / minus 204.8 means no valid level detected :type pulse_level_or_pulse_field_strength: Float :param region_of_interest: Marks if signal is from region of interest :type region_of_interest: Boolean :param azimuth_confidence: degree in steps of 0.1 (0.0-6.2) / 6.3 means confidence unknown :type azimuth_confidence: Float :param modulation: type of modulation (e.g. PSK-2, PSK-4, FM etc.) :type modulation: String :param sector: reference antenna sector (0-15) :type sector: Integer :param polarity: Horizontal, Vertical, Clockwise, Counter clockwise :type polarity: String :param df_quality: Direction finding quality in percent (0-100) - Zero means unknown :type df_quality: Integer :param elevation: elevation of incoming signal (from -90 to 90 degree) in steps of 0.1 degree \ minus 102.4 means unknown :type elevation: Float :param azimuth: azimuth of incoming signal (from 0 to 359.9 degree) in steps of 0.1 degree \ plus 409.5 means unknown :type azimuth: Float :param channel: detecting channel (0-16) - Zero means unknown :type channel: Integer :return: An instance of class PDW with attributes set according to the data of a data body :rtype: PDW
Expand source code
class PDW(): """ I store information from a single ppdw data block. .. automethod:: __init__ """ @classmethod def from_bytes(cls, byte_string): """ I create an instance of class PDW from data body (8 * 32 bits). :param byte_string: a byte string containing a single data body read from a ppdw file :type byte_string: byte string :return: an instance of class PDW with attributes set according to the data of a data body :rtype: PDW """ assert(len(byte_string) == 32) parts = struct.unpack('<Q4s4s4s4s4s4s', byte_string) nanoseconds = (parts[0]) time_of_arrival = np.datetime64(nanoseconds, 'ns') third_entry = bin(int.from_bytes(parts[1], byteorder='little')) padding = 32-len(str(third_entry)[2:]) third_entry_bit_string = "0" * padding + str(third_entry)[2:] pdw_format_identifier = int(third_entry_bit_string[0:6], 2) center_frequency = int(third_entry_bit_string[5:32], 2) fourth_entry = bin(int.from_bytes(parts[2], byteorder='little')) padding = 32-len(str(fourth_entry)[2:]) fourth_entry_bit_string = "0" * padding + str(fourth_entry)[2:] is_valid = bool(int(fourth_entry_bit_string[0])) is_pulse = bool(int(fourth_entry_bit_string[1])) level_unit = int(fourth_entry_bit_string[2]) signal_start_missing = bool(int(fourth_entry_bit_string[3])) signal_end_missing = bool(int(fourth_entry_bit_string[4])) pulse_width = int(fourth_entry_bit_string[7:33], 2) fifth_entry = bin(int.from_bytes(parts[3], byteorder='little')) padding = 32-len(str(fifth_entry)[2:]) fifth_entry_bit_string = "0" * padding + str(fifth_entry)[2:] frequency_shift_or_bandwidth = int(fifth_entry_bit_string[0:20], 2) # FIXME: You have to scale me to the range from -200.0 to 200.0 in 0.1 steps pulse_level_or_pulse_field_strength = math.ceil(int(fifth_entry_bit_string[20:32], 2)) / 10 sixth_entry = bin(int.from_bytes(parts[4], byteorder='little')) padding = 32-len(str(sixth_entry)[2:]) sixth_entry_bit_string = "0" * padding + str(sixth_entry)[2:] region_of_interest = bool(int(sixth_entry_bit_string[0])) # FIXME: You have to scale me to a range from 0.0 to 6.2 in steps of 0.1 - 6.3 means unknown azimuth_confidence = math.ceil(int(sixth_entry_bit_string[1:7], 2)) / 10 modulations = {0: 'Unknown', 1: 'Unmodulated', 2: 'FM', 3: 'LFM', 4: 'PSK-2', 5: 'PSK-3', 6: 'PSK-4', 7: 'PSK-m', 8: 'NLFM', 9: 'SFM', 10: 'TFM', 11: 'Pulse too short'} modulation = modulations[int(sixth_entry_bit_string[7:12], 2)] sector = int(sixth_entry_bit_string[28:32], 2) seventh_entry = bin(int.from_bytes(parts[5], byteorder='little')) padding = 32-len(str(seventh_entry)[2:]) seventh_entry_bit_string = "0" * padding + str(seventh_entry)[2:] polarities = {0: 'Horizontal/Unknown', 1: 'Vertical', 2: 'Counter clockwise', 3: 'Clockwise'} polarity = polarities[int(seventh_entry_bit_string[0:2], 2)] df_quality = int(seventh_entry_bit_string[2:9], 2) # FIXME: You have to scale me from -90 to 90 in 0.1 degree steps elevation = int(seventh_entry_bit_string[9:20], 2) # FIXME: You have to check me for a range from 0.0 to 359.9 in steps of 0.1 azimuth = 0.1 * (int(seventh_entry_bit_string[20:32], 2)) eighth_entry = bin(int.from_bytes(parts[5], byteorder='little')) padding = 32-len(str(eighth_entry)[2:]) eighth_entry_bit_string = "0" * padding + str(eighth_entry)[2:] channel = int(eighth_entry_bit_string[0:4], 2) return PDW(time_of_arrival, pdw_format_identifier, center_frequency, is_valid, is_pulse, level_unit, signal_start_missing, signal_end_missing, pulse_width, frequency_shift_or_bandwidth, pulse_level_or_pulse_field_strength, region_of_interest, azimuth_confidence, modulation, sector, polarity, df_quality, elevation, azimuth, channel) def __init__(self, time_of_arrival, pdw_format_identifier, center_frequency, is_valid, is_pulse, level_unit, signal_start_missing, signal_end_missing, pulse_width, frequency_shift_or_bandwidth, pulse_level_or_pulse_field_strength, region_of_interest, azimuth_confidence, modulation, sector, polarity, df_quality, elevation, azimuth, channel): r""" I return an instance of an Pulse Data word. :param time_of_arrival: nanoseconds since 1970-01-01 00:00:00 :type time_of_arrival: Integer :param pdw_format: format code :type pdw_format: Integer :param center_frequency: center frequency in KHz :type center_frequency: Integer :param is_valid: flag to mark if pdw data body is valid :type is_valid: Boolean :param is_pulse: flag to mark if pdw data body contains a pulse or a continuous wave signal :type is_pulse: Boolean :param level_unit: 0 means dBµV - 1 means dBµV/m :type level_unit: Integer :param signal_start_missing: signal started before time of arrival :type signal_start_missing: Boolean :param signal_end_missing: signal stops after time of arrival :type signal_end_missing: Boolean :param pulse_width: pulse width in nanoseconds - Zero if no valid pulse detected :type pulse_width: Integer :param frequency_shift_or_bandwidth: Value in KHz - Value set to 1048575 means Unknown :type frequency_shift_or_bandwidth: Integer :param pulse_level_or_pulse_field_strength: Pulse level or Pulse Field Strength depending on level_unit \ (-200.0...200.0) in 0.1 steps / minus 204.8 means no valid level detected :type pulse_level_or_pulse_field_strength: Float :param region_of_interest: Marks if signal is from region of interest :type region_of_interest: Boolean :param azimuth_confidence: degree in steps of 0.1 (0.0-6.2) / 6.3 means confidence unknown :type azimuth_confidence: Float :param modulation: type of modulation (e.g. PSK-2, PSK-4, FM etc.) :type modulation: String :param sector: reference antenna sector (0-15) :type sector: Integer :param polarity: Horizontal, Vertical, Clockwise, Counter clockwise :type polarity: String :param df_quality: Direction finding quality in percent (0-100) - Zero means unknown :type df_quality: Integer :param elevation: elevation of incoming signal (from -90 to 90 degree) in steps of 0.1 degree \ minus 102.4 means unknown :type elevation: Float :param azimuth: azimuth of incoming signal (from 0 to 359.9 degree) in steps of 0.1 degree \ plus 409.5 means unknown :type azimuth: Float :param channel: detecting channel (0-16) - Zero means unknown :type channel: Integer :return: An instance of class PDW with attributes set according to the data of a data body :rtype: PDW """ self.time_of_arrival = time_of_arrival # self.pdw_format_identifier = pdw_format_identifier self.center_frequency = center_frequency # self.__is_valid = is_valid # self.is_pulse = is_pulse # self.level_unit = level_unit # self.signal_start_missing = signal_start_missing self.signal_end_missing = signal_end_missing self.pulse_width = pulse_width # self.frequency_shift_or_bandwidth = frequency_shift_or_bandwidth # self.pulse_level_or_pulse_field_strength = pulse_level_or_pulse_field_strength # self.region_of_interest = region_of_interest self.azimuth_confidence = azimuth_confidence self.modulation = modulation # self.sector = sector self.polarity = polarity self.df_quality = df_quality # self.elevation = elevation # self.azimuth = azimuth self.channel = channel # def __str__(self): """ I return the string representation of myself. :rtype: str """ output = ("Time of arrival: " + str(self.time_of_arrival) + "\n" + "PDW Format identifier: " + str(self.pdw_format_identifier) + "\n" + "Center frequency: " + str(self.center_frequency) + " KHz\n") if self.__is_valid: output += "Signal: Valid\n" else: output += "Signal: Invalid\n" if self.is_pulse: output += "Signal type: Pulse\n" else: output += "Signal type: Continuous wave\n" if self.level_unit == 1: output += "Pulse level: " + str(self.pulse_level_or_pulse_field_strength) + " dbµV\n" else: output += "Pulse field strength: " + str(self.pulse_level_or_pulse_field_strength) + " dbµV/meter\n" output += ("Pulse width: " + str(self.pulse_width) + " nanoseconds\n" + "Frequency shift or bandwidth: " + str(self.frequency_shift_or_bandwidth) + " KHz\n") if self.region_of_interest: output += "Region of interest: Yes\n" else: output += "Region of interest: No\n" if self.azimuth_confidence == 6.3: output += "Azimuth confidence: Invalid\n" else: output += "Azimuth confidence: " + str(self.azimuth_confidence) + " degree\n" output += "Modulation: " + str(self.modulation) + "\n" if self.sector == 0: output += "Sector: Unknown\n" else: output += "Sector:" + str(self.sector) + "\n" output += "Polarity: " + str(self.polarity) + "\n" output += "DF quality: " + str(self.df_quality) + " %\n" if self.elevation == 1024: output += "Elevation: Unknown\n" else: output += "Elevation: " + str(self.elevation) + " degree\n" if self.azimuth == 409.5: output += "Azimuth: Unknown\n" else: output += "Azimuth: " + str(self.azimuth) + " degree\n" output += "Channel: " + str(self.channel) + "\n" return output def is_valid(self): return self.__is_valid def to_json(self): return {'time of arrival': self.time_of_arrival, 'FORMATIDENTIFIER': self.pdw_format_identifier, 'center frequency': self.center_frequency, 'VALID': self.__is_valid, 'PULSE': self.is_pulse, 'PULSELEVEL': self.pulse_level_or_pulse_field_strength, 'PULSEWIDTH': self.pulse_width, 'BANDWIDTH': self.frequency_shift_or_bandwidth, 'REGIONOFINTEREST': self.region_of_interest, 'AZIMUTHCONFIDENCE': self.azimuth_confidence, 'MODULATION': self.modulation, 'SECTOR': self.sector, 'POLARITY': self.polarity, 'DFQUALITY': self.df_quality, 'ELEVATION': self.elevation, 'AZIMUTH': self.azimuth, 'CHANNEL': self.channel }
Static methods
def from_bytes(byte_string)
-
I create an instance of class PDW from data body (8 * 32 bits).
:param byte_string: a byte string containing a single data body read from a ppdw file :type byte_string: byte string
:return: an instance of class PDW with attributes set according to the data of a data body :rtype: PDW
Expand source code
@classmethod def from_bytes(cls, byte_string): """ I create an instance of class PDW from data body (8 * 32 bits). :param byte_string: a byte string containing a single data body read from a ppdw file :type byte_string: byte string :return: an instance of class PDW with attributes set according to the data of a data body :rtype: PDW """ assert(len(byte_string) == 32) parts = struct.unpack('<Q4s4s4s4s4s4s', byte_string) nanoseconds = (parts[0]) time_of_arrival = np.datetime64(nanoseconds, 'ns') third_entry = bin(int.from_bytes(parts[1], byteorder='little')) padding = 32-len(str(third_entry)[2:]) third_entry_bit_string = "0" * padding + str(third_entry)[2:] pdw_format_identifier = int(third_entry_bit_string[0:6], 2) center_frequency = int(third_entry_bit_string[5:32], 2) fourth_entry = bin(int.from_bytes(parts[2], byteorder='little')) padding = 32-len(str(fourth_entry)[2:]) fourth_entry_bit_string = "0" * padding + str(fourth_entry)[2:] is_valid = bool(int(fourth_entry_bit_string[0])) is_pulse = bool(int(fourth_entry_bit_string[1])) level_unit = int(fourth_entry_bit_string[2]) signal_start_missing = bool(int(fourth_entry_bit_string[3])) signal_end_missing = bool(int(fourth_entry_bit_string[4])) pulse_width = int(fourth_entry_bit_string[7:33], 2) fifth_entry = bin(int.from_bytes(parts[3], byteorder='little')) padding = 32-len(str(fifth_entry)[2:]) fifth_entry_bit_string = "0" * padding + str(fifth_entry)[2:] frequency_shift_or_bandwidth = int(fifth_entry_bit_string[0:20], 2) # FIXME: You have to scale me to the range from -200.0 to 200.0 in 0.1 steps pulse_level_or_pulse_field_strength = math.ceil(int(fifth_entry_bit_string[20:32], 2)) / 10 sixth_entry = bin(int.from_bytes(parts[4], byteorder='little')) padding = 32-len(str(sixth_entry)[2:]) sixth_entry_bit_string = "0" * padding + str(sixth_entry)[2:] region_of_interest = bool(int(sixth_entry_bit_string[0])) # FIXME: You have to scale me to a range from 0.0 to 6.2 in steps of 0.1 - 6.3 means unknown azimuth_confidence = math.ceil(int(sixth_entry_bit_string[1:7], 2)) / 10 modulations = {0: 'Unknown', 1: 'Unmodulated', 2: 'FM', 3: 'LFM', 4: 'PSK-2', 5: 'PSK-3', 6: 'PSK-4', 7: 'PSK-m', 8: 'NLFM', 9: 'SFM', 10: 'TFM', 11: 'Pulse too short'} modulation = modulations[int(sixth_entry_bit_string[7:12], 2)] sector = int(sixth_entry_bit_string[28:32], 2) seventh_entry = bin(int.from_bytes(parts[5], byteorder='little')) padding = 32-len(str(seventh_entry)[2:]) seventh_entry_bit_string = "0" * padding + str(seventh_entry)[2:] polarities = {0: 'Horizontal/Unknown', 1: 'Vertical', 2: 'Counter clockwise', 3: 'Clockwise'} polarity = polarities[int(seventh_entry_bit_string[0:2], 2)] df_quality = int(seventh_entry_bit_string[2:9], 2) # FIXME: You have to scale me from -90 to 90 in 0.1 degree steps elevation = int(seventh_entry_bit_string[9:20], 2) # FIXME: You have to check me for a range from 0.0 to 359.9 in steps of 0.1 azimuth = 0.1 * (int(seventh_entry_bit_string[20:32], 2)) eighth_entry = bin(int.from_bytes(parts[5], byteorder='little')) padding = 32-len(str(eighth_entry)[2:]) eighth_entry_bit_string = "0" * padding + str(eighth_entry)[2:] channel = int(eighth_entry_bit_string[0:4], 2) return PDW(time_of_arrival, pdw_format_identifier, center_frequency, is_valid, is_pulse, level_unit, signal_start_missing, signal_end_missing, pulse_width, frequency_shift_or_bandwidth, pulse_level_or_pulse_field_strength, region_of_interest, azimuth_confidence, modulation, sector, polarity, df_quality, elevation, azimuth, channel)
Methods
def is_valid(self)
-
Expand source code
def is_valid(self): return self.__is_valid
def to_json(self)
-
Expand source code
def to_json(self): return {'time of arrival': self.time_of_arrival, 'FORMATIDENTIFIER': self.pdw_format_identifier, 'center frequency': self.center_frequency, 'VALID': self.__is_valid, 'PULSE': self.is_pulse, 'PULSELEVEL': self.pulse_level_or_pulse_field_strength, 'PULSEWIDTH': self.pulse_width, 'BANDWIDTH': self.frequency_shift_or_bandwidth, 'REGIONOFINTEREST': self.region_of_interest, 'AZIMUTHCONFIDENCE': self.azimuth_confidence, 'MODULATION': self.modulation, 'SECTOR': self.sector, 'POLARITY': self.polarity, 'DFQUALITY': self.df_quality, 'ELEVATION': self.elevation, 'AZIMUTH': self.azimuth, 'CHANNEL': self.channel }