bolster.data_sources.psni.road_traffic_collisions ================================================= .. py:module:: bolster.data_sources.psni.road_traffic_collisions .. autoapi-nested-parse:: PSNI Road Traffic Collision Statistics. Provides access to police-recorded injury road traffic collision (RTC) statistics for Northern Ireland. Data includes: - Collision records with date, location, road conditions, severity - Casualty records with age, gender, severity, road user class - Vehicle records with type, manoeuvre, driver details - Geographic breakdown by 11 policing districts (aligned with LGDs) - Historical time series from 2013 onwards Data Source: **Primary Source**: OpenDataNI - Police Recorded Injury Road Traffic Collision Statistics https://www.opendatani.gov.uk/dataset?q=road+traffic+collision PSNI collects RTC statistics in accordance with STATS20 guidance from the Department for Transport. Data covers injury collisions only (not damage-only). Published under the Open Government Licence v3.0. **PSNI Official Statistics**: https://www.psni.police.uk/about-us/our-publications-and-reports/official-statistics/road-traffic-collision-statistics Update Frequency: Annual (data available ~6 months after year end) Geographic Coverage: Northern Ireland (11 policing districts) Reference Date: Date of collision occurrence Time Coverage: 2013 to present .. rubric:: Example >>> from bolster.data_sources.psni import road_traffic_collisions >>> df = road_traffic_collisions.get_collisions() >>> 'severity' in road_traffic_collisions.get_casualties().columns True >>> summary = road_traffic_collisions.get_annual_summary() >>> 'year' in summary.columns True Attributes ---------- .. autoapisummary:: bolster.data_sources.psni.road_traffic_collisions.logger bolster.data_sources.psni.road_traffic_collisions.OPENDATANI_API bolster.data_sources.psni.road_traffic_collisions.DISTRICT_CODES bolster.data_sources.psni.road_traffic_collisions.DISTRICT_NAMES_TO_CODES bolster.data_sources.psni.road_traffic_collisions.SEVERITY_CODES bolster.data_sources.psni.road_traffic_collisions.CASUALTY_CLASS_CODES bolster.data_sources.psni.road_traffic_collisions.VEHICLE_TYPE_CODES bolster.data_sources.psni.road_traffic_collisions.DAY_OF_WEEK_CODES bolster.data_sources.psni.road_traffic_collisions.LIGHT_CONDITIONS_CODES bolster.data_sources.psni.road_traffic_collisions.WEATHER_CODES bolster.data_sources.psni.road_traffic_collisions.ROAD_SURFACE_CODES Functions --------- .. autoapisummary:: bolster.data_sources.psni.road_traffic_collisions.get_available_years bolster.data_sources.psni.road_traffic_collisions.get_collisions bolster.data_sources.psni.road_traffic_collisions.get_casualties bolster.data_sources.psni.road_traffic_collisions.get_vehicles bolster.data_sources.psni.road_traffic_collisions.get_casualties_with_collision_details bolster.data_sources.psni.road_traffic_collisions.get_annual_summary bolster.data_sources.psni.road_traffic_collisions.get_casualties_by_district bolster.data_sources.psni.road_traffic_collisions.get_casualties_by_road_user bolster.data_sources.psni.road_traffic_collisions.validate_data Module Contents --------------- .. py:data:: logger .. py:data:: OPENDATANI_API :value: 'https://admin.opendatani.gov.uk/api/3/action' .. py:data:: DISTRICT_CODES .. py:data:: DISTRICT_NAMES_TO_CODES .. py:data:: SEVERITY_CODES .. py:data:: CASUALTY_CLASS_CODES .. py:data:: VEHICLE_TYPE_CODES .. py:data:: DAY_OF_WEEK_CODES .. py:data:: LIGHT_CONDITIONS_CODES .. py:data:: WEATHER_CODES .. py:data:: ROAD_SURFACE_CODES .. py:function:: get_available_years() Get list of years with available RTC data. :returns: List of years (integers) in descending order .. rubric:: Example >>> years = get_available_years() >>> len(years) > 0 True .. py:function:: get_collisions(year = None, force_refresh = False, decode_values = True) Get collision records for a specific year. Each row represents a single road traffic collision with details about date, time, location, road conditions, and severity. :param year: Year to fetch (default: latest available) :param force_refresh: If True, bypass cache and re-download :param decode_values: If True, decode coded values to human-readable strings :returns: - year: int - ref: int (collision reference number) - district: str (policing district name if decoded) - district_code: str (original code) - month: int - day: int - weekday: str (day name if decoded) - hour: int - vehicles: int (number of vehicles) - casualties: int (number of casualties) - light_conditions: str (if decoded) - weather: str (if decoded) - road_surface: str (if decoded) - lgd_code: str (ONS LGD code) - nuts3_code: str (NUTS3 region code) :rtype: DataFrame with columns including .. rubric:: Example >>> df = get_collisions(2024) >>> 'severity' in df.columns or 'district' in df.columns True .. py:function:: get_casualties(year = None, force_refresh = False, decode_values = True) Get casualty records for a specific year. Each row represents a single casualty involved in a road traffic collision. Casualties are linked to collisions via the 'ref' column. :param year: Year to fetch (default: latest available) :param force_refresh: If True, bypass cache and re-download :param decode_values: If True, decode coded values to human-readable strings :returns: - year: int - ref: int (collision reference number for linking) - vehicle_id: int - casualty_id: int - casualty_class: str (road user type if decoded) - sex_code: int - age_group: int - severity: str ('Fatal', 'Serious', 'Slight' if decoded) - severity_code: int (1=fatal, 2=serious, 3=slight) :rtype: DataFrame with columns including .. rubric:: Example >>> df = get_casualties(2024) >>> 'severity' in df.columns True .. py:function:: get_vehicles(year = None, force_refresh = False, decode_values = True) Get vehicle records for a specific year. Each row represents a single vehicle involved in a road traffic collision. Vehicles are linked to collisions via the 'ref' column. :param year: Year to fetch (default: latest available) :param force_refresh: If True, bypass cache and re-download :param decode_values: If True, decode coded values to human-readable strings :returns: - year: int - ref: int (collision reference number for linking) - vehicle_id: int - vehicle_type: str (if decoded) - vehicle_type_code: int - driver_sex_code: int - driver_age_group: int :rtype: DataFrame with columns including .. rubric:: Example >>> df = get_vehicles(2024) >>> 'vehicle_id' in df.columns True .. py:function:: get_casualties_with_collision_details(year = None, force_refresh = False) Get casualty records merged with collision details. Combines casualty data with collision information including date, location, and road conditions. :param year: Year to fetch (default: latest available) :param force_refresh: If True, bypass cache and re-download :returns: DataFrame with casualty records enriched with collision details .. rubric:: Example >>> df = get_casualties_with_collision_details(2024) >>> 'severity' in df.columns True .. py:function:: get_annual_summary(years = None, force_refresh = False) Get annual summary statistics across multiple years. Provides aggregated collision and casualty counts by year, useful for trend analysis. :param years: List of years to include (default: all available) :param force_refresh: If True, bypass cache and re-download :returns: - year: int - collisions: int (total collisions) - casualties: int (total casualties) - fatal: int (fatal casualties) - serious: int (serious injuries) - slight: int (slight injuries) - fatalities_per_100_collisions: float :rtype: DataFrame with columns .. rubric:: Example >>> summary = get_annual_summary() >>> 'fatal' in summary.columns True .. py:function:: get_casualties_by_district(year = None, force_refresh = False) Get casualty counts by policing district. :param year: Year to fetch (default: latest available) :param force_refresh: If True, bypass cache and re-download :returns: - district: str (policing district name) - lgd_code: str (ONS LGD code) - collisions: int - casualties: int - fatal: int - serious: int - slight: int :rtype: DataFrame with columns .. rubric:: Example >>> by_district = get_casualties_by_district(2024) >>> 'district' in by_district.columns True .. py:function:: get_casualties_by_road_user(year = None, force_refresh = False) Get casualty counts by road user type. :param year: Year to fetch (default: latest available) :param force_refresh: If True, bypass cache and re-download :returns: - casualty_class: str (road user type) - casualties: int - fatal: int - serious: int - slight: int - fatality_rate: float (fatal / total %) :rtype: DataFrame with columns .. rubric:: Example >>> by_user = get_casualties_by_road_user(2024) >>> 'casualty_class' in by_user.columns True .. py:function:: validate_data(df, data_type) Validate RTC data integrity. :param df: DataFrame to validate :param data_type: Type of data ('collision', 'casualty', or 'vehicle') :returns: True if validation passes :raises PSNIValidationError: If validation fails