bolster.data_sources.nisra.elective_waiting_times

NISRA Elective/Outpatient Waiting Times Module.

Provides access to Northern Ireland’s elective and outpatient waiting times statistics, covering inpatient/day case and outpatient referrals waiting by weeks-waited band, specialty, and HSC Trust.

Data is published quarterly by the Department of Health NI and covers two separate series:

  • Inpatient/Day Case Waiting Times — patients waiting by management type (Day Case or Inpatient), weeks-waited band, specialty, and HSC Trust. Data from Q1 2007-08 (quarter ending June 2007) to present.

  • Outpatient Waiting Times — referrals waiting by weeks-waited band, specialty, and HSC Trust. Data from Q1 2008-09 (quarter ending June 2008) to present.

Both series contain two sheets reflecting a system change:

  • Pre-encompass: Legacy PAS data up to March 2025 (inpatient) / March 2025 (outpatient). Inpatient pre-encompass includes additional derived aggregate columns (e.g. “> 26 weeks”) that are excluded from the long-format output.

  • encompass: Data from the new electronic patient record system, starting from South Eastern Trust in December 2023. Not directly comparable with pre-encompass data due to the system transition.

Waiting Bands (Inpatient/Day Case — weeks):

0 - 6, >6 - 13, >13 - 21, >21 - 26, >26 - 52, >52 - 65, >65 - 78, >78 - 91, >91 - 104, >104

Waiting Bands (Outpatient — weeks):

0 - 6, >6 - 9, >9 - 13 / >9 - 12*, >12 - 15, >15 - 18, >18 - 26, >26 - 39, >39 - 52, >52 - 65, >65 - 78, >78 - 91, >91 - 104, >104

(*The >9-13 / >9-12 split is a historical artefact; both columns appear but only one is populated per row.)

HSC Trusts:

Belfast, Northern, South Eastern, Southern, Western (DPC = Domiciliary/Primary Care, included in source data but typically excluded from trust-level analyses)

Data Sources:
Update Frequency:

Quarterly, published approximately 3-6 months after the quarter end.

Example

>>> from bolster.data_sources.nisra import elective_waiting_times as ewt
>>> df = ewt.get_latest_elective_waiting_times()
>>> sorted(df.columns.tolist())
['date', 'patients_waiting', 'programme_of_care', 'quarter_ending', 'specialty', 'trust', 'waiting_type', 'weeks_waited_band', 'year']
>>> ewt.validate_elective_waiting_times(df)
True
Publication Details:

Attributes

logger

DOH_BASE_URL

DOH_INPATIENT_PAGE

DOH_OUTPATIENT_PAGE

SHEET_PRE_ENCOMPASS

SHEET_ENCOMPASS

EXPECTED_TRUSTS

IP_ID_COLS

IP_BAND_COLS

OP_ID_COLS

OP_BAND_COLS

REQUIRED_COLUMNS

Functions

get_elective_waiting_times_url()

Scrape the Department of Health pages to find the latest Excel file URLs.

parse_elective_waiting_times_file(file_path)

Parse a combined elective waiting times Excel file (inpatient or outpatient).

get_latest_elective_waiting_times([force_refresh])

Download and return the latest elective waiting times data (both series).

validate_elective_waiting_times(df)

Validate that an elective waiting times DataFrame meets quality requirements.

Module Contents

bolster.data_sources.nisra.elective_waiting_times.logger[source]
bolster.data_sources.nisra.elective_waiting_times.DOH_BASE_URL = 'https://www.health-ni.gov.uk'[source]
bolster.data_sources.nisra.elective_waiting_times.DOH_INPATIENT_PAGE = 'https://www.health-ni.gov.uk/articles/inpatient-waiting-times'[source]
bolster.data_sources.nisra.elective_waiting_times.DOH_OUTPATIENT_PAGE = 'https://www.health-ni.gov.uk/articles/outpatient-waiting-times'[source]
bolster.data_sources.nisra.elective_waiting_times.SHEET_PRE_ENCOMPASS = 'Pre-encompass'[source]
bolster.data_sources.nisra.elective_waiting_times.SHEET_ENCOMPASS = 'encompass'[source]
bolster.data_sources.nisra.elective_waiting_times.EXPECTED_TRUSTS[source]
bolster.data_sources.nisra.elective_waiting_times.IP_ID_COLS = ['Management', 'Quarter Ending', 'HSC Trust', 'Specialty', 'Programme Of Care'][source]
bolster.data_sources.nisra.elective_waiting_times.IP_BAND_COLS = ['0 - 6 weeks', '> 6 - 13 weeks', '> 13 - 21 weeks', '> 21 - 26 weeks', '> 26-52 weeks', '> 52 -...[source]
bolster.data_sources.nisra.elective_waiting_times.OP_ID_COLS = ['Quarter Ending', 'HSC Trust', 'Specialty', 'Programme of Care'][source]
bolster.data_sources.nisra.elective_waiting_times.OP_BAND_COLS = ['0 - 6 Wks', '>6 - 9 Wks', '>9 - 13 Wks', '>9 - 12 Wks', '>12 - 15 Wks', '>15 - 18 Wks', '>18 -...[source]
bolster.data_sources.nisra.elective_waiting_times.REQUIRED_COLUMNS[source]
bolster.data_sources.nisra.elective_waiting_times.get_elective_waiting_times_url()[source]

Scrape the Department of Health pages to find the latest Excel file URLs.

Returns:

Dictionary with keys "inpatient" and "outpatient", each mapping to the absolute URL of the most recent quarterly Excel file.

Raises:

NISRADataNotFoundError – If either URL cannot be located.

Return type:

dict[str, str]

bolster.data_sources.nisra.elective_waiting_times.parse_elective_waiting_times_file(file_path)[source]

Parse a combined elective waiting times Excel file (inpatient or outpatient).

Reads both Pre-encompass and encompass sheets from the file, melts the weekly waiting-band columns into long format, and returns a unified DataFrame.

The parser auto-detects the file type (inpatient vs outpatient) by checking whether a Management column (present only in inpatient files) exists in the first data sheet.

Parameters:

file_path (str | pathlib.Path) – Path to an Excel file downloaded from the Department of Health inpatient or outpatient waiting times publication pages.

Returns:

  • date (datetime): Quarter-end date (e.g. 2025-12-31)

  • year (int): Calendar year of the quarter end

  • quarter_ending (datetime): Same as date

  • trust (str): HSC Trust name

  • specialty (str): Medical specialty

  • programme_of_care (str): Programme of care grouping

  • weeks_waited_band (str): Waiting band label (e.g. “0 - 6 weeks”)

  • patients_waiting (float): Number of patients/referrals in that band

  • waiting_type (str): "inpatient_day_case" or "outpatient"

For inpatient files, management ("Day Case" or "Inpatient") is also present.

Return type:

Long-format DataFrame with columns

Raises:

NISRAValidationError – If neither expected sheet is found in the file.

bolster.data_sources.nisra.elective_waiting_times.get_latest_elective_waiting_times(force_refresh=False)[source]

Download and return the latest elective waiting times data (both series).

Fetches the most recent quarterly publication for both the inpatient/day case and outpatient series, parses each into long format, and returns a combined DataFrame.

Parameters:

force_refresh (bool) – If True, bypass the on-disk cache and re-download the Excel files.

Returns:

Combined long-format DataFrame covering both inpatient/day case and outpatient waiting times. See parse_elective_waiting_times_file() for the column schema.

Raises:
  • NISRADataNotFoundError – If either publication page or Excel file cannot be located.

  • NISRAValidationError – If the downloaded data fails schema validation.

Return type:

pandas.DataFrame

bolster.data_sources.nisra.elective_waiting_times.validate_elective_waiting_times(df)[source]

Validate that an elective waiting times DataFrame meets quality requirements.

Checks that the DataFrame is non-empty, contains all required columns, and has no negative patient counts.

Parameters:

df (pandas.DataFrame) – DataFrame as returned by get_latest_elective_waiting_times() or parse_elective_waiting_times_file().

Returns:

True if all checks pass.

Raises:

NISRAValidationError – If the DataFrame is empty, missing required columns, or contains negative patients_waiting values.

Return type:

bool