bolster.data_sources.nisra.deaths ================================= .. py:module:: bolster.data_sources.nisra.deaths .. autoapi-nested-parse:: NISRA Weekly Death Registrations Data Source. Provides access to weekly death registration statistics for Northern Ireland with breakdowns by: - Demographics (age, sex) - Geography (Local Government Districts) - Place of death (hospital, home, care home, etc.) Data is based on registration date, not death occurrence date. Most deaths are registered within 5 days in Northern Ireland. Data Source: **Mother Page**: https://www.nisra.gov.uk/statistics/death-statistics/weekly-death-registrations-northern-ireland This page lists all weekly death registration publications in reverse chronological order (newest first). The module automatically scrapes this page to find the current year's publication (e.g., "Weekly Death Registrations in Northern Ireland, 2025"), then downloads the latest weekly Excel file from that publication's detail page. The weekly files are cumulative, containing all weeks for the year to date. This ensures the module always retrieves the most recent data without hardcoding week numbers or dates. Update Frequency: Weekly (published Fridays for week ending previous Friday) Geographic Coverage: Northern Ireland .. rubric:: Example >>> from bolster.data_sources.nisra import deaths >>> # Get latest demographics breakdown >>> df = deaths.get_latest_deaths(dimension='demographics') >>> sorted(df.columns.tolist()) ['age_range', 'deaths', 'sex', 'week_ending'] >>> len(df) > 0 True Attributes ---------- .. autoapisummary:: bolster.data_sources.nisra.deaths.logger bolster.data_sources.nisra.deaths.WEEKLY_DEATHS_LANDING_PAGE bolster.data_sources.nisra.deaths.WEEKLY_DEATHS_BASE_URL bolster.data_sources.nisra.deaths.HISTORICAL_DEATHS_URL bolster.data_sources.nisra.deaths.DimensionType Functions --------- .. autoapisummary:: bolster.data_sources.nisra.deaths.get_latest_weekly_deaths_url bolster.data_sources.nisra.deaths.parse_deaths_totals bolster.data_sources.nisra.deaths.parse_deaths_demographics bolster.data_sources.nisra.deaths.parse_deaths_geography bolster.data_sources.nisra.deaths.parse_deaths_place bolster.data_sources.nisra.deaths.parse_deaths_file bolster.data_sources.nisra.deaths.get_latest_deaths bolster.data_sources.nisra.deaths.get_historical_deaths bolster.data_sources.nisra.deaths.get_combined_deaths bolster.data_sources.nisra.deaths.validate_deaths_data Module Contents --------------- .. py:data:: logger .. py:data:: WEEKLY_DEATHS_LANDING_PAGE :value: 'https://www.nisra.gov.uk/publications/weekly-death-registrations-northern-ireland-{year}' .. py:data:: WEEKLY_DEATHS_BASE_URL :value: 'https://www.nisra.gov.uk/statistics/death-statistics/weekly-death-registrations-northern-ireland' .. py:data:: HISTORICAL_DEATHS_URL :value: 'https://www.nisra.gov.uk/publications/historical-final-weekly-deaths-data' .. py:data:: DimensionType .. py:function:: get_latest_weekly_deaths_url() Scrape NISRA mother page to find the latest weekly deaths file. Navigates the publication structure: 1. Scrapes mother page for current year publication 2. Follows link to publication detail page 3. Finds latest weekly Excel file 4. Extracts and validates week ending date :returns: URL of the latest weekly deaths Excel file :raises NISRADataNotFoundError: If no file found .. py:function:: parse_deaths_totals(file_path) Parse weekly totals with COVID-19, flu/pneumonia, and excess deaths from weekly deaths file. Extracts Table 1a and creates a flat table with columns: - week_ending: Friday of the reporting week - week_number: Week number in the year - observed_deaths: Total deaths registered in the week - deaths_same_week_2024: Deaths in corresponding week in 2024 - expected_deaths_5yr: Average deaths over previous 5 years (2020-2024) - expected_deaths_ons: Average deaths using ONS methodology (2019, 2021-2024) - excess_deaths_5yr: Observed minus expected (5yr method) - expected_deaths_current: Expected deaths using current methodology - excess_deaths_current: Observed minus expected (current method) - flu_pneumonia_deaths: Deaths mentioning flu or pneumonia - covid_deaths: Deaths mentioning COVID-19 :param file_path: Path to the weekly deaths Excel file :returns: DataFrame with weekly totals and disease-specific deaths :raises NISRAValidationError: If data validation fails .. py:function:: parse_deaths_demographics(file_path) Parse demographics dimension (age, sex) from weekly deaths file. Extracts Table 2 and creates a flat table with columns: - week_ending: Friday of the reporting week - sex: Total, Male, or Female - age_range: All, 0-14, 15-44, 45-64, 65-74, 75-84, 85+ - deaths: Count of deaths :param file_path: Path to the weekly deaths Excel file :returns: DataFrame with demographics breakdown :raises NISRAValidationError: If data validation fails .. py:function:: parse_deaths_geography(file_path) Parse geography dimension (Local Government Districts) from weekly deaths file. Extracts Table 3 and creates a flat table with columns: - week_ending: Friday of the reporting week - lgd: Local Government District name - deaths: Count of deaths :param file_path: Path to the weekly deaths Excel file :returns: DataFrame with geography breakdown :raises NISRAValidationError: If data validation fails .. py:function:: parse_deaths_place(file_path) Parse place of death dimension from weekly deaths file. Extracts Table 4 and creates a flat table with columns: - week_ending: Friday of the reporting week - place_of_death: Hospital, Care/Nursing Home, Hospice, Home, Other - deaths: Count of deaths :param file_path: Path to the weekly deaths Excel file :returns: DataFrame with place of death breakdown :raises NISRAValidationError: If data validation fails .. py:function:: parse_deaths_file(file_path, dimension = 'all') Parse weekly deaths file for one or all dimensions. :param file_path: Path to the weekly deaths Excel file :param dimension: Which dimension(s) to parse: - 'totals': Weekly totals with COVID, flu/pneumonia, excess deaths - 'demographics': Age and sex breakdown - 'geography': Local Government Districts - 'place': Place of death - 'all': All dimensions (returns dict) :returns: DataFrame for single dimension, or dict of DataFrames for 'all' .. rubric:: Example >>> url = get_latest_weekly_deaths_url() >>> path = download_file(url, cache_ttl_hours=24*7) >>> data = parse_deaths_file(path, dimension='all') >>> sorted(data.keys()) ['demographics', 'geography', 'place', 'totals'] .. py:function:: get_latest_deaths(dimension = 'all', force_refresh = False) Get the latest weekly deaths data. :param dimension: Which dimension(s) to retrieve :param force_refresh: Force re-download even if cached :returns: DataFrame or dict of DataFrames depending on dimension .. rubric:: Example >>> df = get_latest_deaths(dimension='demographics') >>> sorted(df.columns.tolist()) ['age_range', 'deaths', 'sex', 'week_ending'] >>> len(df) > 0 True .. py:function:: get_historical_deaths(years = None, force_refresh = False, include_age_breakdowns = False) Get historical weekly deaths data (2011-2024). Downloads and parses the NISRA historical weekly deaths file which contains final (not provisional) data for multiple years. Includes total deaths, respiratory deaths, COVID-19 deaths, flu/pneumonia deaths, and age breakdowns. :param years: List of years to include (default: all available years) :param force_refresh: Force re-download even if cached :param include_age_breakdowns: If True, returns dict with 'totals' and 'age_breakdowns' DataFrames If False (default), returns only totals DataFrame :returns: DataFrame with columns: - year: Year - week_number: Week number in year - week_ending: Friday of the reporting week - total_deaths: Total deaths registered in week - expected_deaths_5yr: Average deaths over previous 5 years - excess_deaths: Observed minus expected deaths - respiratory_deaths_involving: Deaths involving respiratory diseases - flu_pneumonia_deaths_involving: Deaths involving flu/pneumonia - covid_deaths_involving: Deaths involving COVID-19 - covid_deaths_due_to: Deaths due to COVID-19 (underlying cause) If include_age_breakdowns=True: Dict with keys: - 'totals': DataFrame as above - 'age_breakdowns': DataFrame in long format with columns: - year: Year - week_ending: Friday of the reporting week - age_range: Age range label (e.g., '0-7 days', '15-44', '85+') - deaths: Death count for this age range :rtype: If include_age_breakdowns=False .. rubric:: Example >>> # Get totals only >>> df = get_historical_deaths() >>> 'total_deaths' in df.columns True >>> # Get totals with age breakdowns >>> data = get_historical_deaths(years=[2020, 2021], include_age_breakdowns=True) >>> sorted(data.keys()) ['age_breakdowns', 'totals'] >>> totals = data['totals'] >>> age_data = data['age_breakdowns'] >>> # Analyze age distribution >>> age_summary = age_data.groupby('age_range')['deaths'].sum() >>> len(age_summary) > 0 True .. py:function:: get_combined_deaths(years = None, include_current_year = True, force_refresh = False) Get combined historical and current year deaths data. Combines the historical deaths file (2011-2024) with the current year's provisional data to give a complete time series including the most recent weeks. :param years: List of years to include from historical data (default: last 5 years + current) :param include_current_year: Include current year provisional data (default: True) :param force_refresh: Force re-download of both historical and current files :returns: - year: Year - week_number: Week number in year - week_ending: Friday of the reporting week - total_deaths: Total deaths registered in week - covid_deaths: COVID-19 deaths (from current year) or covid_deaths_involving (historical) - flu_pneumonia_deaths: Flu/pneumonia deaths - excess_deaths: Excess deaths (observed - expected) - data_source: 'historical' or 'current' :rtype: DataFrame with columns .. rubric:: Example >>> df = get_combined_deaths(years=[2022, 2023, 2024]) >>> 'total_deaths' in df.columns True >>> 'data_source' in df.columns True .. py:function:: validate_deaths_data(df) Validate NISRA deaths data integrity. :param df: DataFrame from get_latest_deaths or parse_deaths_file :returns: True if validation passes, False otherwise