Wells Criteria for Pulmonary Embolism

Estimates the probability of a PE based on pretest probability and D-dimer result

Description
Used to categorise patients clinical probability of pulmonary embolism based on pretest probability and D-dimer test result
Academic References
Wells PS, Anderson DR, Rodger M, et al. Excluding pulmonary embolism at the bedside without diagnostic imaging: management of patients with suspected pulmonary embolism presenting to the emergency department by using a simple clinical model and d-dimer. Ann Intern Med. 2001;135(2):98-107. doi:10.7326/0003-4819-135-2-200107170-00010
See: https://www.ncbi.nlm.nih.gov/pubmed/11453709
Code Version Id
fde4e08f-5ac3-4875-aca5-eeb3b5930ac0
// Copyright (C) 2023 Calcarta
module Calcarta.Calculation.Wells_criteria_for_pulmonary_embolism.Code
open Calcarta.CodeResource.Standard

type Patient = {
    [<Name("Clinical signs and symptoms of DVT")>]
    [<Description("Objectively measured leg swelling and pain with palpation in the deep-vein region")>]
    DvtSigns : bool

    [<Name("Heart Rate >100bpm")>]
    HeartRate : bool

    [<Name("Recent history of immobilisation")>]
    [<Description("Bedrest, except to access the bathroom, for ≥3 days")>]
    Immobilisation : bool

    [<Name("Surgery in the previous 4 weeks")>]
    RecentSurgery : bool

    [<Name("Previous objectively diagnosed deep venous thrombosis or pulmonary embolism")>]
    PreviousDvt : bool

    [<Name("Haemoptysis")>]
    Haemoptysis : bool

    [<Name("Malignancy")>]
    [<Description("Patients with cancer who were receiving treatment, those in whom treatment had been stopped within the past 6 months, or those who were receiving palliative care")>]
    Malignancy : bool

    [<Name("Pulmonary embolism likelihood")>]
    [<Description("Pulmonary embolism as likely as or more likely than an alternative diagnosis")>]
    PulmonaryEmbolismLikelihood : bool
}

type PretestProbability =
    | Low = 1
    | Moderate = 2
    | High = 3

type Output = {
    [<Name("Wells score")>]
    [<Unit("Points")>]
    Score : decimal

    [<Name("Pretest risk category")>]
    RiskCategory : PretestProbability

    [<Name("PE probability")>]
    [<Description("Based on statistical analysis in original paper")>]
    PeRisk : string
}

let wells_criteria_for_pulmonary_embolism (patient : Patient) = 
    let dvtSigns = if patient.DvtSigns then 3m else 0m
    let heartRate = if patient.HeartRate then 1.5m else 0m
    let immobilisation = if patient.Immobilisation || patient.RecentSurgery then 1.5m else 0m
    let previousDvt = if patient.PreviousDvt then 1.5m else 0m
    let haemoptysis = if patient.Haemoptysis then 1m else 0m
    let malignancy = if patient.Malignancy then 1m else 0m
    let pulmonaryEmbolismLikelihood = if patient.PulmonaryEmbolismLikelihood then 3m else 0m
    let score = 
        dvtSigns + 
        heartRate + 
        immobilisation + 
        previousDvt + 
        haemoptysis + 
        malignancy + 
        pulmonaryEmbolismLikelihood
    let riskCategory =
        if score < 2m then PretestProbability.Low 
        else if score <=6m then PretestProbability.Moderate
        else PretestProbability.High
    let peRisk = 
        match riskCategory with
        | PretestProbability.High -> "40.6% [CI, 28.7% to 53.7%]"
        | PretestProbability.Moderate -> "16.2% [CI, 12.5% to 20.6%]"
        | PretestProbability.Low -> "1.3% [CI, 0.5% to 2.7%]"
        | _ -> "Not defined"
    {
        Score = score
        RiskCategory = riskCategory
        PeRisk = peRisk
    }