Documentation
¶
Overview ¶
Package news2 calculates the National Early Warning Score 2 (NEWS2), the Royal College of Physicians' standardised score for detecting acute clinical deterioration in adult patients.
The score aggregates six physiological parameters — respiration rate, oxygen saturation, systolic blood pressure, pulse, level of consciousness (ACVPU) and temperature — plus whether the patient is on supplemental oxygen. Calculate returns the full result including per-parameter subscores and the clinical risk category that drives escalation; CalculateScore returns just the aggregate score.
Scoring follows the RCP publication "National Early Warning Score (NEWS) 2: Standardising the assessment of acute-illness severity in the NHS" (2017). NEWS2 applies to adults aged 16 or over and is not validated for use in pregnancy. SpO2 Scale 2 must only be selected for patients with confirmed hypercapnic respiratory failure, on the direction of a competent clinical decision maker.
Disclaimer: this package is not a medical device and is not designed, certified or warranted for use in clinical care or in any system where reliability or safe operation is required. It was written to support creation and management of simulation cases. No guarantee is provided of its stability, reliability or accuracy.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidVitalSigns = errors.New("invalid vital signs")
ErrInvalidVitalSigns is wrapped by all validation errors returned from Calculate, CalculateScore and VitalSigns.Validate, so callers can detect them with errors.Is.
Functions ¶
func CalculateScore ¶
func CalculateScore(v VitalSigns) (int, error)
CalculateScore computes the aggregate NEWS2 score from vital signs. It is a convenience wrapper around Calculate for callers that only need the numeric score; prefer Calculate when the clinical risk category or the per-parameter breakdown is needed, since escalation decisions cannot be derived from the aggregate score alone.
Example ¶
package main
import (
"fmt"
"github.com/kscarlett/news2"
)
func main() {
vitals := news2.VitalSigns{
RespRate: 18,
OxygenSat: 95,
SystolicBP: 120,
Pulse: 80,
Temp: 36.8,
ConsciousnessLevel: news2.Alert,
OnOxygen: false,
}
score, err := news2.CalculateScore(vitals)
if err != nil {
fmt.Println("invalid observations:", err)
return
}
fmt.Println("NEWS2 score:", score)
}
Output: NEWS2 score: 1
Types ¶
type ConsciousnessLevel ¶
type ConsciousnessLevel int
ConsciousnessLevel represents the patient's level of consciousness on the ACVPU scale used by NEWS2.
const ( // Alert means the patient is fully awake and responsive. Patients with // chronic, baseline confusion (e.g. long-standing dementia) are recorded // as Alert unless their confusion is new or worse than baseline. Alert ConsciousnessLevel = iota // Confused means new-onset confusion or delirium, or confusion that is // worse than the patient's known baseline. Confused // Voice means the patient responds only to a verbal stimulus. Voice // Pain means the patient responds only to a painful stimulus. Pain // Unresponsive means the patient does not respond to any stimulus. Unresponsive )
func (ConsciousnessLevel) String ¶
func (c ConsciousnessLevel) String() string
String returns the string representation of the ConsciousnessLevel. Returns "Unknown" if the level is not recognized.
type Response ¶ added in v0.2.0
type Response struct {
// MonitoringFrequency is the recommended minimum frequency of
// observations.
MonitoringFrequency string
// ClinicalResponse summarises the recommended escalation of care.
ClinicalResponse string
}
Response describes the clinical response recommended by the Royal College of Physicians for a NEWS2 result: the minimum frequency of monitoring and the escalation of care.
The text is a plain-language summary of the RCP "Clinical response to the NEWS2 trigger thresholds" chart (Chart 4), keyed on the clinical risk category. It is provided for information only. Do not rely on it to direct patient care: it is not a medical device, may be summarised, abbreviated or out of date relative to current RCP guidance and local escalation policy, and the definitive source is the RCP publication itself. Local protocols always take precedence.
func ResponseFor ¶ added in v0.2.0
ResponseFor returns the RCP-recommended clinical response for a given clinical risk category, as summarised from the RCP "Clinical response to the NEWS2 trigger thresholds" chart (Chart 4).
This information is provided for reference only and is not a substitute for the RCP guidance or local escalation policy. See the Response type for the full disclaimer. An unrecognised RiskLevel returns a zero Response.
type Result ¶ added in v0.2.0
type Result struct {
// Total is the aggregate NEWS2 score (0-20).
Total int
// Per-parameter subscores, as they would appear on a NEWS2 chart.
RespRate int
Saturations int
SupplementalO2 int
SystolicBP int
Pulse int
Consciousness int
Temperature int
// RedFlag reports whether any single physiological parameter scored 3.
// On its own (with a total below 5) this triggers an urgent ward-based
// review regardless of the aggregate score.
RedFlag bool
// Risk is the clinical risk category for the aggregate score and
// red-flag state.
Risk RiskLevel
}
Result is the full outcome of a NEWS2 calculation: the aggregate score, the subscore each parameter contributed, and the escalation indicators derived from them.
func Calculate ¶ added in v0.2.0
func Calculate(v VitalSigns) (Result, error)
Calculate computes the full NEWS2 result from a set of vital signs, including the per-parameter subscores, the aggregate score, the red-flag indicator (a score of 3 in any single physiological parameter) and the resulting clinical risk category.
It returns an error without scoring if the vital signs fail validation; see VitalSigns.Validate.
Example ¶
package main
import (
"fmt"
"github.com/kscarlett/news2"
)
func main() {
vitals := news2.VitalSigns{
RespRate: 22,
OxygenSat: 93,
SystolicBP: 98,
Pulse: 112,
Temp: 38.4,
ConsciousnessLevel: news2.Alert,
OnOxygen: false,
// SpO2Scale defaults to news2.Scale1.
}
result, err := news2.Calculate(vitals)
if err != nil {
fmt.Println("invalid observations:", err)
return
}
fmt.Println("Total:", result.Total)
fmt.Println("Risk:", result.Risk)
fmt.Println("Red flag:", result.RedFlag)
}
Output: Total: 9 Risk: High Red flag: false
func (Result) Response ¶ added in v0.2.0
Response returns the RCP-recommended clinical response for the result's clinical risk category. See ResponseFor and the Response type for the important limitations on this information.
Example ¶
package main
import (
"fmt"
"github.com/kscarlett/news2"
)
func main() {
vitals := news2.VitalSigns{
RespRate: 24,
OxygenSat: 92,
SystolicBP: 100,
Pulse: 115,
Temp: 38.5,
ConsciousnessLevel: news2.Alert,
OnOxygen: true,
}
result, err := news2.Calculate(vitals)
if err != nil {
fmt.Println("invalid observations:", err)
return
}
response := result.Response()
fmt.Println("Risk:", result.Risk)
fmt.Println("Monitoring:", response.MonitoringFrequency)
}
Output: Risk: High Monitoring: continuous monitoring of vital signs
type RiskLevel ¶ added in v0.2.0
type RiskLevel int
RiskLevel is the clinical risk category that NEWS2 maps an aggregate score to. It determines the urgency of the clinical response and the minimum observation frequency (see the package documentation and README for the full thresholds-and-triggers table).
const ( // Low risk: aggregate score 0-4 with no single parameter scoring 3. // Ward-based response; routine monitoring. Low RiskLevel = iota // LowMedium risk: aggregate score below 5 but with a score of 3 in any // single parameter. Urgent ward-based review. LowMedium // Medium risk: aggregate score 5-6. Key threshold for an urgent // response by a clinician competent in assessing acute illness. Medium // High risk: aggregate score 7 or more. Emergency response, usually // including critical care assessment; continuous monitoring. High )
type SpO2Scale ¶ added in v0.2.0
type SpO2Scale int
SpO2Scale selects which NEWS2 oxygen saturation scoring scale applies to the patient. The zero value is Scale1, which is correct for the vast majority of patients.
const ( // Scale1 is the standard oxygen saturation scale, used for all patients // unless Scale2 has been explicitly prescribed. Scale1 SpO2Scale = iota // Scale2 is used only for patients with confirmed hypercapnic // respiratory failure (usually due to COPD) with a prescribed oxygen // saturation target of 88-92%. The decision to use Scale2 must be made // by a competent clinical decision maker and recorded in the patient's // notes. Scale2 )
type VitalSigns ¶
type VitalSigns struct {
// RespRate is the respiration rate in breaths per minute.
RespRate int
// OxygenSat is the peripheral oxygen saturation (SpO2) as a percentage.
OxygenSat int
// SystolicBP is the systolic blood pressure in mmHg.
SystolicBP int
// Pulse is the heart rate in beats per minute.
Pulse int
// Temp is the body temperature in degrees Celsius.
Temp float64
// ConsciousnessLevel is the patient's consciousness on the ACVPU scale.
ConsciousnessLevel ConsciousnessLevel
// OnOxygen reports whether the patient is receiving supplemental oxygen.
OnOxygen bool
// SpO2Scale selects the saturation scoring scale. The zero value is
// Scale1, the correct default for most patients; only set Scale2 when
// it has been clinically prescribed.
SpO2Scale SpO2Scale
}
VitalSigns holds one complete set of patient observations for NEWS2 scoring. All fields must be populated; Calculate and CalculateScore validate them and return an error for values that cannot be meaningfully scored, which also guards against accidentally scoring an incomplete struct. See Validate for what is checked.
func (VitalSigns) String ¶
func (v VitalSigns) String() string
String returns a string representation of the VitalSigns struct. It formats the vital signs in a human-readable way.
func (VitalSigns) Validate ¶ added in v0.2.0
func (v VitalSigns) Validate() error
Validate checks that the VitalSigns can be meaningfully scored. It is deliberately minimal: it rejects only values that cannot be a real observation — non-positive measurements (which also catches unset fields, whose zero values would otherwise silently score as a critically ill patient), an oxygen saturation above 100%, values beyond the extreme sanity bounds above, and unknown enum values. Enforcing clinically plausible ranges is left to the calling software.
It returns nil if the vital signs can be scored, or an error wrapping ErrInvalidVitalSigns describing the first invalid field found.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/kscarlett/news2"
)
func main() {
// The zero value is rejected rather than silently scored.
var vitals news2.VitalSigns
_, err := news2.Calculate(vitals)
fmt.Println(errors.Is(err, news2.ErrInvalidVitalSigns))
}
Output: true