Sensor Positioning (SP) API Reference
Data
Data model for the Sensor Positioning (SP) use case.
SppData
Bases: UcData
Materialized coverage representation for Sensor Positioning.
This variant assumes coverage was precomputed (e.g., from geometry)
and stored as a boolean matrix: targets x positions. Fixed-on/off sets
(fixed_on, fixed_off) capture degree-1/dominated preprocessing decisions.
Attributes:
-
name(Literal['sensor_position_problem']) –Identifier.
-
position_ids(list[str]) –Identifiers for candidate sensor placements.
-
target_ids(list[str]) –Identifiers for targets/street points to cover.
-
coverage(NumPyArray) –Boolean matrix shape (n_targets, n_positions): coverage[t, p] is True if position p covers target t.
-
position_costs(NumPyArray) –Length n_positions; cost of activating each position (default 1).
-
min_coverage(list[int]) –Required coverage per target (broadcasted from int if needed).
-
budget(float | None) –Optional cost budget (<= constraint).
-
max_positions(int | None) –Optional cardinality cap.
-
incompatibilities(list[tuple[int, int]]) –Pairwise exclusions between positions.
-
must_select(list[int]) –Positions that must be activated.
-
forbidden(list[int]) –Positions that must stay deactivated.
-
fixed_on(list[int]) –Positions forced to 1 from preprocessing (e.g., degree-1 reductions).
-
fixed_off(list[int]) –Positions forced to 0 from preprocessing (e.g., dominated reductions).
-
uncoverable_targets(list[int] | None) –Target indices that cannot be covered by any candidate sensor.
-
cost_weight(float) –Weight on cost term (default 1.0).
-
proximity_penalty_weight(float) –Optional weight for future pairwise penalties (not used yet).
-
dropped_dominated_positions(NumPyArray | None) –Display-only geometry for dominated dropped lidars.
-
dropped_degree1_positions(NumPyArray | None) –Display-only geometry for degree-1 dropped lidars.
-
dropped_target_positions(NumPyArray | None) –Display-only geometry for targets removed by degree-1 reductions.
-
walls(list[WallLike] | None) –Optional wall geometry as tuples in this order:
(endpoint_a[x, y], endpoint_b[x, y], wall_height, sensor_density, lidar_height, wall_offset, direction_mode, pitch). -
group_ids(list[str | None]) –Optional mutual-exclusion groups (variants) per position; same group means at most one.
-
lidar_params(list[dict] | None) –Per-position coverage overrides (max_radius, half_horizontal_angle, max_vert_angle, min_vert_angle).
-
position_metadata(list[dict] | None) –Display metadata per position (labels, source, groupId, coverage params, variantOf, cost).
to_string() -> str
Summarize core counts and reduction metadata.
to_problem_dict(*, include_metadata: bool = True, include_coverage: bool = False) -> dict[str, Any]
Convert the instance to the enriched problem dictionary format.
save_to_json(path: str | Path, *, include_metadata: bool = True, include_coverage: bool = False) -> Path
Persist the problem dictionary to JSON on disk.
with_coverage(coverage: np.ndarray) -> SppData
Return a new instance with updated coverage while retaining metadata.
plot(*, ax: Axes | None = None, show_walls: bool = True, show_targets: bool = True, show_uncoverable_targets: bool = False, show_dropped_dominated_sensors: bool = True, show_dropped_degree1_sensors: bool = True, show_dropped_targets: bool = True, show_candidate_sensors: bool = True, show_coverage_rays: bool = False, show_sensor_headings: bool = True) -> Axes
Plot the SP problem structure on the provided axes.
Parameters:
-
ax(Axes | None, default:None) –Matplotlib axes to draw on. If
None, a new axes is created. -
show_walls(bool, default:True) –Draw walls and wall polygon.
-
show_targets(bool, default:True) –Draw target points.
-
show_uncoverable_targets(bool, default:False) –Highlight uncoverable targets.
-
show_dropped_dominated_sensors(bool, default:True) –Draw dominated dropped sensors.
-
show_dropped_degree1_sensors(bool, default:True) –Draw degree-1 dropped sensors.
-
show_dropped_targets(bool, default:True) –Draw dropped targets.
-
show_candidate_sensors(bool, default:True) –Draw candidate sensors.
-
show_coverage_rays(bool, default:False) –Draw all coverage rays.
-
show_sensor_headings(bool, default:True) –Draw sensor heading arrows.
Returns:
-
Axes–The axes with the plot.
Raises:
-
InvalidProblemStructureError–If required geometry is missing (
lidar_positionsortarget_positions).
generate_random(n_positions: int = 10, n_targets: int = 20, density: float = 0.2, seed: int | None = None) -> SppData
staticmethod
Create a random SP instance with guaranteed coverable targets.
Formulation
Formulation for the Sensor Positioning (SP) use case.
SppFormulation
Bases: UcFormulation[SppData, SppSolution]
Min-cost set-cover style formulation using materialized coverage.
to_string(data: SppData) -> str
staticmethod
Return a text summary of the formulated model inputs.
formulate(data: SppData) -> Model
staticmethod
Build the mixed-integer model for the SP instance.
interpret(solution: Solution, data: SppData) -> SppSolution
staticmethod
Map solver output back into an SpSolution with coverage metrics.
Solution
Solution model for the Sensor Positioning use case.
SppSolution
Bases: UcSolution
Selected positions and coverage metrics.
to_string() -> str
Return a formatted summary of the solution.
print() -> str
Return the string representation (alias for to_string).
plot(data: SppData | None = None, *, ax: Axes | None = None, show_walls: bool = True, show_targets: bool = True, show_uncoverable_targets: bool = False, show_dropped_dominated_sensors: bool = True, show_dropped_degree1_sensors: bool = True, show_dropped_targets: bool = True, show_candidate_sensors: bool = True, show_selected_sensors: bool = True, show_covered_targets: bool = True, show_uncovered_targets: bool = True, show_coverage_rays_all: bool = False, show_coverage_rays_selected: bool = False, show_sensor_headings: bool = True) -> Axes
Plot the SP solution structure on the provided axes.
Parameters:
-
data(SppData | None, default:None) –Problem data used for geometry and coverage information.
-
ax(Axes | None, default:None) –Matplotlib axes to draw on. If
None, a new axes is created. -
show_walls(bool, default:True) –Draw walls and wall polygon.
-
show_targets(bool, default:True) –Draw target points.
-
show_uncoverable_targets(bool, default:False) –Highlight uncoverable targets.
-
show_dropped_dominated_sensors(bool, default:True) –Draw dominated dropped sensors.
-
show_dropped_degree1_sensors(bool, default:True) –Draw degree-1 dropped sensors.
-
show_dropped_targets(bool, default:True) –Draw dropped targets.
-
show_candidate_sensors(bool, default:True) –Draw non-selected candidate sensors.
-
show_selected_sensors(bool, default:True) –Draw selected sensors.
-
show_covered_targets(bool, default:True) –Draw covered targets.
-
show_uncovered_targets(bool, default:True) –Draw uncovered targets.
-
show_coverage_rays_all(bool, default:False) –Draw all target-to-candidate coverage rays.
-
show_coverage_rays_selected(bool, default:False) –Draw target-to-selected coverage rays.
-
show_sensor_headings(bool, default:True) –Draw sensor heading arrows.
Returns:
-
Axes–The axes with the plot.
Raises:
-
ValueError–If
datais not provided. -
InvalidProblemStructureError–If required geometry is missing on
data. -
DataShapeMismatchError–If
data.coverageshape is inconsistent with geometry.
Instance
Instance model for Sp use case.
SppInstance
Bases: UcInstance[SppData, SppFormulation, SppSolution]
Instance combining data and formulation for Sp.
Collection
Collection of Sp instances.
SppCollection
Bases: UcInstanceCollection[SppInstance]
Lightweight SP collection utilities.
from_random(n_positions: int, n_targets: int, density: float = 0.2, num_instances: int = 1, seed: int | None = None) -> SppCollection
classmethod
Generate a collection of random SP instances.
from_json_file(path: str, *, max_vert_angle: float = 30, min_vert_angle: float = -80, max_radius: float = 2.5, half_horizontal_angle: float = 180, lidar_wall_offset: float = 0.2, min_coverage: int = 1, budget: float | None = None, max_positions: int | None = None, sensor_reduction: Literal['none', 'drop', 'fix'] = 'none', auto_variants: bool = False, auto_variant_specs: list[str] | None = None, auto_variant_group_mode: Literal['by-label', 'per-base-label'] = 'per-base-label', auto_variant_base_group: bool = True, auto_variant_cost_mult: float = 1.0, save_enriched_path: str | Path | None = None, include_metadata: bool = True, include_coverage: bool = True) -> SppCollection
classmethod
Load collection from JSON file.
Args: path: Path to JSON file. max_vert_angle: Maximum vertical viewing angle (degrees). min_vert_angle: Minimum vertical viewing angle (degrees). max_radius: Maximum sensor range. half_horizontal_angle: Half of horizontal field of view (degrees). lidar_wall_offset: Distance from wall endpoints when generating lidars. min_coverage: Required minimum coverage per target. budget: Optional total cost budget. max_positions: Optional cap on selected positions. sensor_reduction: "none" (default), "drop" to remove redundant sensors, "fix" to keep them but mark as fixed on/off.
Returns:
-
SpCollection with one instance from the JSON file.–
from_json_obj(problem_dict: dict[str, Any], *, max_vert_angle: float = 30, min_vert_angle: float = -80, max_radius: float = 2.5, half_horizontal_angle: float = 180, lidar_wall_offset: float = 0.2, min_coverage: int = 1, budget: float | None = None, max_positions: int | None = None, sensor_reduction: Literal['none', 'drop', 'fix'] = 'none', auto_variants: bool = False, auto_variant_specs: list[str] | None = None, auto_variant_group_mode: Literal['by-label', 'per-base-label'] = 'per-base-label', auto_variant_base_group: bool = True, auto_variant_cost_mult: float = 1.0, save_enriched_path: str | Path | None = None, include_metadata: bool = True, include_coverage: bool = True) -> SppCollection
classmethod
Load collection from an in-memory JSON object.
from_json_str(json_string: str, *, max_vert_angle: float = 30, min_vert_angle: float = -80, max_radius: float = 2.5, half_horizontal_angle: float = 180, lidar_wall_offset: float = 0.2, min_coverage: int = 1, budget: float | None = None, max_positions: int | None = None, sensor_reduction: Literal['none', 'drop', 'fix'] = 'none', auto_variants: bool = False, auto_variant_specs: list[str] | None = None, auto_variant_group_mode: Literal['by-label', 'per-base-label'] = 'per-base-label', auto_variant_base_group: bool = True, auto_variant_cost_mult: float = 1.0, save_enriched_path: str | Path | None = None, include_metadata: bool = True, include_coverage: bool = True) -> SppCollection
classmethod
Load collection from JSON string payload.