Skip to content

Commit

Permalink
absolute imports, formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
zacharyburnett committed Apr 17, 2021
1 parent e99eeda commit f6d5717
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 77 deletions.
2 changes: 1 addition & 1 deletion packetraven/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .connections import APRSDatabaseTable, APRSfi, RawAPRSTextFile, SerialTNC
from packetraven.connections import APRSDatabaseTable, APRSfi, RawAPRSTextFile, SerialTNC
48 changes: 31 additions & 17 deletions packetraven/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,22 @@
from dateutil.parser import parse as parse_date
import numpy

from .base import PacketSource
from .connections import APRSDatabaseTable, APRSfi, APRSis, PacketDatabaseTable, PacketGeoJSON, RawAPRSTextFile, SerialTNC, \
TimeIntervalError
from .packets import APRSPacket
from .predicts import PredictionAPIURL, PredictionError, get_predictions
from .tracks import APRSTrack, LocationPacketTrack
from .utilities import get_logger, read_configuration, repository_root
from .writer import write_packet_tracks
from packetraven.base import PacketSource
from packetraven.connections import (
APRSDatabaseTable,
APRSfi,
APRSis,
PacketDatabaseTable,
PacketGeoJSON,
RawAPRSTextFile,
SerialTNC,
TimeIntervalError,
)
from packetraven.packets import APRSPacket
from packetraven.predicts import PredictionAPIURL, PredictionError, get_predictions
from packetraven.tracks import APRSTrack, LocationPacketTrack
from packetraven.utilities import get_logger, read_configuration, repository_root
from packetraven.writer import write_packet_tracks

LOGGER = get_logger('packetraven')

Expand Down Expand Up @@ -48,7 +56,8 @@ def main():
args_parser.add_argument('--log', help='path to log file to save log messages')
args_parser.add_argument('--output', help='path to output file to save packets')
args_parser.add_argument(
'--prediction-output', help='path to output file to save most up-to-date predicted trajectory'
'--prediction-output',
help='path to output file to save most up-to-date predicted trajectory',
)
args_parser.add_argument(
'--prediction-ascent-rate', help='ascent rate to use for prediction (m/s)'
Expand All @@ -62,9 +71,7 @@ def main():
args_parser.add_argument(
'--prediction-float-altitude', help='float altitude to use for prediction (m)'
)
args_parser.add_argument(
'--prediction-float-duration', help='duration of float (s)'
)
args_parser.add_argument('--prediction-float-duration', help='duration of float (s)')
args_parser.add_argument(
'--prediction-api',
help=f'API URL to use for prediction (one of {[entry.value for entry in PredictionAPIURL]})',
Expand Down Expand Up @@ -187,7 +194,9 @@ def main():
kwargs['prediction_float_altitude'] = float(args.prediction_float_altitude)

if args.prediction_float_duration is not None:
kwargs['prediction_float_duration'] = timedelta(seconds=float(args.prediction_float_duration))
kwargs['prediction_float_duration'] = timedelta(
seconds=float(args.prediction_float_duration)
)

if args.prediction_api is not None:
kwargs['prediction_api_url'] = args.prediction_api
Expand Down Expand Up @@ -311,9 +320,12 @@ def main():
database_kwargs['database_password'] = database_password

database = APRSDatabaseTable(
**{key.replace('database_', ''): value
for key, value in database_kwargs.items()},
**ssh_tunnel_kwargs, callsigns=callsigns
**{
key.replace('database_', ''): value
for key, value in database_kwargs.items()
},
**ssh_tunnel_kwargs,
callsigns=callsigns,
)
LOGGER.info(f'connected to {database.location}')
connections.append(database)
Expand Down Expand Up @@ -495,7 +507,9 @@ def retrieve_packets(
)

if packet_track.time_to_ground >= timedelta(seconds=0):
current_time_to_ground = packet_time + packet_track.time_to_ground - current_time
current_time_to_ground = (
packet_time + packet_track.time_to_ground - current_time
)
message += (
f'; {packet_track} descending from max altitude of {packet_track.coordinates[:, 2].max():.3f} m'
f'; {current_time_to_ground / timedelta(seconds=1):.2f} s to the ground'
Expand Down
2 changes: 1 addition & 1 deletion packetraven/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import requests
from serial.tools import list_ports

from .packets import APRSPacket, LocationPacket
from packetraven.packets import APRSPacket, LocationPacket


class Connection(ABC):
Expand Down
10 changes: 6 additions & 4 deletions packetraven/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
from tablecrow import PostGresTable
from tablecrow.utilities import split_hostname_port

from packetraven.packets import APRSPacket, LocationPacket
from packetraven.parsing import InvalidPacketError
from packetraven.utilities import get_logger, read_configuration, repository_root
from .base import (
APRSPacketSink,
APRSPacketSource,
Expand All @@ -22,9 +25,6 @@
PacketSource,
next_open_serial_port,
)
from .packets import APRSPacket, LocationPacket
from .parsing import InvalidPacketError
from .utilities import get_logger, read_configuration, repository_root

LOGGER = get_logger('connection')

Expand Down Expand Up @@ -458,7 +458,9 @@ def __init__(
kwargs['fields'] = {
f'packet_{field}': field_type for field, field_type in kwargs['fields'].items()
}
PacketDatabaseTable.__init__(self, hostname=hostname, database=database, table=table, **kwargs)
PacketDatabaseTable.__init__(
self, hostname=hostname, database=database, table=table, **kwargs
)
location = f'postgres://{self.hostname}:{self.port}/{self.database}/{self.name}'
APRSPacketSource.__init__(self, location, callsigns)
APRSPacketSink.__init__(self, location)
Expand Down
31 changes: 16 additions & 15 deletions packetraven/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
from dateutil.parser import parse
import numpy

from . import APRSDatabaseTable, APRSfi, RawAPRSTextFile, SerialTNC
from .__main__ import DEFAULT_INTERVAL_SECONDS, LOGGER, retrieve_packets
from .base import available_serial_ports, next_open_serial_port
from .connections import APRSis, PacketGeoJSON
from .plotting import LivePlot
from .predicts import PredictionError, get_predictions
from .tracks import LocationPacketTrack, PredictedTrajectory
from .utilities import get_logger
from .writer import write_packet_tracks
from packetraven import APRSDatabaseTable, APRSfi, RawAPRSTextFile, SerialTNC
from packetraven.__main__ import DEFAULT_INTERVAL_SECONDS, LOGGER, retrieve_packets
from packetraven.base import available_serial_ports, next_open_serial_port
from packetraven.connections import APRSis, PacketGeoJSON
from packetraven.plotting import LivePlot
from packetraven.predicts import PredictionError, get_predictions
from packetraven.tracks import LocationPacketTrack, PredictedTrajectory
from packetraven.utilities import get_logger
from packetraven.writer import write_packet_tracks


class PacketRavenGUI:
Expand Down Expand Up @@ -705,7 +705,8 @@ def toggle(self):
self.tncs = [
connection.location
for connection in self.__connections
if isinstance(connection, SerialTNC) or isinstance(connection, RawAPRSTextFile)
if isinstance(connection, SerialTNC)
or isinstance(connection, RawAPRSTextFile)
]

api_key = self.__configuration['aprs_fi']['aprs_fi_key']
Expand Down Expand Up @@ -767,7 +768,10 @@ def toggle(self):
raise ConnectionError('missing SSH password')
ssh_tunnel_kwargs['ssh_password'] = password

database_kwargs = {key.replace('database_', ''): value for key, value in self.__configuration['database'].items()}
database_kwargs = {
key.replace('database_', ''): value
for key, value in self.__configuration['database'].items()
}
if (
'username' not in database_kwargs
or database_kwargs['username'] is None
Expand Down Expand Up @@ -797,10 +801,7 @@ def toggle(self):
if database_password is None or len(database_password) == 0:
raise ConnectionError('missing database password')
database_kwargs['password'] = database_password
if (
'table' not in database_kwargs
or database_kwargs['table'] is None
):
if 'table' not in database_kwargs or database_kwargs['table'] is None:
database_table = simpledialog.askstring(
'Database Table',
f'enter database table name',
Expand Down
2 changes: 1 addition & 1 deletion packetraven/packets.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy
from pyproj import CRS, Geod, Transformer

from .parsing import InvalidPacketError, parse_raw_aprs
from packetraven.parsing import InvalidPacketError, parse_raw_aprs

DEFAULT_CRS = CRS.from_epsg(4326)

Expand Down
2 changes: 1 addition & 1 deletion packetraven/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from matplotlib.axes import Axes
from matplotlib.figure import Figure

from .tracks import LocationPacketTrack, PredictedTrajectory
from packetraven.tracks import LocationPacketTrack, PredictedTrajectory

VARIABLES = {
'altitude': {'x': 'times', 'y': 'altitudes', 'xlabel': 'time', 'ylabel': 'altitude (m)'},
Expand Down
35 changes: 26 additions & 9 deletions packetraven/predicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import requests
from shapely.geometry import Point

from .packets import LocationPacket
from .tracks import LocationPacketTrack, PredictedTrajectory
from .utilities import get_logger
from packetraven.packets import LocationPacket
from packetraven.tracks import LocationPacketTrack, PredictedTrajectory
from packetraven.utilities import get_logger

DEFAULT_ASCENT_RATE = 5.5
DEFAULT_BURST_ALTITUDE = 28000
Expand Down Expand Up @@ -71,7 +71,10 @@ def __init__(
launch_time = UTC_TIMEZONE.localize(launch_time)

if float_end_time is not None:
if float_end_time.tzinfo is None or float_end_time.tzinfo.utcoffset(float_end_time) is None:
if (
float_end_time.tzinfo is None
or float_end_time.tzinfo.utcoffset(float_end_time) is None
):
float_end_time = UTC_TIMEZONE.localize(float_end_time)

self.api_url = api_url
Expand Down Expand Up @@ -131,7 +134,10 @@ def __init__(
profile = FlightProfile.standard

if dataset_time is not None:
if dataset_time.tzinfo is None or dataset_time.tzinfo.utcoffset(dataset_time) is None:
if (
dataset_time.tzinfo is None
or dataset_time.tzinfo.utcoffset(dataset_time) is None
):
dataset_time = UTC_TIMEZONE.localize(dataset_time)

if api_url is None:
Expand Down Expand Up @@ -219,7 +225,11 @@ def get(self) -> {str: Any}:
raise PredictionError('API did not return a float trajectory')

standard_profile_query = self.__class__(
launch_site=[float_end['longitude'], float_end['latitude'], float_end['altitude']],
launch_site=[
float_end['longitude'],
float_end['latitude'],
float_end['altitude'],
],
launch_time=parse_date(float_end['datetime']),
ascent_rate=10,
burst_altitude=float_end['altitude'] + 0.1,
Expand Down Expand Up @@ -410,12 +420,19 @@ def get_predictions(
prediction_start_time = packet_track[-1].time

if float_altitude is not None and not packet_track.falling:
packets_at_float_altitude = packet_track[numpy.abs(float_altitude - packet_track.altitudes) < float_altitude_uncertainty]
if len(packets_at_float_altitude) > 0 and packets_at_float_altitude[-1].time == packet_track.times[-1]:
packets_at_float_altitude = packet_track[
numpy.abs(float_altitude - packet_track.altitudes) < float_altitude_uncertainty
]
if (
len(packets_at_float_altitude) > 0
and packets_at_float_altitude[-1].time == packet_track.times[-1]
):
float_start_time = packets_at_float_altitude[0].time
descent_only = False
elif packet_track.ascent_rates[-1] >= 0:
float_start_time = prediction_start_time + timedelta(seconds=(float_altitude - prediction_start_location[2]) / ascent_rate)
float_start_time = prediction_start_time + timedelta(
seconds=(float_altitude - prediction_start_location[2]) / ascent_rate
)
descent_only = False
else:
float_start_time = None
Expand Down
4 changes: 3 additions & 1 deletion packetraven/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ def __getitem__(self, index: Union[int, Iterable[int], slice]) -> Union[Any, Lis
elif isinstance(index, Iterable):
return self.__class__([self.__getitem__(value) for value in index])
elif isinstance(index, slice):
slice_parameters = [value for value in (index.start, index.stop, index.step) if value is not None]
slice_parameters = [
value for value in (index.start, index.stop, index.step) if value is not None
]
if all(slice_parameter is None for slice_parameter in slice_parameters):
return self
else:
Expand Down
50 changes: 31 additions & 19 deletions packetraven/tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
from pandas import DataFrame
from pyproj import CRS

from .model import FREEFALL_DESCENT_RATE, FREEFALL_DESCENT_RATE_UNCERTAINTY, FREEFALL_SECONDS_TO_GROUND
from .packets import APRSPacket, DEFAULT_CRS, LocationPacket
from .structures import DoublyLinkedList
from packetraven.model import (
FREEFALL_DESCENT_RATE,
FREEFALL_DESCENT_RATE_UNCERTAINTY,
FREEFALL_SECONDS_TO_GROUND,
)
from packetraven.packets import APRSPacket, DEFAULT_CRS, LocationPacket
from packetraven.structures import DoublyLinkedList


class LocationPacketTrack:
Expand Down Expand Up @@ -145,7 +149,9 @@ def length(self) -> float:
""" total length of the packet track over the ground """
return sum([distance.overground for distance in self.packets.difference])

def __getitem__(self, index: Union[int, Iterable[int], slice]) -> Union[LocationPacket, 'LocationPacketTrack']:
def __getitem__(
self, index: Union[int, Iterable[int], slice]
) -> Union[LocationPacket, 'LocationPacketTrack']:
if isinstance(index, int):
return self.packets[index]
elif isinstance(index, Iterable) or isinstance(index, slice):
Expand Down Expand Up @@ -179,19 +185,21 @@ def __str__(self) -> str:

@property
def dataframe(self) -> DataFrame:
return DataFrame({
'name': [self.name for _ in range(len(self))],
'times': self.times,
'x': self.coordinates[:, 0],
'y': self.coordinates[:, 1],
'z': self.coordinates[:, 2],
'intervals': self.intervals,
'overground_distances': self.overground_distances,
'ascents': self.ascents,
'ascent_rates': self.ascent_rates,
'ground_speeds': self.ground_speeds,
'cumulative_overground_distances': self.cumulative_overground_distances,
})
return DataFrame(
{
'name': [self.name for _ in range(len(self))],
'times': self.times,
'x': self.coordinates[:, 0],
'y': self.coordinates[:, 1],
'z': self.coordinates[:, 2],
'intervals': self.intervals,
'overground_distances': self.overground_distances,
'ascents': self.ascents,
'ascent_rates': self.ascent_rates,
'ground_speeds': self.ground_speeds,
'cumulative_overground_distances': self.cumulative_overground_distances,
}
)


class BalloonTrack(LocationPacketTrack):
Expand Down Expand Up @@ -220,8 +228,12 @@ def falling(self) -> bool:
elif not self.__falling:
current_altitude = self.altitudes[-1]
freefall_descent_rate = FREEFALL_DESCENT_RATE(current_altitude)
freefall_descent_rate_uncertainty = FREEFALL_DESCENT_RATE_UNCERTAINTY(current_altitude)
if numpy.abs(current_ascent_rate - freefall_descent_rate) < numpy.abs(freefall_descent_rate_uncertainty):
freefall_descent_rate_uncertainty = FREEFALL_DESCENT_RATE_UNCERTAINTY(
current_altitude
)
if numpy.abs(current_ascent_rate - freefall_descent_rate) < numpy.abs(
freefall_descent_rate_uncertainty
):
self.__falling = True
return self.__falling

Expand Down
4 changes: 2 additions & 2 deletions packetraven/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import numpy
from shapely.geometry import LineString

from .packets import APRSPacket
from .tracks import APRSTrack, LocationPacketTrack
from packetraven.packets import APRSPacket
from packetraven.tracks import APRSTrack, LocationPacketTrack

KML_STANDARD = '{http://www.opengis.net/kml/2.2}'

Expand Down
Loading

0 comments on commit f6d5717

Please sign in to comment.