openEHR logo

openEHR Process Examples

Issuer: openEHR Specification Program

Release: PROC latest

Status: DEVELOPMENT

Revision: [latest_issue]

Date: [latest_issue_date]

Keywords: process, task planning, decision logic, examples, workflow

openEHR components
© 2017 - 2021 The openEHR Foundation

The openEHR Foundation is an independent, non-profit foundation, facilitating the sharing of health records by consumers and clinicians via open specifications, clinical models and open platform implementations.

Licence

image Creative Commons Attribution-NoDerivs 3.0 Unported. https://creativecommons.org/licenses/by-nd/3.0/

Support

Issues: Problem Reports
Web: specifications.openEHR.org

Amendment Record

Issue Details Raiser Completed

PROC Release 1.5.0

PROC Release 1.0.0

0.1.12

Update perinatal care DLM.

D S Alves

18 Nov 2020

0.1.1

Replace 'manual notification' callback by normal Handoff followed by manual notification Task wait state.

M Polajnar,
T Beale

16 Apr 2020

0.1.0

Initial writing.

T Beale,
B Næss

25 Apr 2019

Acknowledgements

Contributors

  • Danielle S Alves, RN, midwife, Federal University of Pernambuco (UFPE), Brazil

  • Bjørn Næss, DIPS, Norway

Support

The work reported in this specification has been funded by the following organisations:

  • DIPS, Norway

  • Marand d.o.o., Slovenia

Trademarks

  • 'openEHR' is a trademark of the openEHR Foundation.

  • 'OMG' is a trademark of the Object Management Group.

1. Preface

1.1. Purpose

This document contains elaborated examples of the openEHR Process framework, including Task Plans and Decision Logic Modules, with diagrams in TP-VML.

The intended audience includes:

  • Plan and Guideline authors;

  • Tool vendors.

Prerequisite documents for reading this document include:

1.3. Status

This specification is in the DEVELOPMENT state. The development version of this document can be found at https://specifications.openehr.org/releases/PROC/latest/process_examples.html.

Known omissions or questions are indicated in the text with a 'to be determined' paragraph, as follows:

TBD: (example To Be Determined paragraph)

1.4. Feedback

Feedback may be provided on the process specifications forum.

Issues may be raised on the specifications Problem Report tracker.

To see changes made due to previously reported issues, see the PROC component Change Request tracker.

2. Overview

2.1. Draw.io Tool mode

The following files can be downloaded and then imported into draw.io as libraries to provide a working palette for TP-VML diagrams.

3. Teamwork

The examples in this section illustrate the use of TP for team-based work plans, including hand-offs, callbacks and other kinds of coordination.

3.1. Out-patient Eye Clinic Encounter

This example is based on the original description of DIPS Eye encounter example.

outpatient eye clinic
Figure 1. Outpatient eye clinic encounter

3.1.1. Plan Overview

As for all Plans defined in the Task Planning formalism, it must be remembered that the Plan definition above is what the TP engine executes. It is the result of the execution (including worker allocation and communication, which is not shown in the definition) that causes workers in the real world to do things. Additionally, what the TP engine knows about the real world is limited to what it is told - many actions and events can occur outside the TP computing environment that will remain unknown to the system unless it is informed (e.g. by Manual notification).

The Work Plan consists of two top-level Task Plans, one for the patient and one for the clinic administrator / reception. The latter has two sub-plans linked by hand-off Tasks.

The purpose of the patient top-level Task Plan is to allow the system to notify the patient of the visit, via a reminder on the day of the visit, or some fixed time beforehand. The driving event is the calendar appointment, which is waited on by both the patient and the clinic admin Task Plans. It is assumed that longer term reminders, opportunities for changing appointments and so on are managed by another system that see the same calendar events, and is responsible for setting the calendar events in the first place. Thus, in the model above, the patient top-level plan is not really necessary (he/she will be notified by the appointment system), and is mainly included for purposes of demonstration.

3.1.2. Detailed Description

The main work of the Work Plan is in the other three Task Plans, which essentially encode the following logic:

Clinic Administrator:

  • clinic has a live Task Plan waiting on appointment A for patient P, at 2019-02-15 09:30:00;

  • when this calendar timepoint is reached, the TP system 'opens' the appointment via a System Request to the clinic appointment system (details not shown);

  • WAIT: the clinic Task Plan enters a new wait state for patient P, for appointment A;

Patient:

  • patient arrives at clinic (modelled as a Manual notification);

Clinic Administrator:

  • receive patient, record presence;

  • Hand-off: pass to consultation (e.g. send to waiting area);

  • WAIT: until manual notification (patient returns)

Nurse:

  • receive patient & check EMR

  • review eye function, decide on whether to send to doc or not:

    • EITHER: return to reception

    • OR: pass to doctor

Specialist:

  • receive patient and check EMR

  • perform examination

  • update EMR

  • send patient back to reception.

4. Order Management

The examples in this section illustrate the use of TP for order management, where openEHR Instructions and Actions (or other non-openEHR equivalents) are created and tracked.

4.1. Order Coordination

This example is based on a standard Moscow City clinic protocol, and covers a 12 month period.

order coordination
Figure 2. GP order coordination

4.1.1. Plan Overview

The Work Plan shown above defines the tasks for a 'standard health check' that includes a chest x-ray, a full blood panel and a hypertension checkup. The Plan executes over the periof a year, and consists of a health coordinator creating orders for the three items, via UI forms. The result of creating these orders will be the creation of a normal Composition and Instruction in the openEHR EHR for the patient. At some later point in time, the coordinator will action these orders, which will cause the EHR data to be used to create appropriate API calls / messages to the relevant target systems (radiology clinic, pathology lab, consultant) that will further cause appointments and attendances in the normal way by the patient. Each of these 'execute order' Tasks will block and wait for appropriate callbacks resulting from each of the orders being fulfilled and corresponding Actions being committed to the EHR (or else timeouts, if nothing happens). With the received results, the coordinator creates a health summary for the patient and commits that to the EHR.

4.1.2. Detailed Description

TBD

5. Multi-drug Chemotherapy

This section illustrates multi-drug chemotherapy with complex dosing and timing arrangements.

This example is based on the version of RCHOPS-21 documented by NHS Thames Valley Cancer Network.

5.1. Limitations

The following elements of the plan are not yet included (mainly for brevity of the example):

  • Vincristine dose modification due to hepatic impairment;

  • Concurrent meds only shown in summarised form;

  • Exception pathways to handle patient reactions not shown.

5.2. Plan Definition

The following shows the pre-medication phase.

RCHOPS21 pre
Figure 3. RCHOPS21 pre-med phase

The following shows the main regime, including conditional addition of Rituximab / methotrexate for high IPI patients.

RCHOPS21 admin
Figure 4. RCHOPS21 administration phase

5.3. RCHOPS21 Decision Logic Module

dlm RCHOPS21

language
    original_language = <[ISO_639-1::en]>

description
    lifecycle_state = <"unmanaged">
    original_author = <
        ["name"] = <"Dr Spock">
        ["organisation"] = <"Acme healthcare">
        ["date"] = <"2020-03-22">
    >
    details = <
        ["en"] = <
            language = <[ISO_639-1::en]>
            purpose = <"NHS CHOPS-21 chemotherapy guideline ....">
        >
    >

use
    BSA: Body_surface_area

preconditions
    has_lymphoma_diagnosis

reference
    paracetamol_dose: Quantity = 1g
    chlorphenamine_dose: Quantity = 10mg
    prednisolone_dose_per_m2: Quantity = 40mg
    rituximab_dose_per_m2: Quantity = 375mg
    doxorubicin_dose_per_m2: Quantity = 50mg
    vincristine_dose_per_m2: Quantity = 1.4mg
    cyclophosphamide_dose_per_m2: Quantity = 750mg
    cycle_period: Duration = 3w
    cycle_repeats: Integer = 6

input -- State

    has_lymphoma_diagnosis: Boolean
        time_window = tw_current_episode

input -- Tracked state

    staging: Terminology_term «ann_arbor_staging»
        currency = 30 days
        time_window = tw_current_episode

    has_metastases: Boolean
        currency = 30 days
        time_window = tw_current_episode

    neutrophils: Quantity
        currency = 3d
        ranges =
            ----------------------------------
            [normal]:      |>1 x 10^9/L|,
            [low]:         |0.5 - 1 x 10^9/L|,
            [very_low]:    |<0.5 x 10^9/L|
            ----------------------------------
        ;

    platelets: Quantity
        currency = 12h
        ranges =
            ----------------------------------
            [normal]:      |>75 x 10^9/L|,
            [low]:         |50 - 74 x 10^9/L|,
            [very_low]:    |<50 x 10^9/L|
            ----------------------------------
        ;

    bilirubin: Quantity
        currency = 12h
        ranges =
            ----------------------------------
            [normal]:      |<20 mmol/L|,
            [high]:        |20 - 51 mmol/L|,
            [very_high]:   |51 - 85 mmol/L|,
            [crit_high]:   |>85 mmol/L|
            ----------------------------------
        ;

    gfr: Quantity
        currency = 24h
        ranges =
            ----------------------------------
            [normal]:      |>20 mL/min|,
            [low]:         |10 - 20 mL/min|,
            [very_low]:    |<10 mL/min|
            ----------------------------------
        ;

    ldh: Quantity
        currency = 24h
        ranges =
            ----------------------------------
            [normal]:      |>20 mL/min|,
            [low]:         |10 - 20 mL/min|,
            [very_low]:    |<10 mL/min|
            ----------------------------------
        ;

rules -- Conditions

    high_ipi:
        Result := ipi_risk ∈ {[ipi_high_risk], [ipi_intermediate_high_risk]}

rules -- Main

    |
    | patient fit to undertake regime
    |
    patient_fit:
        Result := not
            (platelets.in_range ([very_low]) or
             neutrophils.in_range ([very_low]))

    prednisolone_dose: Quantity
        Result := prednisolone_dose_per_m2 * BSA.bsa_m2

    rituximab_dose: Quantity
        Result := rituximab_dose_per_m2 * BSA.bsa_m2

    doxorubicin_dose: Quantity
        Result := doxorubicin_dose_per_m2 * BSA.bsa_m2
            * case bilirubin.range in
                ===================
                [high]:        0.5,
                [very_high]:   0.25,
                [crit_high]:   0.0
                ===================
            ;

    |
    | TODO: hepatic impairment dose modification
    |
    vincristine_dose: Quantity
        Result := vincristine_dose_per_m2 * BSA.bsa_m2

    |
    | CHECK: is low platelets and GFR dose modification
    | cumulative?
    |
    cyclophosphamide_dose: Quantity
        Result := cyclophosphamide_dose_per_m2 * BSA.bsa_m2
            * case platelets.range in
                ===================
                [normal]:      1,
                [low]:         0.75
                ===================
            * case gfr.range in {
                ===================
                [normal]:      1,
                [low]:         0.75,
                [very_low]:    0.5
                ===================
            ;

    |
    | International Prognostic Index
    | ref: https:|en.wikipedia.org/wiki/International_Prognostic_Index
    |
    | One point is assigned for each of the following risk factors:
    |     Age greater than 60 years
    |     Stage III or IV disease
    |     Elevated serum LDH
    |     ECOG/Zubrod performance status of 2, 3, or 4
    |     More than 1 extranodal site
    |
    | The sum of the points allotted correlates with the following risk groups:
    |     Low risk (0-1 points) - 5-year survival of 73%
    |     Low-intermediate risk (2 points) - 5-year survival of 51%
    |     High-intermediate risk (3 points) - 5-year survival of 43%
    |     High risk (4-5 points) - 5-year survival of 26%
    |
    ipi_raw_score: Integer
        Result.add (
            ---------------------------------------------
            age > 60                             ? 1 : 0,
            staging ∈ {[stage_III], [stage_IV]} ? 1 : 0,
            ldh.in_range ([normal])              ? 1 : 0,
            ecog > 1                             ? 1 : 0,
            extranodal_sites > 1                 ? 1 : 0
            ---------------------------------------------
        )

    ipi_risk: Terminology_code
        Result :=
            case ipi_raw_score in
                =======================================
                |0..1|  : [ipi_low_risk],
                |2|     : [ipi_intermediate_low_risk],
                |3|     : [ipi_intermediate_high_risk],
                |4..5|  : [ipi_high_risk];
                =======================================
            ;

terminology
    term_definitions = <
        ["en"] = <
            ["paracetamol_dose"] = <
                text = <"paracetamol dose">
                description = <"paracetamol base dose level per sq. m of BSA">
            >
            ["chlorphenamine_dose"] = <
                text = <"chlorphenamine dose">
                description = <"chlorphenamine base dose level per sq. m of BSA">
            >
            ...
            ["staging"] = <
                text = <"Cancer staging">
                description = <"Cancer staging (Ann Arbor system)">
            >
            ["has_metastases"] = <
                text = <"Metastatic status">
                description = <"Status of metastasis of cancer">
            >
            ...
            ["neutrophils"] = <
                text = <"neutrophils">
                description = <"neutrophils level">
            >
            ["platelets"] = <
                text = <"platelets">
                description = <"platelets level">
            >
            ...
            ["ipi_low_risk"] = <
                text = <"low risk: 5y survival - 73%">
                description = <"..">
            >
            ["ipi_intermediate_low_risk"] = <
                text = <"intermediate-low risk: 5y survival - 51%">
                description = <"..">
            >
            ["ipi_intermediate_high_risk"] = <
                text = <"intermediate-high risk: 5y survival - 43%">
                description = <"...">
            >
            ["ipi_high_risk"] = <
                text = <"high risk: 5y survival - 26%">
                description = <"...">
            >
        >
    >

6. Antenatal Care

The following pregnancy care DLM was developed by Danielle S Alves (RN, midwife) as part of her PhD thesis at Federal University of Pernambuco (UFPE), Brazil.

6.1. Work Plan

The following Work Plan is the standard risk assessment for an antenatal visit.

prenatal risk assessment2
Figure 5. Pre-natal risk assessment Work Plan

6.2. Pregnancy Risk Assessment DLM

dlm ruleset Obstetric_pregnancy

preconditions

    is_pregnant

types

    Risk_value ::= Ordinal
        map =
            -------------------
            [emergency]:    2,
            [high_risk]:    1,
            [low_risk]:     0
            -------------------
        ;

input -- State

    is_type1_diabetic: Boolean

    previous_obstetric_hypertension: Boolean

    previous_pre_eclampsia: Boolean

    previous_eclampsia: Boolean

    previous_gestational_diabetes: Boolean

    family_history_of_diabetes: Boolean

    race_related_diabetes_risk: Boolean

    |
    | Macrosomic baby from any previous pregnancy
    |
    previous_macrosomic_baby: Boolean

    is_pregnant: Boolean

    has_gestational_diabetes: Boolean

    has_pregnancy_hypertension: Boolean

    has_pre_eclampsia: Boolean

    has_eclampsia: Boolean

    has_anaemia_of_pregnancy: Boolean

input -- Tracked State

    bmi: Quantity
        currency = 30d
        ranges =
            ------------------------------------
            [high]:      |>30 kg/m^2|,
            [normal]:    |>=15 .. <= 30 kg/m^2|,
            [low]:       |< 15 kg/m^2|
            ------------------------------------
        ;

    |
    | Possible values:
    |   |premature rupture|,
    |   |polyhydramnios|, |oligohydramnios|,
    |   |severe polyhydramnios|, |severe oligohydramnios|
    |
    amniotic_fluid_state: Terminology_term
        currency = 24h

    uterine_fundal_height: Quantity
        currency = 24h

    vaginal_blood_flow: Quantity
        currency = 30mins
        ranges =
            [critical_high]: |> 500 mL/hr|

    |
    | Assessment of vaginal bleeding, pain, confirm
    | with ultrasound. Result value-set includes
    | |placenta previa|, |risk of miscarriage|,
    | |ectopic pregnancy| etc
    |
    vaginal_physical_exam_assessment: Terminology_term
        currency = 48h

    vomiting_assessment: Terminology_term
        currency = 48h

    ultrasound_finding: Terminology_term
        currency = 48h

    amniotic_volume: Real
        currency = 24h
        ranges =
            ------------------------------------
            [polyhydramnios]:    |> 14|,
            [normal]:            |>= 5 .. <= 14|,
            [oligohydramnios]:   |< 5|
            ------------------------------------
        ;

    labour_onset_assessment: Terminology_term
        currency = 24h

rules

    |
    | Possible values:
    |    |excluded|, |anaemia of pregnancy|
    |
    anaemia_type: Terminology_term
        Result := not has_anaemia_of_pregnancy ? [excluded] : [anaemia_of_pregnancy]

    |
    | Return the highest level risk of any of the
    | assessed risks
    |
    effective_risk: Risk_value
        Result := Result.max ({fundal_height_related_risk,
                    amniotic_fluid_risk,
                    vaginal_bleeding_related_risk,
                    hypertension_risk,
                    hyperemesis_related_risk,
                    gestational_diabetes_risk,
                    anaemia_risk})
        ;

    ultrasound_required: Boolean
        Result := fundal_height_related_risk != [low_risk] or
                amniotic_fluid_risk != [low_risk] or
                vaginal_bleeding_related_risk != [low_risk]

    anaemia_risk: Risk_value
        Result := case anaemia_type in
            ============================================
            [severe_anaemia_of_pregnancy]:  [emergency],
            --------------------------------------------
            [anaemia_of_pregnancy]:         [high_risk],
            --------------------------------------------
            *:                              [low_risk]
            ============================================
        ;

    fundal_height_related_risk: Risk_value
        Result := case ultrasound_finding in
            =================================================
            [interuterine_growth_retardation],
            [multiple_pregnancy],
            [macrosomia]:                        [high_risk],
            -------------------------------------------------
            *:                                   [low_risk]
            =================================================
        ;

    amniotic_fluid_risk: Risk_value
        Result := case amniotic_fluid_state in
            =========================================
            [premature_rupture],
            [severe_oligohydramnios],
            [severe_polyhydramnios]:     [emergency],
            -----------------------------------------
            [polyhydramnios],
            [oligohydramnios]:           [high_risk],
            -----------------------------------------
            *:                            [low_risk]
            =========================================
        ;

    vaginal_bleeding_related_risk: Risk_value
        Result := case vaginal_physical_exam_assessment in
            =================================================
            [ectopic_pregnancy],
            [gestational_trophoblastic_disease]: [emergency],
            -------------------------------------------------
            [placenta_previa],
            [risk_of_miscarriage]:               [high_risk],
            -------------------------------------------------
            *:                                   [low_risk]
            =================================================
        ;

    gestational_diabetes_risk: Risk_value
        Result := choice of
            =================================================
            bmi.in_range ([high]) or
            previous_macrosomic_baby or
            previous_gestational_diabetes or
            family_history_of_diabetes or
            race_related_diabetes_risk or
            has_gestational_diabetes or
            is_type1_diabetic:                  [high_risk],
            -------------------------------------------------
            *:                                  [low_risk]
            =================================================
        ;

    hypertension_risk: Risk_value
        Result := choice of
            =================================================
            has_pre_eclampsia or
            has_eclampsia:                      [emergency],
            -------------------------------------------------
            previous_obstetric_hypertension or
            previous_pre_eclampsia or
            previous_eclampsia or
            has_pregnancy_hypertension:         [high_risk],
            -------------------------------------------------
            *:                                  [low_risk]
            =================================================
        ;

   labour_onset_pathway: Terminology
        Result := case labour_onset_assessment in
            ====================================
            [placental_abruption],
            [premature_labour]:    [emergency],
            ------------------------------------
            [onset_of_labour],
            [labour_first_stage]:  [maternity],
            ------------------------------------
            *:                     [observation]
            ====================================
        ;

terminology
    term_definitions = <
        ["en"] = <
            ["low_risk"] = <
                text = <"Normal obstetric care">
                description = <"...">
            >
            ["emergency"] = <
                text = <"Obstetric emergency">
                description = <"...">
            >
            ["high_risk"] = <
                text = <"Refer to high risk care">
                description = <"...">
            >
            ["premature_rupture"] = <
                text = <"Premature rupture of membranes">
                description = <"...">
            >
            ["polyhydramnios"] = <
                text = <"polyhydramnios">
                description = <"...">
            >
            ["oligohydramnios"] = <
                text = <"oligohydramnios">
                description = <"...">
            >
            ["severe polyhydramnios"] = <
                text = <"severe polyhydramnios">
                description = <"...">
            >
            ["severe oligohydramnios"] = <
                text = <"severe oligohydramnios">
                description = <"...">
            >
            ["severe_anaemia_of_pregnancy"] = <
                text = <"anaemia of pregnancy, severe">
                description = <"...">
            >
            ["anaemia_of_pregnancy"] = <
                text = <"anaemia of pregnancy">
                description = <"...">
            >
            ["amniotic_fluid_risk"] = <
                text = <"Risk of pregnancy-related amniotic fluid">
                description = <"...">
            >
            ["hypertension_risk"] = <
                text = <"Risk of pregnancy-related hypertension">
                description = <"...">
            >
            ["diabetes_risk"] = <
                text = <"Risk of pregnancy-related diabetes">
                description = <"...">
            >
            ["anaemia_risk"] = <
                text = <"Risk of pregnancy-related anaemia">
                description = <"...">
            >
            ["previous_macrosomic_baby"] = <
                text = <"Baby weighing 4.5kg or above">
                description = <"...">
            >
            ["previous_gestational_diabetes"] = <
                text = <"xxx">
                description = <"...">
            >

            ["ectopic_pregnancy"] = <
                text = <"Ectopic pregnancy">
                description = <"...">
            >
            ["gestational_trophoblastic_disease"] = <
                text = <"Gestational trophoblastic disease">
                description = <"...">
            >
            ["previous_macrosomic_baby"] = <
                text = <"Baby weighing 4.5kg or above">
                description = <"...">
            >
            ["previous_gestational_diabetes"] = <
                text = <"xxx">
                description = <"...">
            >

        >
    >

7. Breast Cancer Decision Protocol

7.1. Decision Logic Module

dlm guideline Oncology_breast_cancer.v0.5.0

input -- State

    has_heart_failure_class_II: Boolean

    has_heart_failure_class_III: Boolean

    has_heart_failure_class_IV: Boolean

    has_allergy_to_taxanes: Boolean

input -- Tracked State

    tnm_t: String
        currency = 60 days

    tnm_n: String
        currency = 60 days

    tnm_m: String
        currency = 60 days

    tnm_g: String
        currency = 60 days

    estrogen_receptor: Terminology_term «pos_neg_vs»
        currency = 60 days

    progesterone_receptor:  Terminology_term «pos_neg_vs»
        currency = 60 days

    her2_expression: Terminology_term «pos_neg_vs»
        currency = 60 days

    ki67: Quantity
        currency = 60 days
        ranges =
            -------------------
            [high]:   |>= 14%|,
            [normal]: |< 14%|
            -------------------
        ;

    ejection_fraction: Quantity
        currency = 60 days
        ranges =
            --------------------
            [normal]:  |>= 40%|,
            [low]  :   |< 40%|
            --------------------
        ;

rules -- Conditions

    er_negative:
        Result := estrogen_receptor = [negative]

    er_positive:
        Result := estrogen_receptor = [positive]

    pr_negative:
        Result := progesterone_receptor = [negative]

    pr_positive:
        Result := progesterone_receptor = [positive]

    her2_negative:
        Result := her2_expression = [negative]

    her2_positive:
        Result := her2_expression = [positive]

    has_non_class_I_heart_failure:
        Result := has_heart_failure_class_II
                  or has_heart_failure_class_III
                  or has_heart_failure_class_IV

    anthracyclines_contraindicated:
        Result := has_transmural_MI
            or ejection_fraction.in_range ([low])
            or has_non_class_I_heart_failure

    taxanes_contraindicated:
        Result := is_type1_diabetic
            or has_allergy_to_taxanes
            or has_intolerance ([taxanes])

rules -- Guideline

    molecular_subtype: Terminology_term
        Result :=
            choice of
                =========================================================
                er_positive and
                her2_negative and
                not ki67.in_range ([high]):    [luminal_A],
                ---------------------------------------------------------
                er_positive and
                her2_negative and
                ki67.in_range ([high]):        [luminal_B_HER2_negative],
                ---------------------------------------------------------
                er_positive and
                her2_positive:                 [luminal_B_HER2_positive],
                ---------------------------------------------------------
                er_negative and
                pr_negative and
                her2_positive and
                ki67.in_range ([high]):        [HER2],
                ---------------------------------------------------------
                er_negative and
                pr_negative and
                her2_negative and
                ki67.in_range ([high]):        [triple_negative],
                ---------------------------------------------------------
                *:                             [none];
                =========================================================
            ;

    chemotherapy_regime: Terminology_term
        Result :=
            choice of
                ================================================================================
                not metastatic:
                    choice of
                        ========================================================================
                        molecular_subtype in
                            {[luminal_B_HER2_negative],
                             [triple_negative]} and
                        (tnm_t > '1a' or tnm_n > '0'):                   [taxanes],
                        ------------------------------------------------------------------------
                        molecular_subtype = [luminal_A] and
                        (tnm_t >= '3' or tnm_n >= '2' or tnm_g >= '3'):  [anthracyclines],
                        ------------------------------------------------------------------------
                        molecular_subtype = [luminal_B_HER2_positive] and
                        (tnm_t = '1b' or tnm_t = '1c' and tnm_n = '0') or
                        molecular_subtype = [HER2_positive] and
                        (tnm_t = '1b' and tnm_n = '0'):                  [paditaxel_trastuzumab]
                        ========================================================================
                    ;,
                --------------------------------------------------------------------------------
                *:
                    choice of
                        =====================
                        yyy:        aaa,
                        ---------------------
                        xxx:        bbb,
                        ---------------------
                        *:          ccc
                        =====================
                    ;
                =================================================================================
            ;

terminology
    term_definitions = <
        ["en"] = <
            ["luminal_A"] = <
                text = <"xxx">
                description = <"...">
            >
            ["luminal_B_HER2_positive"] = <
                text = <"xxx">
                description = <"...">
            >
            ["luminal_B_HER2_negative"] = <
                text = <"xxx">
                description = <"...">
            >
            ["HER2_positive"] = <
                text = <"xxx">
                description = <"...">
            >
            ["HER2_megative"] = <
                text = <"xxx">
                description = <"...">
            >
            ["triple_negative"] = <
                text = <"xxx">
                description = <"...">
            >
            ["oligohydramnios"] = <
                text = <"xxx">
                description = <"...">
            >

8. Covid19 Severity Classification

8.1. Work Plan

The following work plan is a rendition of the ACEP Covid19 severity guideline multi-step structure.

ACEP covid19 severity
Figure 6. ACEP Covid19 Work Plan

8.2. Decision Logic Module

dlm ACEP_COVID19_severity_classification.v0.5.0

language
    original_language = <[ISO_639-1::en]>

description
    lifecycle_state = <"unmanaged">
    original_author = <
        ["name"] = <"Thomas Beale">
        ["email"] = <"thomas.beale@openEHR.org">
        ["organisation"] = <"openEHR Foundation <http://www.openEHR.org>">
        ["date"] = <"2020-12-02">
    >
    details = <
        ["en"] = <
            language = <[ISO_639-1::en]>
            purpose = <"This tool was developed by ACEP and EvidenceCare to assist
                in determining the appropriate evaluation and disposition for adult
                patients with suspected or confirmed COVID-19.">
        >
    >
    copyright = <"© 2020 openEHR Foundation">
    licence = <"Creative Commons CC-BY <https://creativecommons.org/licenses/by/3.0/>">
    ip_acknowledgements = <
        ["ACEP_EvidenceCare"] = <"This content developed from original publication of
            © 2020 American College of Emergency Physicians (ACEP), EvidenceCare,
            see https://www.acep.org/globalassets/sites/acep/media/covid-19-main/acep_evidencecare_covid19severitytool.pdf">
    >

use
    BASIC: Basic_patient_data
    BMI: Body_mass_index

input -- Administrative

    is_LT_care_resident: Boolean
        ;

input -- State

    |
    | Extract from master problem list or ask patient
    |
    has_cardiovascular_disease: Boolean
        ;

    |
    | Extract from master problem list or ask patient
    |
    has cerebrovascular_disease: Boolean
        ;

    |
    | Extract from master problem list or ask patient
    |
    has_COPD: Boolean
        ;

    |
    | Extract from master problem list or ask patient
    |
    is_type_2_diabetic: Boolean
        ;

    |
    | Extract from master problem list or ask patient
    |
    has_hypertension: Boolean
        ;

    |
    | True if any cancer diagnosis on master problem list
    | or ask patient
    |
    has_malignancy: Boolean
        ;

input -- Tracked State

    heart_rate: Count
        currency = 1 min
        ranges =
            ------------------------------------
            [mild_low_risk]:  |<= 99 /min|,
            [mild_at_risk]:   |100 .. 120 /min|,
            [moderate_risk]:  |>= 121 /min|
            ------------------------------------
        ;

    systolic_BP: Quantity
        currency = 10 min
        ranges =
            --------------------------------
            [critical_risk]:  |< 90 mm[Hg]|,
            [normal_risk]:    |>= 90 mm[Hg]|
            --------------------------------
        ;

    |
    | Minimum documented within last 8 hrs
    |
    lowest_SpO2: Quantity
        currency = 8 hr
        ranges =
            ------------------------------
            [mild_low_risk]:  |>= 93 %|,
            [moderate_risk]:  |89 .. 92 %|,
            [severe_risk]:    |<= 88 %|
            ------------------------------
        ;

    respiratory_rate: Quantity
        currency = 2 min
        ranges =
            ----------------------------------
            [mild_low_risk]:  |<= 22 /min|,
            [moderate_risk]:  |23 .. 28 /min|,
            [severe_risk]:    |>= 29 /min|
            ----------------------------------
        ;

    O2_flow_rate: Quantity
        currency = 2 min
        ranges =
            ---------------------------------
            [mild_low_risk]:  |= 0 L/min|,
            [mild_at_risk]:   |1 .. 2 L/min|,
            [moderate_risk]:  |3 .. 4 L/min|,
            [severe_risk]:    |>= 5 L/min|
            ---------------------------------
        ;

    has_altered_LOC: Boolean
        currency = 5 min
        ;

    has_hemoptysis: Boolean
        currency = 5 min
        ;

    has_persistent_dyspnea: Boolean
        currency = 5 min
        ;

    |
    | Reference SpO2 for exertional test: a 1-minute sit-to-stand
    | test can be performed within the patient’s room.
    | With this, they sit and stand as many as they can over the
    | course of 1 minute.
    | * A 3% drop in pulse oximeter reading is considered a positive test
    |
    SpO2_exertion_reference: Quantity
        currency = 5 min
        ;

    |
    | Post exertion SpO2
    |
    SpO2_exertion_post: Quantity
        currency = 5 min
        ;

rules

    heart_rate_score: Integer
        Result := case heart_rate in
            =====================
            *:                0
            =====================
        ;

    systolic_BP_score: Integer
        Result := case systolic_BP in
            =====================
            *:                0
            =====================
        ;

    SpO2_score: Integer
        Result := case lowest_SpO2 in
            =====================
            [mild_low_risk]:  0,
            ---------------------
            [moderate_risk]:  2,
            ---------------------
            [severe_risk]:    5,
            ---------------------
            *:                0
            =====================
        ;

    respiratory_rate_score: Integer
        Result := case respiratory_rate in
            =====================
            [mild_low_risk]:  0,
            ---------------------
            [mild_at_risk]:   1,
            ---------------------
            [moderate_risk]:  2,
            ---------------------
            *:                0
            =====================
        ;

    O2_flow_rate_score: Integer
        Result := case O2_flow_rate in
            =====================
            [mild_low_risk],
            [mild_at_risk]:   0,
            ---------------------
            [moderate_risk]:  4,
            ---------------------
            [severe_risk]:    5,
            ---------------------
            *:                0
            =====================
        ;

    |
    | Compute the qCSI score from vital signs sub-scores
    |
    qCSI_score: Integer
        Result := heart_rate_score +
                systolic_BP_score +
                SpO2_score +
                respiratory_rate_score +
                O2_flow_rate_score
        ;

    |
    | ACEP step 2 assessment
    |
    qCSI_risk: Terminology_code
        Result := case qCSI_score in
            ============================
            0:          [mild_low_risk],
            ----------------------------
            |1..2|:     [mild_at_risk],
            ----------------------------
            |3..5|:     [moderate_risk],
            ----------------------------
            |6..8|:     [severe_risk],
            ----------------------------
            |>= 9|:     [critical_risk]
            ============================
        ;

    |
    | Count demographic related risk factors
    |
    risk_factors_demographic_count: Integer
        Result.add (
            ------------------------------------
            BASIC.sex = [male]          ? 1 : 0,
            BASIC.age > 60              ? 1 : 0,
            BASIC.race = [black_race]   ? 1 : 0
            ------------------------------------
        );

    |
    | Count medical / history related risk factors
    |
    risk_factors_medical_count: Integer
        Result.add (
            --------------------------------------
            has_cardiovascular_disease    ? 1 : 0,
            has cerebrovascular_disease   ? 1 : 0,
            has_COPD                      ? 1 : 0,
            is_type_2_diabetic            ? 1 : 0,
            has_hypertension              ? 1 : 0,
            has_malignancy                ? 1 : 0,
            BMI.bmi > 30                  ? 1 : 0,
            has_renal_disease             ? 1 : 0
            --------------------------------------
        );

    |
    | Total pre-existing risk factors count
    |
    risk_factors_count: Integer
        Result := risk_factors_demographic_count +
                  risk_factors_medical_count
        ;

    |
    | ACEP step 3 assessment
    | NB: must be assessed in highest -> lowest order
    |
    symptoms_related_risk: Terminology_code
        Result := choice of
            ====================================================
            has_altered_LOC:                    [critical_risk],
            ----------------------------------------------------
            has_hemoptysis:                     [severe_risk],
            ----------------------------------------------------
            has_persistent_dyspnea or
            is_LT_care_resident:                [moderate_risk],
            ----------------------------------------------------
            risk_factors_count ∈ {|>= 2|}:     [mild_at_risk],
            ----------------------------------------------------
            risk_factors_count ∈ {|0..1|}:     [mild_low_risk]
            ====================================================
        ;

    |
    | Discharge home rule based on various criteria
    |
    can_discharge: Boolean
        Result :=
            qCSI_risk = [mild_low_risk] and
            symptoms_related_risk = [mild_low_risk] and
            exertional_SpO2_drop = [normal] and
            TO BE COMPLETED
        ;

    |
    | Generate a % drop in SpO2 over 1 min sit/stand exertion test;
    | NB: A fall in SpO2 generates a +ve result value.
    |
    exertional_SpO2_drop: Quantity
        Result := (SpO2_exertion_reference - SpO2_exertion_post)/SpO2_exertion_reference * 100
        ;

    exertional_SpO2_result: Terminology_code
        Result := case exertional_SpO2_drop in
            ========================
            |< 3%|:   [normal],
            ------------------------
            |>= 3%|:  [mild_at_risk]
            ========================
        ;