pytheas package#
Submodules#
pytheas.boat module#
The Boat class of Pytheas.
It represents a boat - a logboat, a plank canoe, a longship - you name it. In the Agent-Based Modelling framework, the Boat represents a basic Agent.
- class pytheas.boat.Boat(craft: str, latitude: float, longitude: float, target: Tuple[float, float], land_radar_on: bool = True, uncertainty_sigma: float = 0.0, speed_polar_diagram: DataFrame | None = None, leeway_polar_diagram: DataFrame | None = None, route_to_take: List[float] | None = None)#
Bases:
object
Base class for a Boat in Pytheas.
- craft#
Name or type of boat.
- Type:
str
- latitude#
Latitude at which the boat is.
- Type:
float
- longitude#
Longitude at which the boat is.
- Type:
float
- target#
Lat/Lon of the target landing site.
- Type:
Tuple[float, float]
- land_radar_on#
Whether the land radar algorithm acts or not.
- Type:
bool
- uncertainty_sigma#
standard deviation of the navigation error.
- Type:
float
- speed_polar_diagram#
Table representing the boat speed polar diagram.
- Type:
pd.DataFrame
- leeway_polar_diagram#
Table representing the boat leeway polar diagram.
- Type:
pd.DataFrame
- route_to_take#
List of lat/lon coordinates that the boat has to follow to get to target.
- Type:
List[float]
- trajectory#
List of lat/lon keeping track of the trajectory of the boat.
- Type:
List[float]
- distance#
Distance (in km) covered by the boat so far.
- Type:
float
- bearing#
Current angle between launching site and target.
- Type:
float)
- nominal_bearings#
list of all the direction that the crew takes to reach the target.
- Type:
List[float]
- modified_bearings#
list of the actual bearings that the boat takes during the trip, after accounting for currents and land avoidance.
- Type:
List[float]
- has_hit_land#
Boolean to record if the boat hits land before the end of the trip.
- Type:
bool
- calculate_displacement(local_winds: ndarray, local_currents: ndarray, bearing: float, timestep: int) ndarray #
Function to calculate the displacement in km of a boat from its current position given winds, currents and bearing.
- Parameters:
local_winds (np.ndarray) – array containing speed and direction of the wind in the local position.
local_currents (np.ndarray) – array containing Eastward (x) and Northward (y) speed of currents in the local position.
bearing (float) – bearing taken by the boat.
- Returns:
array containing Eastward and Northward displacement of the boat from current position.
- Return type:
np.ndarray
- generic_displacement(local_winds: ndarray, local_currents: ndarray, bearing_xy: ndarray)#
- leeway_due_to_wind(current_winds: ndarray, bearing: float)#
Calculates the leeway due to wind according to a polar diagram, when existing.
- Parameters:
current_winds (np.ndarray) – Wind velocity (two components)
bearing_xy (np.ndarray) – bearing of the boat split in x, y components
- Raises:
ValueError – Raised if the angle between the bearing and reference is a non-positive number
ValueError – Raised if the speed of the wind is higher than 30
- Returns:
- geographic angle of leeway due to the wind to be added to the bearing to obtain the real angle
at which the boat travels, in degrees
- Return type:
leeway_angle
- move_boat(landmarks: Tuple[float, float], local_winds: ndarray, local_currents: ndarray, timestep: int, accepted_distance_from_target: float = 1)#
Function tha determines the movement of a boat at each time step. It runs from Travel.
- Parameters:
(Tuple[float (landmarks) – List containing the distance to the closest land (in km) and the direction to the closest land (in degrees)).
float] – List containing the distance to the closest land (in km) and the direction to the closest land (in degrees)).
local_winds (np.ndarray) – Array containing the speed and geographic angle of the wind.
local_currents (np.ndarray) – Array containing Northward and Eastward components of sea currents speed.
timestep (int) – Time step between steps of movement, in minutes.
acceted_distance_from_target (float) – Distance from target that does not trigger stirring away from land (if target is not distant, the boat should keep going towards it, not stir away.)
- plot_trajectory(bbox: Tuple[float, float, float, float]) None #
Quick trajectory plot utility, to show a simulated trajectory.
- Parameters:
bbox (Tuple[float, float, float, float]) – list containing [min latitude, min longitude, max latitude, max longitude] for map plotting.
- speed_due_to_wind(current_winds: ndarray, bearing: float)#
Calculate the combined speed of paddling with the effect of the wind according to a polar diagram, when existing.
- Parameters:
current_winds (np.ndarray) – Wind velocity (two components), 0-element is speed in m/s, 1-element is direction in degrees.
bearing_xy (np.ndarray) – Bearing of the boat split in x, y components.
- Raises:
ValueError – Raised if the angle between the bearing and reference is a non-positive number.
ValueError – Raised if the speed of the wind is higher than 30.
- Returns:
Speed in m/s of the paddling crew.
- Return type:
speed (float)
pytheas.map module#
The map object of Pytheas.
It represents the space over which the Boat will travel. It is a continuous space where we super impose three distinct layers of data: winds, currents and waves. The wind and current layers directly affect the movement of the boat, while the wave layer is necessary to record encountered waves. In the Agent-Based Modelling framework, the Map corresponds to the Space.
- class pytheas.map.Map(bounding_box: Tuple[float, float, float, float], earliest_time: Timestamp, latest_time: Timestamp, wind_data_path: str, current_data_path: str, waves_data_path: str)#
Bases:
object
The base Map object in Pytheas.
- bounding_box#
Bounding box including [min_latitude, min_longitude, max_latitude, max_longitude].
- Type:
List[float, float, float, float]
- earliest_time#
Earliest time included in the Map dataset.
- Type:
pd.Timestamp
- latest_time#
Latest time included in the Map dataset.
- Type:
pd.Timestamp
- wind_path#
Folder where the wind data are stored.
- Type:
str
- current_path#
Folder where the current data are stored.
- Type:
str
- waves_path#
Folder where the waves data are stored.
- Type:
str
- winds_data#
Data array containing winds data (each point has component speed in m/s and angle in degrees).
- Type:
xr.DataArray
- currents_data#
Data array containing currents data (each point is speed in x/y - both m/s).
- Type:
xr.DataArray
- waves_data#
Data array containing waves height data (each point is wave height in meters).
- Type:
xr.DataArray
- create_route(launching_site: Tuple[float, float], landing_site: Tuple[float, float], target_interval: int = 5, **kwargs)#
Create a route that hugs the coast from a launching site to a landing site. The kwargs need to be weights (a list) and iterations (also a list, of the same length as weights) to modify the creation of different “weight corridors” along the shoreline.
- Parameters:
launching_site (Tuple[float, float]) – Launching site in lat/lon format.
landing_site (Tuple[float, float]) – Landing site in in lat/lon format.
target_interval (int) – Interval between the nodes in the route. Defaults to 5.
- Raises:
RuntimeError – Raised if the algorithm was unable to find a route.
- Returns:
List of coordinates through which the routes goes.
- Return type:
List[Tuple[float, float]]
- find_closest_land(position_on_water: Tuple[float, float], radar_radius: float = 0.2) Tuple[float, float] #
Find land closest to a point in water.
- Parameters:
position_on_water (Tuple[float, float]) – Position on the water in latitude / longitude.
radar_radius (float, optional) – Radius within which to look for land, in degrees. Defaults to 0.2 degrees.
- Returns:
Distance from closest land and angle to closest land.
- Return type:
Tuple[float, float]
- find_closest_water(position_on_land: Tuple[float, float], radar_radius: float = 10) Tuple[float, float] #
Find coordinates in water closest to a point on land.
- Parameters:
position_on_land (Tuple[float, float]) – Position on land in lon/lat format.
radar_radius (float, optional) – Radius within which to look for water, in degrees. Defaults to 10 degrees.
- Returns:
Lat/lon of closest point.
- Return type:
Tuple[float, float]
- find_nearest_index_to_point(point: Tuple[float, float]) Tuple[int, int] #
Find the index of the latitude/longitude in the data closest to a given point.
- Parameters:
point (Tuple[float, float]) – A geographical point in lat/lon format.
- Returns:
x index and y index of closest coordinate in the data to a given point.
- Return type:
Tuple[int, int]
- load_dataset_currents() DataArray #
Load the dataset for currents in xarray’s DataArray format.
- Returns:
Data array containing the currents data.
- Return type:
xr.DataArray
- load_dataset_waves()#
Load the dataset for waves in xarray’s DataArray format.
- Returns:
Data array containing the waves data.
- Return type:
xr.DataArray
- load_dataset_winds() DataArray #
Load the dataset for winds in xarray’s DataArray format.
- Returns:
Data array containing the winds data.
- Return type:
xr.DataArray
- return_local_currents(location: ndarray, time: Timestamp, average: bool = True, radius: float = 0.075) ndarray #
Return horizontal and vertical components of current speed at a location and a time. Currents are measured in a square of +/-0.075 degrees around the location, and an average of all the values found in that “radius” is output. The radius is chosen based on the grid size for the ECMWF dataset (~5.5 x 5.5 km). The value of 0.075 has been found with trial and error.
- Parameters:
location (np.ndarray) – Array of latitude and longitude of a location.
time (pd.Timestamp) – Timestamp of time at which one wants the measure.
radius (float, optional) – “Square” radius around which the measure of wind datapoints is performed. Defaults to 0.02.
- Returns:
An array containing horizontal (Eastward) and vertical (Northward) component of the currents speed.
- Return type:
np.ndarray
- return_local_waves(location: ndarray, time: Timestamp, radius: float = 0.2) float #
Return wave height at a location and a time. Waves are measured in a square of +/-0.2 degrees around the location, and an average of all the values found in that “radius” is output. The radius is chosen based on the grid size for the ECMWF dataset (~5.5 x 5.5 km). The value of 0.2 has been found with trial and error.
- Parameters:
location (np.ndarray) – Array of latitude and longitude of a location.
time (pd.Timestamp) – Timestamp of time at which one wants the measure.
radius (float, optional) – “Square” radius around which the measure of wind datapoints is performed. Defaults to 0.05.
- Returns:
A wave height.
- Return type:
float
- return_local_winds(location: ndarray, time: Timestamp, radius: float = 0.05) ndarray #
Return wind speed and direction given a location and a time. Winds are measured in a square of +/-0.05 degrees around the location, and an average of all the values found in that radius is output. The radius is chosen based on the grid size for the CERRA dataset (~2 x 2 km). The value of 0.05 has been found with trial and error.
- Parameters:
location (np.ndarray) – Array of latitude and longitude of a location.
time (pd.Timestamp) – Timestamp of time at which one wants the measure.
radius (float, optional) – “Square” radius around which the measure of wind datapoints is performed. Defaults to 0.05.
- Returns:
An array containing wind speed (m/s) and wind direction (degrees).
- Return type:
np.ndarray
pytheas.travel module#
The Travel class of Pytheas.
It represents a travel from A to B. This class collects all the different components of the travel of a Boat from A to B on a Map. In the Agent-Based Modelling framework, it represents the Model.
- class pytheas.travel.Travel(boat: Boat, map: Map, start_day: str, max_duration: int, timestep: int, night_travel: bool = False, tolerance_distance: float = 3, twilights_of_stops: str = 'sun')#
Bases:
object
Base class for a Travel in Pytheas.
- Attr:
boat (Boat): The boat that will travel. map (Map): The map over which the boat will travel. max_duration (int): The maximal duration of the trip (in hours). timestep (int): Time between each step (in minutes). launching_site (Tuple[float, float]): Departure site in lat/lon format, inherited from boat. start_time (pd.Timestamp): The day and time of departure for the trip. target (Tuple[float, float]): Target landing site in lat/lon format, inherited from boat. night_travel (bool): Whether the boat is stops for night or not. twilight_of_stops (str): Determines whether tips start and end at sunrise or twilight. Options are “sun” (sunrise), “civil”, “nautical” and “astronomical”. current_time (pd.Timestamp): Keeps track of the current time in the travel. is_completed (bool): Marks whether the travel is completed within tolerance. tolerance (float): Tolerance distance from target to be considered “arrived” (in km). Defaults to 3 km, a distance within which a boat travelling at 3 m/s can travel in 15 minutes. encountered_currents (List): List of tuples (x, y) of currents encountered on the travel. encountered_winds (List): List of tuples (speed, angle) of winds encountered on the travel. encountered_waves (List[float]): List of wave heights encountered on the travel. times_of_stops (List[pd.Timestamp]): List of times at which stops for night were initiated. It gets populated only if night_travel = True. stop_coords (List): List of lat/lon points at which the boat stopped for night.
- append_to_aggregates(output_path: str, radius_for_success: float = 5) None #
- output_geojson(output_path: str) dict #
Save GeoJSON file of the travel and return it.
- Parameters:
output_path (str) – filepath for output.
- Returns:
GeoJSON of the travel containing various data.
- Return type:
dict
- run(verbose: bool = False) None #
Run the travel from the launching site to the target landing site or until it hits land.
- Parameters:
verbose (bool) – Boolean determining whether to print a final short summary of the trip.
- step() None #
Advance the travel by one step.
pytheas.search module#
Searching algorithms. This module is copied from Voyager. It was developed by Victor Wåhlstrand Skärström (@waahlstrand on Github).
This script contains tools to calculate paths and routes through a simulation.
- This file can be imported as module and contains the following functions:
heuristic - Generic measure between two positions
- And the following classes:
Grid - represents the map as an approximately equidistant grid
WeightedGrid - inherits from Grid, used to symbolize a map where not all positions are equally likely to traverse
PriorityQueue - used in A-star algorithm to deal with queues and stacking
Astar - implementation of A-star algorithm
- class pytheas.search.Astar(graph: WeightedGrid)#
Bases:
object
Implementation of A-star algorithm (see e.g. https://en.wikipedia.org/wiki/A*_search_algorithm)
- graph#
weighted graph over which to perform the search
- Type:
- search(start, goal)#
find a route from a start position to a goal position
- recontruct_path(came_from, start, goal)#
reconstruct the route from the graph pointing to previous positions.
- reconstruct_path(came_from: Dict[Tuple[int, int], Tuple[int, int]], start: Tuple[int, int], goal: Tuple[int, int]) List[Tuple[int, int]] #
Reconstruct the route from the graph pointing to previous positions.
- Parameters:
came_from (Dict[Position, Position]) – Dictionary pointing from one position to another
start (Position) – Start position
goal (Position) – End position
- Returns:
The resulting route as a list of positions
- Return type:
List[Position]
- search(start: Tuple[int, int], goal: Tuple[int, int]) Tuple[Dict[Tuple[int, int], Tuple[int, int]], Dict[Tuple[int, int], float]] #
Find a route from a start position to a goal position.
- Parameters:
start (Position) – Start position
goal (Position) – End position
- Returns:
A dict as a graph pointing to the previous position, and the current cost of the route.
- Return type:
Tuple[Dict[Position, Position], Dict[Position, float]]
- class pytheas.search.Grid(width: int, height: int)#
Bases:
object
Represents the map as an approximately equidistant grid, with methods to find if the current position is in bounds, if there are obstacles “walls”, and which are the closest places to go.
- width#
width of the grid
- Type:
int
- height#
height of the grid
- Type:
int
- walls#
walls of the map, defined as unpassable steps in the A-star algorithm
- Type:
Position
- in_bounds(id)#
Checks if the current position is in bounds
- passable(id)#
Checks if current position has any obstacles around (walls)
- neighbors(id)#
Calculates all traversable neighbors of a current position
- in_bounds(id: Tuple[int, int]) bool #
Checks if the current position is in bounds of the map.
- Parameters:
id (Position) – Current position
- Returns:
Whether position is in bounds
- Return type:
bool
- neighbors(id: Tuple[int, int]) Iterator[Tuple[int, int]] #
Calculates the traversable neighbours of the current position as an iterator
- Parameters:
id (Position) – Current position
- Returns:
A traversable neighbour to the current position
- Return type:
Position
- Yields:
Iterator[Position] – An iterator with the traversable neighbours
- passable(id: Tuple[int, int]) bool #
Checks if the current position has any obstacles, so called “walls”.
- Parameters:
id (Position) – Current position
- Returns:
Whether the position is passable, or if it has walls
- Return type:
bool
- class pytheas.search.PriorityQueue#
Bases:
object
Class to define PriorityQueue (used in Astar).
- elements#
elements a queue used to check points in A-star algorithm.
- Type:
List[Tuple[float, T]]
- empty()#
return True if self.elements is empty.
- put(item, priority)#
insert new element in priority list
- get()#
return weight for iteration step
- empty() bool #
- get() T #
- put(item: T, priority: float)#
- class pytheas.search.WeightedGrid(width: int, height: int)#
Bases:
Grid
The WeightedGrid is a Grid used to symbolize a map where not all positions are equally likely to traverse. Some are more likely, these regions being weighted.
- weights#
weights of different points of the Grid.
- weigthed_mask#
mask to superpose on Grid with weights.
- cost(from_node, to_node)#
calculate cost of movement between two points
- from_map(map, **kwargs)#
class method to generate WeightedGrid from an array where land is marked
- create_shoreline_contour(mask, weights=[5, 0.5], iterations=[1, 4], kernel_size=3)#
creates weighted shoreline contours for the map.
- mask_to_graph(mask)#
superposes mask on Grid.
- cost(from_node: Tuple[int, int], to_node: Tuple[int, int]) float #
- static create_shoreline_contour(mask: ndarray, weights=[5, 0.5], iterations=[1, 4], kernel_size=3) ndarray #
Create a weight mask corresponding to the shoreline contour of the map.
The contours are created using dilation of the land for a number of iterations and a given kernel size. The result is a contour with a specific width, which is then assigned a specific weight.
This mimics the tendency to avoid close shorelines and open sea.
- Parameters:
mask (np.ndarray) – A mask symbolizing the land
weights (list, optional) – A list of weights for each contour. Defaults to [5, 0.5].
iterations (list, optional) – Number of iterations to broaden the contour. Defaults to [1, 4].
kernel_size (int, optional) – The kernel size used for broadening of the contour. Defaults to 3.
- Returns:
A weighted array corresponding to a map with contours around the land
- Return type:
np.ndarray
- classmethod from_map(map: ndarray, **kwargs)#
Generate a WeightedGrid from a numpy array, wehere the land is symbolized as NaN.
- Parameters:
map (np.ndarray) – An array with land as NaN
- Returns:
A WeightedGrid instance
- Return type:
- static mask_to_graph(mask)#
Superposes mask on Grid. :param mask: mask with weights to be superposed on Grid. :type mask: np.ndarray
- Returns:
array with weighted Grid
- Return type:
np.ndarray
- pytheas.search.heuristic(a: Tuple[int, int], b: Tuple[int, int]) float #
Distance measure between two positions.
- Parameters:
a (Position) – Current position
b (Position) – Other position
- Returns:
A measure of the distance between the points
- Return type:
float
pytheas.utilities module#
Module containing utility functions that are not used within a particular class. These are generally functions that deal with geography, measurements and distances, or time functions, such as ephemeris functions.
- pytheas.utilities.angle_uncertainty(sigma=0) float #
Returns an angle error in radiants.
- pytheas.utilities.bearing_from_latlon(position: Tuple[float, float], target: Tuple[float, float]) float #
Gives angle between a coordinate and a target (in degrees with respect to North). Taken from Voyager.
- Parameters:
position (np.ndarray) – current position (lat/lon)
target (np.ndarray) – target position (lat/lon)
- Returns:
bearing (angle) between a position and a target in degrees
- Return type:
float
- pytheas.utilities.calculate_end_of_day(day: str, position: Tuple[float, float], type_of_twilight: str = 'sun') Timestamp #
Function to calculate at what time the sun goes down (or twilight).
- Parameters:
day (str) – date in format ‘yyyy-mm-dd’
position (Tuple[float, float]) – position at which you want to calculate the end of the day
type_of_twilight (str, optional) – whether you want to calculate sunset, civil, nautical or astronomical twilight. Defaults to ‘sun’.
- Raises:
ValueError – If ‘type_of_twilight’ is not one of ‘civil’, ‘nautical’, ‘astronomical’ or ‘sun’.
- Returns:
timestamp of date and time of end of the day.
- Return type:
pd.Timestamp
- pytheas.utilities.calculate_start_of_day(day: str, position: Tuple[float, float], type_of_twilight: str = 'sun') Timestamp #
Function to calculate at what time the sun rises (or twilight).
- Parameters:
day (str) – date in format ‘yyyy-mm-dd’
position (Tuple[float, float]) – position at which you want to calculate the start of the day, in format lon / lat
type_of_twilight (str, optional) – whether you want to calculate sunrise, civil, nautical or astronomical twilight. Defaults to ‘sun’.
- Raises:
ValueError – If ‘type_of_twilight’ is not one of ‘civil’, ‘nautical’, ‘astronomical’ or ‘sun’.
- Returns:
timestamp of date and time of end of the day.
- Return type:
pd.Timestamp
- pytheas.utilities.difference_between_geographic_angles(bearing: float, angle_wind: float) float #
Calculate the difference between geographic angles. Used to turn the absolute wind angle into the wind angle with the respect to the boat.
- Parameters:
bearing (float) – Bearing of the boat (in degrees).
angle_wind (float) – Absolute angle of the wind (in degrees).
- Returns:
Returns the angle of the wind with respect to the boat (in degrees).
- Return type:
float
- pytheas.utilities.direction_from_displacement(displacement: ndarray) float #
Calculates the absolute direction of a displacement in given as a vector (x, y).
- Parameters:
displacement (np.ndarray) – Array containing displacement (in km) in the x and y axis.
- Returns:
Angle of displacement with respect to the North (in degrees).
- Return type:
float
- pytheas.utilities.distance_km(origin: Tuple[float, float], target: Tuple[float, float]) float #
Calculates distance in km between two lat/lon points, in km
- Parameters:
origin (Tuple[float, float]) – point of origin as [lon, lat]
target (Tuple[float, float]) – point of destination as [lon, lat]
- Returns:
distance between origin and target
- Return type:
float
- pytheas.utilities.geographic_angle_to_xy(angle: float) ndarray #
From a geographic angle (with 0 degrees signifying North, 90 East, 180 South and 270 W) return x and y.
- Parameters:
angle (float) – geographic angle in degrees
- Returns:
array with dx (horizontal Eastward) and dy (vertical Northward)
- Return type:
np.ndarray
- pytheas.utilities.is_it_night(date_and_time: Timestamp, position: Tuple[float, float], type_of_twilight='sun') bool #
Calculates whether a set of coordinates refer to a moment in the day or in the night. We consider sunrise time as day, and sunset time as night.
- Parameters:
date_and_time (pd.Timestamp) – day of the year
position (Tuple[float, float]) – place in format [longitude, latitude]
type_of_twilight (str) – type of twilight, “civil”, “nautical” or “astronomical”. Defaults to “sun”.
- Returns:
returns whether the point is during the night or not
- Return type:
bool
- pytheas.utilities.knots_to_si(knots: float) float #
Converts knots to SI units (m/s)
- Parameters:
knots (float) – Speed in knots
- Returns:
Speed in metres/second
- Return type:
float
- pytheas.utilities.si_to_knots(si: float) float #
Converts SI units (m/s) to knots
- Parameters:
si (float) – Speed in m/s
- Returns:
Speed in knots
- Return type:
float