API

The ProMis engine for solving constrained navigation tasks using hybrid probabilistic logic.

class promis.promis.ProMis(star_map: StaRMap)[source]

Bases: object

The ProMis engine to create Probabilistic Mission Landscapes.

adaptive_solve(initial_evaluation_points, candidate_sampler, logic, number_of_iterations: int, number_of_improvement_points: int, n_jobs: int | None = None, batch_size: int = 10, scaler: float = 10.0, interpolation_method: str = 'linear', acquisition_method: str = 'entropy')[source]

Automatically add support points at locations where the uncertainty is high.

Parameters:
  • number_of_random_maps – How often to sample from map data in order to compute statistics of spatial relations

  • number_of_improvement_points – How many points to add to improve the map

  • relations – The spatial relations to compute

  • location_types – The location types to compute

  • interpolation_method – The interpolation method used to get from StaR Map known values to evluation points

  • acquisition_method – The method to inform the adaptive solving process, one of {entropy, gaussian_process}

solve(evaluation_points: CartesianCollection, logic: str, n_jobs: int | None = None, batch_size: int = 10, show_progress: bool = False, print_first: bool = False, interpolation_method: str = 'linear') None[source]

Solve the given ProMis problem.

It searches the provided logic for the used relations and location types and only encodes the necessary information for the inference. It can further parallelize the inference process over multiple workers and batch into fewer solver invocations to speed up computations.

Parameters:
  • support – The points to compute exactly, with the output being interpolated to the same target as the employed StaRMap

  • logic – The constraints of the landscape(X) predicate, including its definition

  • n_jobs – How many workers to use in parallel

  • batch_size – How many pixels to infer at once

  • show_progress – Whether to show a progress bar

  • print_first – Whether to print the first program to stdout

  • interpolation_method – The interpolation method used to get from StaR Map known values to evluation points

This module contains a class for handling probabilistic, semantic and geospatial data.

class promis.star_map.StaRMap(uam: CartesianMap)[source]

Bases: object

A Statistical Relational Map.

Among others, this holds two types of points: the target points and the support points. Initially the value of the relations are determined at the support points. To determine the value at the target points, the relations are approximated using the support points, e.g., through linear interpolation. When solving a ProMis problem, the solution is computed at the target points.

Note

Adding support points as CartesianRasterBands can be more efficient than adding an arbitraty CartesianCollection.

Parameters:
  • uam – The uncertainty annotated map as generator in Cartesian space

  • method – The method to approximate parameters from a set of support points; one of {“linear”, “nearest”, “gaussian_process”}

adaptive_sample(candidate_sampler: Callable[[int], ndarray[tuple[int, ...], dtype[_ScalarType_co]]], number_of_random_maps: int, number_of_iterations: int, number_of_improvement_points: int, what: dict[str, Iterable[str | None]] | None = None, scaler: float = 10.0, value_index: int = 0, acquisition_method: str = 'entropy')[source]

Automatically add support points at locations where the uncertainty is high.

Parameters:
  • candidate_sampler – The sampler that provides a candidate Collection that may be used for computing relation parameters

  • number_of_random_maps – How often to sample from map data in order to compute statistics of spatial relations

  • number_of_iterations – How many iterations of improvements to run

  • number_of_improvement_points – How many points to add to improve the map at each iteration

  • what – The spatial relations to compute, as a mapping of relation names to location types

  • scaler – How much to weigh the employed scoreing method over the distance score

  • value_index – Which value column of the relation’s parameters to use for improvement

  • acquisition_method – Which improvement method to use, one of {entropy, gaussian_process}

get(relation: str, location_type: str) Relation[source]

Get the computed data for a relation to a location type.

Parameters:
  • relation – The relation to return

  • location_type – The location type to relate to

Returns:

The relation for the given location type

get_all(logic: str | None = None) list[Relation][source]

Get all the relations for each location type.

Returns:

A list of all relations

initialize(evaluation_points: CartesianCollection, number_of_random_maps: int, logic: str)[source]

Setup the StaRMap for a given set of support points, number of samples and logic.

Parameters:
  • evaluation_points – The points to initialize the StaR Map on

  • number_of_random_maps – The number of samples to be used per support point

  • logic – The set of constraints deciding which relations are computed

static load(path) StaRMap[source]
property location_types: set[str]
property relation_and_location_types: dict[str, set[str]]
property relation_arities: dict[str, int]
static relation_name_to_class(relation: str) Relation[source]
property relation_types: set[str]
sample(evaluation_points: CartesianCollection, number_of_random_maps: int, what: dict[str, Iterable[str | None]] | None = None)[source]

Compute distributional clauses.

Parameters:
  • evaluation_points – The collection of points for which the spatial relations will be computed

  • number_of_random_maps – How often to sample from map data in order to compute statistics of spatial relations

  • what – The spatial relations to compute, as a mapping of relation names to location types

save(path)[source]

Geo

The ProMis geo package represents spatial data in Cartesian and polar coordinates.

class promis.geo.CartesianCollection(origin: PolarLocation, number_of_values: int = 1)[source]

Bases: Collection

property dimensions: tuple[float, float]

Get the dimensions of this Collection in meters.

Returns:

The dimensions of this Collection in meters as (width, height).

get_interpolator(interpolation_method: str = 'linear') Any[source]

Get an interpolator for the data.

Parameters:

interpolation_method – The interpolation method to use, one of {linear, nearest, hybrid, gaussian_process}

Returns:

A callable interpolator function

into(other: Collection, interpolation_method: str = 'linear', in_place: bool = True) Collection[source]
prune(threshold: float)[source]
to_cartesian_locations() list[CartesianLocation][source]
to_polar() PolarCollection[source]
class promis.geo.CartesianLocation(east: float, north: float, location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None, origin: PolarLocation | None = None)[source]

Bases: Location

A point in the cartesian plane based on local coordinates with an optional global reference.

Parameters:
  • east – The easting of the location in meters

  • north – The northing of the location in meters

  • up – The altitude of the location in meters

  • origin – A reference that can be used to project this cartesian representation (back) into a polar one

  • location_type – The type of this polygon

  • name – An optional name of this polygon

  • identifier – An optional unique identifier for this object, in \([0, 2**63)\)

  • uncertainty – An optional value representing the variance of this location’s east and north coordinates respectively

distance(other: Any) float[source]
property east: float
property north: float
send_to_gui(url='http://localhost:8000/add_geojson', timeout=1)[source]

Send an HTTP POST-request to the GUI backend.

Parameters:
  • url – url of the backend

  • timeout – request timeout in second

Raises:
  • HTTPError – When the HTTP request returned an unsuccessful status code

  • ConnectionError – If the request fails due to connection issues

to_polar(origin: PolarLocation | None = None) PolarLocation[source]

Computes the polar representation of this point.

Parameters:

origin – The global reference to be used for back-projection, must be set if and only if origin is None

Returns:

The global, polar representation of this point

class promis.geo.CartesianMap(origin: PolarLocation, features: list[CartesianLocation | CartesianMap | CartesianPolygon | CartesianPolyLine] | None = None)[source]

Bases: Map

A map containing geospatial objects based on local coordinates with a global reference point.

Parameters:
  • origin – The origin point of this map

  • features – A list of features that should be contained by this map

to_polar() PolarMap[source]

Projects this map to a polar representation according to the map’s global reference.

Returns:

The cartesian representation of this map with the given reference point being the same

class promis.geo.CartesianPolyLine(locations: list[CartesianLocation], location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None, origin: PolarLocation | None = None)[source]

Bases: PolyLine

A Cartesian polyline (line string) in local coordinates.

Parameters:
  • locations – The list of two or more locations that this shape consists of; see locations

  • location_type – The type of this polyline

  • name – The name of this polyline

  • identifier – The polyline’s optional unique identifier, in \([0, 2**63)\)

  • origin – A reference that can be used to project this cartesian representation (back) into a polar one

  • covariance – An optional value representing the variance of this polyline’s east and north coordinates respectively

distance(other: Any) float[source]
classmethod from_numpy(data: ndarray, *args, **kwargs) CartesianPolyLine[source]

Create a Cartesian polyline from a numpy representation.

Parameters:
  • data – An array with shape (number of locations, 2), where each location is represented by a pair of (east, north), each in degrees.

  • *args – Positional arguments to be passed to CartesianPolyLine

  • **kwargs – Keyword arguments to be passed to CartesianPolyLine

Returns:

The polar polyline created from the given coordinates an other parameters

Raises:

AssertionError – If the shape of array is invalid

See also

to_numpy()

send_to_gui(url='http://localhost:8000/add_geojson', timeout=1)[source]

Send an HTTP POST-request to the GUI backend.

Parameters:
  • url – url of the backend

  • timeout – request timeout in second

Raises:
  • HTTPError – When the HTTP request returned an unsuccessful status code

  • ConnectionError – If the request fails due to connection issues

to_polar(origin: PolarLocation | None = None) PolarPolyLine[source]

Computes the polar representation of this polyline.

Parameters:

origin – The global reference to be used for back-projection, must be set if and only if origin is None

Returns:

The global, polar representation of this polyline

class promis.geo.CartesianPolygon(locations: list[CartesianLocation], holes: list[list[CartesianLocation]] | None = None, location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None, origin: PolarLocation | None = None)[source]

Bases: Polygon

A cartesian polygon based on local coordinates with an optional global reference.

Examples

Lets first create the perimeter of the polygon as a list of CartesianLocation objects.

>>> locations = [CartesianLocation(-1.0, 1.0), CartesianLocation(1.0, 1.0),
...  CartesianLocation(1.0, -1.0), CartesianLocation(-1.0, -1.0)]

Now, we can build a polygon from these locations like so:

>>> polygon = CartesianPolygon(locations)

Given another list of locations, e.g.,

>>> holes = [[CartesianLocation(-0.5, 0.5), CartesianLocation(0.5, 0.5),
...  CartesianLocation(0.5, -0.5), CartesianLocation(-0.5, -0.5)]]

we can also build a polygon that contains holes:

>>> polygon = CartesianPolygon(locations, holes)

Given a covariance of this polygons translation, random samples can be drawn.

>>> from numpy import eye
>>> polygon = CartesianPolygon(locations, covariance=eye(2))
>>> random_samples = polygon.sample(10)

CartesianPolygons can also be created from numpy data.

>>> from numpy import array
>>> locations = array([[-1.0, 1.0, 1.0, -1.0], [1.0, 1.0, -1.0, -1.0]])
>>> polygon = CartesianPolygon.from_numpy(locations)

Finally, a CartesianPolygon can be turned into a PolarPolygon given a reference origin in polar coordinates.

>>> origin = PolarLocation(49.873163174, 8.653830718)
>>> polar_polygon = polygon.to_polar(origin)
Parameters:
  • locations – The list of locations that this shape consists of; see locations

  • holes – The points that make up holes in this polygon

  • location_type – The type of this polygon

  • name – The name of this polygon

  • identifier – The polygon’s optional unique identifier, in \([0, 2**63)\)

  • covariance – An optional matrix representing the variance of this polygon’s latitude and longitude respectively

  • origin – A reference that can be used to project this cartesian representation (back) into a polar one

distance(other: Any) float[source]
classmethod from_numpy(data: ndarray, *args, **kwargs) CartesianPolygon[source]

Create a polygon from a numpy representation.

Parameters:
  • data – An array with shape (2, number_of_locations)

  • args – Positional arguments to be passed to the new polygon

  • kwargs – Keyword arguments to be passed to the new polygon

Returns:

The polygon created from the given coordinates and other parameters

Raises:

AssertionError – If the shape or content of data is invalid

See also

to_numpy()

classmethod make_centered_box(width: float, height: float, offset: CartesianLocation = CartesianLocation(east=0.0, north=0.0, identifier=545558260477024664), **kwargs) CartesianPolygon[source]

Generates a box centered around a given offset.

Parameters:
  • width – The width of the map in meters

  • height – The height of the map in meters

  • kwargs – Additional keyword arguments to pass to the polygon, such as an origin

Returns:

The box as a polygon

plot(axis, **kwargs) None[source]

Plots this polygon using Matplotlib.

Parameters:
  • axis – The axis object to use for plotting

  • kwargs – Keyword arguments to pass to Matplotlib

send_to_gui(url='http://localhost:8000/add_geojson', timeout=1)[source]

Send an HTTP POST-request to the GUI backend.

Parameters:
  • url – url of the backend

  • timeout – request timeout in second

Raises:
  • HTTPError – When the HTTP request returned an unsuccessful status code

  • ConnectionError – If the request fails due to connection issues

to_polar(origin: PolarLocation | None = None) PolarPolygon[source]

Computes the polar representation of this shape.

Parameters:

origin – The global reference to be used for back-projection, must be set if and only if origin is None

Returns:

The global, polar representation of this geometry

class promis.geo.CartesianRasterBand(origin: PolarLocation, resolution: tuple[int, int], width: float, height: float, number_of_values: int = 1)[source]

Bases: RasterBand, CartesianCollection

A raster-band of Cartesian referenced data.

Parameters:
  • origin – The polar coordinates of this raster-band’s center

  • resolution – The number of horizontal and vertical pixels

  • width – The width the raster band stretches over in meters

  • height – The height the raster band stretches over in meters

  • number_of_values – How many values are stored per location

class promis.geo.Collection(columns: list[str], origin: PolarLocation, number_of_values: int = 1)[source]

Bases: ABC

A collection of values over a polar or Cartesian space.

Locations are stored as Cartesian coordinates, but data can be unpacked into both polar and Cartesian frames.

Parameters:
  • origin – The polar coordinates of this collection’s Cartesian frame’s center

  • data – A list of Cartesian location and value pairs

append(coordinates: ndarray[tuple[int, ...], dtype[Any]] | list[PolarLocation | CartesianLocation], values: ndarray[tuple[int, ...], dtype[Any]])[source]

Append location and associated value vectors to collection.

Parameters:
  • coordinates – A list of locations to append or matrix of coordinates

  • values – The associated values as 2D matrix, each row belongs to a single location

append_with_default(coordinates: ndarray[tuple[int, ...], dtype[Any]] | list[PolarLocation | CartesianLocation], value: ndarray[tuple[int, ...], dtype[Any]])[source]

Append location with a default value.

Parameters:
  • coordinates – A list of locations to append or matrix of coordinates

  • values – The default value to assign to all locations

clear()[source]

Empties out the kept data.

coordinates() ndarray[tuple[int, ...], dtype[Any]][source]

Unpack the location coordinates as numpy array.

Returns:

The values of this Collection as numpy array

extent() tuple[float, float, float, float][source]

Get the extent of this collection, i.e., the min and max coordinates.

Returns:

The minimum and maximum coordinates in order west, east, south, north

get_basemap(zoom=16)[source]

Obtain the OSM basemap image of the collection’s area.

Parameters:

zoom – The zoom level requested from OSM

Returns:

The basemap image

get_distance_to(other: Collection) ndarray[tuple[int, ...], dtype[_ScalarType_co]][source]

Computes the distances from this collection to another.

Parameters:

other – The other collection to compute the distance to

Returns:

An array that contains the distance to the respectively closest point in the other collection

get_entropy(number_of_neighbours: int = 4, number_of_bins: int = 10, value_index: int = 0) ndarray[tuple[int, ...], dtype[_ScalarType_co]][source]

Compute the local entropy in the collection.

Parameters:
  • number_of_neighbours – The number of neighbours of a point to take into account

  • number_of_bins – The number of bins to be used for the histogram

  • value_index – Decides which value of the collection the entropy is computed from

Returns:

The local entropy for each point

get_nearest_coordinate(point: ndarray[tuple[int, ...], dtype[_ScalarType_co]]) ndarray[tuple[int, ...], dtype[_ScalarType_co]][source]

Get the closest coordinate in this collection relative to a given point.

Parameters:

point – The point to find the nearest coordinate to

Returns:

The coordinate that is closest to the given point

improve(candidate_sampler: Callable, value_function: Callable, number_of_iterations: int, number_of_improvement_points: int, scaler: float, value_index: int = 0, acquisition_method: str = 'entropy') None[source]

Automatic improvement of the collection via informed sampling.

Parameters:
  • candidate_sampler – A sampler that provides a candidate Collection that may be used to improve this collection

  • value_function – The function to get new values from for the chosen points

  • number_of_iterations – The number of iterations to run the improvement for

  • number_of_improvement_points – The number of samples to take at every iteration (will be multiplied by number of value columns)

  • scaler – How much to scale the entropy or standard deviation within the score relative to the distance

  • acquisition_method – The scoreing method to use, one of {entropy, gaussian_process}

static load(path) Collection[source]
classmethod make_latin_hypercube(origin: PolarLocation, width: float, height: float, number_of_samples: int, number_of_values: int = 1, include_corners: bool = False) Collection[source]
save(path: str)[source]
scatter(value_index: int = 0, plot_basemap=True, ax=None, zoom=16, **kwargs)[source]

Create a scatterplot of this Collection.

Parameters:
  • value_index – Which value of the

  • plot_basemap – Whether an OpenStreetMap tile shall be rendered below

  • ax – The axis to plot to, default pyplot context if None

  • zoom – The zoom level of the OSM basemap, default 16

  • **kwargs – Args passed to the matplotlib scatter function

to_csv(path: str, mode: str = 'w')[source]

Saves the collection as comma-separated values file.

Parameters:
  • path – The path with filename to write to

  • mode – The writing mode, one of {w, x, a}

values() ndarray[tuple[int, ...], dtype[Any]][source]

Unpack the location values as numpy array.

Returns:

The values of this Collection as numpy array

class promis.geo.Direction(value)[source]

Bases: float, Enum

A simple collection of named “compass” bearings in degrees for self-documenting code.

EAST = 90.0
NORTH = 0.0
SOUTH = 180.0
WEST = 270.0
class promis.geo.Geospatial(location_type: str | None, name: str | None, identifier: int | None)[source]

Bases: ABC

The common abstract base class for both polar and cartesian geospatial objects.

See to_geo_json() on how this class can be used for visualizing geometries.

Parameters:
  • location_type – The type of this polygon

  • name – An optional name of this polygon

  • identifier – A unique identifier for this object, in \([0, 2^{63})\), i.e. 64 signed bits

property identifier: int | None

The numerical identifier of this object.

Must be None or in \([0, 2^{63})\), i.e. 64 signed bits.

send_to_gui(url: str = 'http://localhost:8000/add_geojson', timeout: int = 1)[source]

Send an HTTP POST-request to the GUI backend.

Parameters:
  • url – url of the backend

  • timeout – request timeout in second

Raises:
  • HTTPError – When the HTTP request returned an unsuccessful status code

  • ConnectionError – If the request fails due to connection issues

to_geo_json(indent: int | str | None = None, properties: dict | None = None, **kwargs) str[source]

Returns the GeoJSON representation of the geometry embedded into a feature.

Parameters:
  • indent – The number of levels to indent or None (see json.dumps())

  • kwargs – Much like indent, any keyword argument that can be passed to json.dumps(), like allow_nan, sort_keys, and more

Returns:

The GeoJSON representation as a string

Examples

GeoJSON is a widely used format that can be interpreted by a variety of GIS programs (geo information systems). Among them are for example the very simple website geojson.io. However, sometimes the geometries are too large to be handled by the web browser. Then there are other programs available, like the free open-source tool QGIS (Desktop). Its even available in the usual Ubuntu repositories, so just run [sudo] apt install qgis. Later, you can simply copy-pasta it into the tool.

The geojson representation can be obtained like this (using a PolarLocation just as an example):

>>> from promis.geo.location import PolarLocation
>>> darmstadt = PolarLocation(latitude=49.878091, longitude=8.654052, identifier=0)
>>> print(darmstadt.to_geo_json(indent=4))
{
    "type": "Feature",
    "id": 0,
    "geometry": {
        "type": "Point",
        "coordinates": [
            8.654052,
            49.878091
        ]
    },
    "properties": {
        "location_type": "UNKNOWN"
    }
}
class promis.geo.Location(x: float, y: float, location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None)[source]

Bases: Geospatial

property covariance: ndarray | None
classmethod from_numpy(data: ndarray, *args, **kwargs) DerivedLocation[source]

Create a location from a numpy representation.

Parameters:
  • data – An array with shape (2, 1)

  • args – Positional arguments to be passed to the new location

  • kwargs – Keyword arguments to be passed to the new location

Returns:

The location created from the given coordinates and other parameters

Raises:

AssertionError – If the shape of array is invalid

See also

to_numpy()

sample(number_of_samples: int = 1) list[DerivedLocation][source]

Sample locations given this location’s distribution.

Parameters:

number_of_samples – How many samples to draw

Returns:

The set of sampled locations with identical name, identifier etc.

to_numpy() ndarray[source]

Converts the coordinates defining this location into a numpy.ndarray.

Returns:

A column vector with shape (2, 1) containing this locations longitude and latitude in degrees.

See also

from_numpy()

class promis.geo.Map(origin: PolarLocation, features: list[CartesianLocation | CartesianMap | CartesianPolygon | CartesianPolyLine | PolarLocation | PolarMap | PolarPolygon | PolarPolyLine] | None = None)[source]

Bases: ABC

A base class for maps.

Parameters:
  • origin – The origin point of this map

  • features – A list of features that should be contained by this map

property all_location_types: set[str]

Get all location types contained in this map.

Returns:

A set of all location types contained in this map

apply_covariance(covariance: ndarray | dict | None)[source]

Set the covariance matrix of all features.

Parameters:

covariance – The covariance matrix to set for all featuers or a dictionary mapping location_type to covariance matrix

filter(location_type: str) DerivedMap[source]

Get a map with only features of the given type.

Parameters:

location_type – The type of locations to filter for

Returns:

A map that only contains features of the given type

is_valid() bool[source]

Whether this map contains only valid polygonal shapes according to shapely.

Quite expensive, not cached. Invalid features might cross themselves or have zero area. Other tools might still refuse it, like GEOS.

static load(path) Map[source]
location_types() list[str][source]

Get all location types contained in this map.

Returns:

A list of all location types contained in this map

sample(number_of_samples: int = 1) list[DerivedMap][source]

Sample random maps given this maps’s feature’s uncertainty.

Parameters:

number_of_samples – How many samples to draw

Returns:

The set of sampled maps with the individual features being sampled according to their uncertainties and underlying sample methods

save(path)[source]
to_geo_json(location_type: str | None = None, indent: int | str | None = None, **kwargs) str[source]

Constructs the GeoJSON string representing this map as a FeatureCollection.

For more information on GeoJSON, see promis.geo.geospatial.Geospatial.to_geo_json().

to_rtree() STRtree | None[source]

Convert this map into a Shapely STRtree for efficient spatial queries.

Returns:

The Shapely STRtree containing this map’s features

class promis.geo.PolarCollection(origin: PolarLocation, number_of_values: int = 1)[source]

Bases: Collection

property dimensions: tuple[float, float]

Get the dimensions of this Collection in meters.

Returns:

The dimensions of this Collection in meters as (width, height).

to_cartesian() CartesianCollection[source]
to_polar_locations() list[PolarLocation][source]
class promis.geo.PolarLocation(longitude: float, latitude: float, location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None)[source]

Bases: Location

A geospatial location representing a spatial object on earth.

See here for a nice collection of formulas and explanations on geographic transformations and calculations. This is the Rome for geographic calculation questions on Stack Overflow: All roads seem to eventually lead here.

Parameters:
  • longitude – The longitude in degrees within \([-180, +180)\)

  • latitude – The latitude in degrees within \([-90, +90]\)

  • location_type – The type of this polygon

  • name – An optional name of this polygon

  • identifier – An optional unique identifier for this object, in \([0, 2**63)\)

  • uncertainty – An optional value representing the variance of this location’s latitude and longitude respectively

distance(other: PolarLocation, approximate: bool = False) float[source]

Calculate the horizontal geodesic distance to another location in meters.

This assumes an ellipsoidal earth and converges for any pair of points on earth. It is accurate to round-off and uses geographiclib (https://pypi.org/project/geographiclib/) via geopy (https://pypi.org/project/geopy/).

The faster great-circle distance can also be used by setting approximate=True. It assumes only a spherical earth and is guaranteed to give a result for any pair of points. It is wrong by up to 0.5% and based on geopy. It is advised to use the exact solution unless you know what you are doing.

Parameters:
  • other – The location to measure the distance to in degrees

  • approximate – Whether to use a faster approximation or not (default: False)

Returns:

The distance to the other point in meters

property latitude: float
property longitude: float
property projection: Proj

Derive a pyproj.Proj instance for projecting points.

This instance is cached for performance reasons, since its creation is relatively time consuming.

to_cartesian(origin: PolarLocation | None = None) CartesianLocation[source]

Projects this point to a Cartesian one according to the given global reference.

Parameters:

origin – The reference by which to project onto the local tangent plane

Returns:

The cartesian representation of this point with the given reference point being set

class promis.geo.PolarMap(origin: PolarLocation, features: list[PolarLocation | PolarMap | PolarPolygon | PolarPolyLine] | None = None)[source]

Bases: Map

A map containing geospatial objects based on WGS84 coordinates.

Parameters:
  • origin – The origin point of this map

  • features – A list of features that should be contained by this map

send_to_gui(url: str = 'http://localhost:8000/add_geojson_map', timeout: int = 10)[source]

Send an HTTP POST-request to the GUI backend to add all feature in the map to gui.

Parameters:
  • url – url of the backend

  • timeout – request timeout in second

Raises:
  • HTTPError – When the HTTP request returned an unsuccessful status code

  • ConnectionError – If the request fails due to connection issues

to_cartesian() CartesianMap[source]

Projects this map to a cartesian representation according to its global reference.

Returns:

The cartesian representation of this map with the given reference point being the same

class promis.geo.PolarPolyLine(locations: list[PolarLocation], location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None)[source]

Bases: PolyLine

A polyline (line string) based on WGS84 coordinates.

Note

This class does not yet support simplification as it was not required so far.

Parameters:
  • locations – The two or more points that make up this polyline; see locations

  • location_type – The type of this polygon

  • name – An optional name of this polygon

  • identifier – The polyline’s optional unique identifier, in \([0, 2**63)\)

  • uncertainty – An optional value representing the variance of this polyline’s latitudes and longitudes respectively

classmethod from_numpy(data: ndarray, *args, **kwargs) PolarPolyLine[source]

Create a polar polyline from a numpy representation.

Parameters:
  • data – An array with shape (number of locations, 2), where each location

  • `` (is represented by a pair of)

  • *args – Positional arguments to be passed to PolarPolyLine

  • **kwargs – Keyword arguments to be passed to PolarPolyLine

Returns:

The polar polyline created from the given coordinates an other parameters

Raises:

AssertionError – If the shape of array is invalid

See also

to_numpy()

to_cartesian(origin: PolarLocation) CartesianPolyLine[source]

Projects this polyline to a Cartesian one according to the given global reference.

Parameters:

origin – The reference by which to project onto the local tangent plane

Returns:

The cartesian representation of this polyline with the given reference point being set

class promis.geo.PolarPolygon(locations: list[PolarLocation], holes: list[list[PolarLocation]] | None = None, location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None)[source]

Bases: Polygon

A polygon based on WGS84 coordinates.

An object with only a single point may be represented by a polygon with three times the same location.

Examples

Lets first create the perimeter of the polygon as a list of PolarLocation objects.

>>> locations = [PolarLocation(-1.0, 1.0), PolarLocation(1.0, 1.0),
...  PolarLocation(1.0, -1.0), PolarLocation(-1.0, -1.0)]

Now, we can build a polygon from these locations like so:

>>> polygon = PolarPolygon(locations)

Given another list of locations, e.g.,

>>> holes = [[PolarLocation(-0.5, 0.5), PolarLocation(0.5, 0.5),
...  PolarLocation(0.5, -0.5), PolarLocation(-0.5, -0.5)]]

we can also build a polygon that contains holes:

>>> polygon = PolarPolygon(locations, holes)

Given a covariance of this polygons translation, random samples can be drawn.

>>> from numpy import eye
>>> polygon = PolarPolygon(locations, covariance=eye(2))
>>> random_samples = polygon.sample(10)

PolarPolygons can also be created from numpy data.

>>> from numpy import array
>>> locations = array([[-1.0, 1.0, 1.0, -1.0], [1.0, 1.0, -1.0, -1.0]])
>>> polygon = PolarPolygon.from_numpy(locations)

Finally, a PolarPolygon can be turned into a CartesianPolygon given a reference origin in polar coordinates.

>>> origin = PolarLocation(0.0, 0.0)
>>> cartesian_polygon = polygon.to_cartesian(origin)
Parameters:
  • locations – The points that make up this polygon; see locations

  • holes – The points that make up holes in this polygon

  • location_type – The type of this polygon

  • name – An optional name of this polygon

  • identifier – The polygon’s optional unique identifier, in \([0, 2**63)\)

  • covariance – An optional matrix representing the variance of this polygon’s latitude and longitude respectively

classmethod from_numpy(data: ndarray, *args, **kwargs) PolarPolygon[source]

Create a polygon from a numpy representation.

Parameters:
  • data – An array with shape (2, number_of_locations)

  • args – Positional arguments to be passed to the new polygon

  • kwargs – Keyword arguments to be passed to the new polygon

Returns:

The polygon created from the given coordinates and other parameters

Raises:

AssertionError – If the shape or content of data is invalid

See also

to_numpy()

to_cartesian(origin: PolarLocation) CartesianPolygon[source]

Projects the polygon to a Cartesian one according to a given global reference.

Parameters:

origin – The reference point by which to project onto the local tangent plane

Returns:

The cartesian representation of this polygon with the given reference point being set

class promis.geo.PolarRasterBand(origin: PolarLocation, resolution: tuple[int, int], width: float, height: float, number_of_values: int = 1)[source]

Bases: RasterBand, PolarCollection

A raster-band of Polar referenced data.

Parameters:
  • origin – The polar coordinates of this raster-band’s center

  • resolution – The number of horizontal and vertical pixels

  • width – The width the raster band stretches over in meters

  • height – The height the raster band stretches over in meters

  • number_of_values – How many values are stored per location

as_image(value_index: int = 0) array[source]

Convert the RasterBand data into a 2D array for use as image.

Parameters:

value_index – Which value to put into the image

Returns:

The RasterBand data as 2D array

class promis.geo.PolyLine(locations: list[PolarLocation | CartesianLocation], location_type: str | None = None, name: str | None = None, identifier: int | None = None, covariance: ndarray | None = None)[source]

Bases: Geospatial

property covariance: ndarray
sample(number_of_samples: int = 1) list[DerivedPolyLine][source]

Sample PolyLines given this PolyLine’s uncertainty.

Parameters:

number_of_samples – How many samples to draw

Returns:

The set of sampled PolyLines, each with same name, identifier etc.

to_numpy() ndarray[source]

Converts the coordinates defining this polyline into a numpy.ndarray.

Returns:

An array with shape (number of locations, 2), where each location is represented by a pair of (longitude, latitude), each in degrees.

See also

from_numpy()

class promis.geo.RasterBand(resolution: tuple[int, int], width: float, height: float)[source]

Bases: ABC

A raster-band of spatially referenced data on a regular grid.

Parameters:
  • resolution – The number of horizontal and vertical pixels

  • width – The width the raster band stretches over in meters

  • height – The height the raster band stretches over in meters

append(location: CartesianLocation | PolarLocation, values: list[float]) NoReturn[source]
search_path(start: tuple[float, float], goal: tuple[float, float], cost_model: Callable[[float], float], value_filter: Callable[[float], float]) ndarray[tuple[int, ...], dtype[_ScalarType_co]][source]

Search the shortest path through this RasterBand using A*.

Parameters:
  • cost_model – A function that maps RasterBand values to edge weights

  • value_filter – A function that is applied to RasterBand values to decide if they should become edges in the graph

Returns:

The shortest path from start to goal given the costs induced by the given models and RasterBand values

to_graph(cost_model: Callable[[float], float], value_filter: Callable[[float], bool]) Graph[source]

Convert a RasterBand into a NetworkX Graph for path planning.

Parameters:
  • cost_model – A function that maps RasterBand values to edge weights

  • value_filter – A function that is applied to RasterBand values to decide if they should become edges in the graph

Returns:

The corresponding graph where the cost of visiting a node is determined by the RasterBand’s values and cost_model

Loaders

The ProMis loaders package provides data loading for various sources.

class promis.loaders.NauticalLoader(chart_root: Path, origin: PolarLocation, dimensions: tuple[float, float])[source]

Bases: SpatialLoader

load(feature_description=None, n_jobs: int | None = None) None[source]

Populates features with from a source.

Parameters:

feature_description – A mapping of location types to loader specific descriptions. Passing None can be valid for loaders with a fixed set of features.

class promis.loaders.OsmLoader(origin: PolarLocation, dimensions: tuple[float, float], feature_description: dict | None, timeout: float = 5.0)[source]

Bases: SpatialLoader

A loader for spatial data from OpenStreetMaps (OSM) via the overpy package.

load(feature_description: dict[str, str], timeout: float = 5.0) None[source]

Populates features with from a source.

Parameters:

feature_description – A mapping of location types to loader specific descriptions. Passing None can be valid for loaders with a fixed set of features.

static relation_to_polygon(relation: Relation, **kwargs) PolarPolygon[source]

Turn an OSM relation into a PolarPolygon.

Parameters:
  • relation – The relation to turn into a PolarPolygon

  • kwargs – Arguments that are given to PolarPolygon

Returns:

The PolarPolygon from the data in the relation

class promis.loaders.SpatialLoader(origin: PolarLocation, dimensions: tuple[float, float])[source]

Bases: ABC

A base class for loaders of geospatial objects from differents sources and interfaces.

static compute_polar_bounding_box(origin: PolarLocation, dimensions: tuple[float, float]) tuple[float, float, float, float][source]

Computes the north, east, south and west limits of the area to be loaded.

Parameters:
  • origin – A point that defines the center of the map

  • dimensions – The width and height of the map in meters

Returns:

Southern latitude, western longitude, northern latitude and eastern longitude

abstract load(feature_description: dict[str, Any] | None = None) None[source]

Populates features with from a source.

Parameters:

feature_description – A mapping of location types to loader specific descriptions. Passing None can be valid for loaders with a fixed set of features.

to_cartesian_map() CartesianMap[source]
to_polar_map() PolarMap[source]

Logic

The ProMis logic package provides probabilistic logic program inference.

class promis.logic.Solver(program: str)[source]

Bases: object

A solver for HPLP based ProMis.

Parameters:

program – The logic program written in ProbLog with distributional clauses

inference() list[float][source]

Run probabilistic inference on the given program.

Returns:

A list of probabilities for all queries in the program

Models

Provides mathematical abstractions for usage within Promis.

class promis.models.Gaussian(mean: ndarray, covariance: ndarray, weight: float = 1.0)[source]

Bases: object

A weighted multivariate gaussian distribution.

Examples

A Gaussian can be simply created from a mean and covarinace vector (and an optional weight):

>>> from numpy import array
>>> from numpy import vstack
>>> mean = vstack([0.0, 0.0])
>>> covariance = array([[1.0, 0.0], [0.0, 1.0]])
>>> N = Gaussian(mean, covariance, weight=1.0)
>>> N(vstack([0.0, 0.0])).item()  
0.159...

Two Gaussians are equal if and only if all attributes are equal:

>>> N == N
True
>>> other_covariance = array([[99.0, 0.0], [0.0, 99.0]])
>>> other_N = Gaussian(mean, other_covariance, weight=1.0)
>>> other_N(vstack([10.0, 10.0])).item()  
0.000585...
>>> N == other_N
False

Sampling from Gaussians is straight forward as well. Either a single

>>> sample = N.sample()
>>> sample.shape
(2, 1)

or many samples

>>> sample = N.sample(100)
>>> sample.shape
(2, 100)

can be generated at once.

Parameters:
  • mean – The mean of the distribution as column vector, of dimension (n, 1)

  • covariance – The covariance matrix of the distribution, of dimension (n, n)

  • weight – The weight of the distribution, e.g. within a mixture model

References

property P: ndarray
cdf(x: ndarray) float[source]

Compute the CDF as integral of the PDF from negative infinity up to x.

Parameters:

x – The upper bound of the integral

Returns:

The probability of a value being less than x

sample(number_of_samples: int = 1) ndarray[source]

Draw a number of samples following this Gaussian’s distribution.

Parameters:

number_of_samples – The number of samples to draw

Returns:

The drawn samples

property w: float
property x: ndarray
class promis.models.GaussianMixture(components: list[Gaussian] | None = None)[source]

Bases: object

The Gaussian Mixture Model (GMM) for representing multi-modal probability distribution.

Parameters:

components – An initial list of components to consider in this GMM

append(component: Gaussian)[source]

Appends a new Gaussian to this Mixture’s list of components.

Parameters:

component – The new Gaussian to append

modes(threshold: float = 0.5) list[ndarray][source]

Extract all modes of the mixture model that are above a set threshold.

Parameters:

threshold – Weight that a component needs to have to be considered

Returns:

The locations of all modes with weight larger than the threshold

prune(threshold: float, merge_distance: float, max_components: int) None[source]

Reduces the number of gaussian mixture components.

Parameters:
  • threshold – Truncation threshold s.t. components with weight < threshold are removed

  • merge_distance – Merging threshold s.t. components ‘close enough’ will be merged

  • max_components – Maximum number of gaussians after pruning

class promis.models.GaussianProcess[source]

Bases: object

A Gaussian Process regressor using GPyTorch for scalable updates.

fit(coordinates: ndarray[tuple[int, ...], dtype[_ScalarType_co]], values: ndarray[tuple[int, ...], dtype[_ScalarType_co]], number_of_iterations: int = 50) float[source]
predict(coordinates: ndarray[tuple[int, ...], dtype[_ScalarType_co]], return_std: bool = False)[source]

Estimators

This package provides methods for state estimation, visual perception, mapping and similar.