.. _api:

=============
API Reference
=============

This chapter provides a reference for OMRAT's key modules, classes, and
functions.

.. contents:: In this chapter
   :local:
   :depth: 2


compute.basic_equations
========================

Core mathematical formulas for risk calculations.

**Source file:** ``compute/basic_equations.py`` (`View on GitHub <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py>`__)

Drifting Functions
------------------

.. function:: get_Fcoll(na, pc)

   Calculate accident frequency from candidates and causation factor.

   :param na: Number of accident candidates
   :param pc: Causation probability
   :return: Accident frequency (:math:`F = N_A \times P_C`)

   **Line:** 5 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L5>`__

.. function:: get_drifting_prob(Fb, line_length, ship_speed)

   Calculate the probability of a blackout during transit.

   :param Fb: Blackout frequency (events/year)
   :param line_length: Leg length (metres)
   :param ship_speed: Ship speed (m/s)
   :return: Blackout probability

   Uses: :math:`P = 1 - \exp(-F_b / (24 \times 365) \times h)`

   **Line:** 9 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L9>`__

.. function:: get_drift_time(distance, drift_speed)

   Estimate the time to drift a given distance.

   :param distance: Drift distance (metres)
   :param drift_speed: Drift speed (m/s)
   :return: Drift time (seconds)

   **Line:** 14 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L14>`__

.. function:: get_not_repaired(data, drift_speed, dist)

   Get the probability that the engine is not repaired before drifting
   distance ``dist``.

   :param data: Repair time parameters dict
   :param drift_speed: Drift speed (m/s)
   :param dist: Distance to obstacle (metres)
   :return: Probability of not being repaired

   **Line:** 30 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L30>`__

.. function:: repairtime_function(data, x)

   Evaluate the repair time CDF at time ``x``.

   :param data: Repair parameters dict
   :param x: Time (hours)
   :return: Cumulative repair probability

   **Line:** 18 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L18>`__

Ship-Ship Collision Functions
------------------------------

.. function:: get_head_on_collision_candidates(Q1, Q2, V1, V2, mu1, mu2, sigma1, sigma2, B1, B2, L_w)

   Calculate geometric head-on collision candidates (Hansen Eq. 4.2--4.4).

   :param Q1, Q2: Traffic volumes (ships/year)
   :param V1, V2: Ship speeds (m/s)
   :param mu1, mu2: Mean lateral positions (m)
   :param sigma1, sigma2: Standard deviations (m)
   :param B1, B2: Ship beams (m)
   :param L_w: Leg length (m)
   :return: Geometric collision candidates per year

   **Line:** 46 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L46>`__

.. function:: get_overtaking_collision_candidates(Q_fast, Q_slow, V_fast, V_slow, mu_fast, mu_slow, sigma_fast, sigma_slow, B_fast, B_slow, L_w)

   Calculate geometric overtaking collision candidates (Hansen Eq. 4.5).
   Returns 0 if ``V_fast <= V_slow``.

   :return: Geometric collision candidates per year

   **Line:** 147 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L147>`__

.. function:: get_crossing_collision_candidates(Q1, Q2, V1, V2, L1, L2, B1, B2, theta)

   Calculate geometric crossing collision candidates (Hansen Eq. 4.6).
   Returns 0 if legs are parallel (``sin(theta) ~ 0``).

   :param theta: Crossing angle (radians)
   :return: Geometric collision candidates per year

   **Line:** 238 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L238>`__

.. function:: get_bend_collision_candidates(Q, P_no_turn, L, B, theta)

   Calculate bend collision candidates at waypoints.

   :param Q: Traffic volume (ships/year)
   :param P_no_turn: Probability of not turning (default 0.01)
   :param theta: Bend angle (radians)
   :return: Bend collision candidates per year

   **Line:** 331 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L331>`__

Powered Grounding Functions
----------------------------

.. function:: get_recovery_distance(position_check_minutes, ship_speed)

   Calculate recovery distance :math:`a = \lambda \times V`.

   :param position_check_minutes: Check interval (minutes)
   :param ship_speed: Ship speed (m/s)
   :return: Recovery distance (metres)

   **Line:** 408 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L408>`__

.. function:: get_powered_grounding_cat1(Q, Pc, prob_in_obstacle)

   Category I powered grounding -- ships sailing directly into obstacle.

   :param Q: Traffic volume (ships/year)
   :param Pc: Causation factor
   :param prob_in_obstacle: Fraction of distribution overlapping obstacle
   :return: Expected groundings per year

   **Line:** 432 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L432>`__

.. function:: get_powered_grounding_cat2(Q, Pc, prob_at_position, distance_to_obstacle, position_check_interval, ship_speed)

   Category II powered grounding -- ships failing to turn at bend.

   :param distance_to_obstacle: Distance from bend (metres)
   :param position_check_interval: Check interval (minutes)
   :return: Expected groundings per year

   **Line:** 470 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/basic_equations.py#L470>`__


compute.run_calculations
========================

**Source file:** ``compute/run_calculations.py`` (`View on GitHub <https://github.com/axelande/OMRAT/blob/main/compute/run_calculations.py>`__)

.. class:: Calculation(omrat)

   Main calculation orchestrator.

   **Line:** 44 | `Source <https://github.com/axelande/OMRAT/blob/main/compute/run_calculations.py#L44>`__

   Composed from mixins: ``DriftingModelMixin``, ``ShipCollisionModelMixin``,
   ``PoweredModelMixin``, ``DriftingReportMixin``, ``VisualizationMixin``
   (`run_calculations.py:34-50 <https://github.com/axelande/OMRAT/blob/main/compute/run_calculations.py#L34>`__)

   .. method:: run_drifting_model(data)

      Execute the complete drifting risk calculation pipeline:
      drift corridor generation, Monte Carlo probability integration,
      repair time application, wind rose weighting.

   .. method:: run_ship_collision_model(data)

      Calculate ship-ship collision frequencies for all encounter types.

   .. method:: run_powered_grounding_model(data)

         Calculate powered grounding (Category I and II).

         Implementation details:

         - Groups draughts into effective depth bins based on depth
            contours.
         - Reuses cached shadow/ray-casting computations per bin.
         - Emits progress updates per obstacle-bin step for long runs.

   .. method:: run_powered_allision_model(data)

      Calculate powered allision with structures.

   .. method:: run_drift_visualization(data)

      Generate drift corridor visualisation layers without full
      probability calculation.


geometries.drift
=================

**Source file:** ``geometries/drift/generator.py`` (`View on GitHub <https://github.com/axelande/OMRAT/blob/main/geometries/drift/generator.py>`__)

Drift Corridor Generation
--------------------------

.. class:: DriftCorridorGenerator(omrat)

   Main orchestrator for drift corridor generation.

   **Line:** 25 | `Source <https://github.com/axelande/OMRAT/blob/main/geometries/drift/generator.py#L25>`__

   .. method:: precollect_data(depth_threshold, height_threshold)

      Pre-collect data from UI in the main thread.

   .. method:: generate_corridors(depth_threshold, height_threshold, target_prob=1e-3)

      Generate corridors for all legs and 8 directions.

      :return: List of corridor dicts with keys: ``direction``,
               ``angle``, ``leg_index``, ``polygon``,
               ``anchor_polygon``, ``deep_polygon``

Corridor Construction
---------------------

.. function:: create_base_surface(leg, half_width)

   Create the base distribution rectangle for a leg.

.. function:: create_projected_corridor(leg, half_width, drift_angle_deg, projection_dist)

   Create the full unclipped corridor by projecting the base surface.

.. function:: create_obstacle_shadow(obstacle, drift_angle_deg, corridor_bounds)

   Create the blocking shadow zone behind an obstacle.

.. function:: clip_corridor_at_obstacles(corridor, obstacles, drift_angle_deg)

   Clip corridor by removing all shadow zones.

Distribution Utilities
-----------------------

.. function:: get_projection_distance(repair_params, drift_speed_ms, target_prob=1e-3, max_distance=50000)

   Calculate maximum drift distance from repair time distribution.

.. function:: get_distribution_width(std, coverage=0.99)

   Calculate lateral strip width for given distribution coverage.

Coordinate Utilities
---------------------

.. function:: get_utm_crs(lon, lat)

   Return the appropriate UTM CRS for a geographic location.

.. function:: transform_geometry(geom, from_crs, to_crs)

   Transform a Shapely geometry between coordinate reference systems.

.. function:: compass_to_vector(angle_deg, distance)

   Convert compass angle and distance to (dx, dy) vector in UTM.


geometries.calculate_probability_holes
=======================================

.. function:: compute_probability_holes(lines, distributions, weights, objs_gdf_list, distance, progress_callback=None)

   Compute probability that vessels will hit each obstacle using
   Monte Carlo integration with parallel execution.

   :param lines: List of leg LineStrings (UTM)
   :param distributions: List of distribution parameter lists
   :param weights: List of weight lists
   :param objs_gdf_list: List of obstacle polygon lists (one per direction)
   :param distance: Maximum drift distance (metres)
   :param progress_callback: Optional ``(completed, total, msg) -> bool``
   :return: 3D array ``[leg][direction][obstacle]`` of probabilities

   **Line:** 642 | `Source <https://github.com/axelande/OMRAT/blob/main/geometries/calculate_probability_holes.py#L642>`__


geometries.result_layers
=========================

.. function:: create_result_layers(report, structures, depths, add_to_project=True)

   Create QGIS vector layers with per-segment probability attributes.

   :param report: Drifting report dict from calculation
   :param structures: List of structure dicts
   :param depths: List of depth dicts
   :return: ``(allision_layer, grounding_layer)``


omrat_utils
============

Key data management classes:

.. class:: Traffic(omrat, widget)

   Manages the traffic data table UI and underlying data structures.

.. class:: OObject(omrat)

   Manages depth and structure obstacle layers and data.

.. class:: DriftSettings(omrat)

   Manages drift parameters (wind rose, speed, repair time).

.. class:: CausationFactors(omrat)

   Manages causation factor values.

.. class:: Distributions(omrat)

   Manages lateral traffic distribution parameters and visualisation.

.. class:: AIS(omrat)

   Manages AIS database connections and traffic data import.

.. class:: GatherData(omrat)

   Collects all data for save/load and populates from saved data.

.. class:: Storage(omrat)

   Handles project file I/O (``.omrat`` JSON format).

.. class:: ShipCategories(omrat)

   Manages ship type and size bin definitions.
