Clinical Decision Logic Fun

How close can we get to making a clinical decision logic language look like the published guidelines which it is used to encode?

Below is an openEHR Decision Logic Module (DLM) example, in the current form of the openEHR Decision Language specification currently under development. Why another language? Well I’ll answer that with: show me a language that does this, and we’ll use it instead (e.g. why not ProForma, Arden, GLIF etc?).

Of course this language doesn’t yet solve all the problems, but we are taking two particular challenges seriously:

  • the problem of ‘subject variables’ (aka ‘curly braces’ or data access problem);
  • getting the cognitive level of the language as close as possible to the cognitive level of the source materials and authors’ thinking.

As background, our conceptual basics here.

The following logic module is the logic part of the RCHOPS21 guideline published by the NHS Thames Valley Cancer Network. Our encoding of this into Task Plan + DLM is shown here; below is the DLM, colourised in a way that future tools will hopefully support.

If you look closely at the DLM below, you will see various syntax tricks. I won’t explain them here (some of them come from the openEHR Expression Language), the idea is that a clinical professional and any other guideline-knowledgeable person will guess the meaning. We would be very interested in what such people think of the example below (along with any others who care to comment).

If you wish to comment, you may of course do so here on the blog post but you might also consider this discussion thread on the openEHR Discourse site (or feel free to raise a new topic in that category).


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
    has_lymphoma_diagnosis: Boolean
        time_window = tw_current_episode

    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
                =======================================
                |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 = <"...">
            >
        >
    >

About wolandscat

I work on semantic architectures for interoperability of information systems. Much of my time is spent studying biomedical knowledge using methods from philosophy, particularly ontology and epistemology.
This entry was posted in Computing, decision support, Health Informatics, openehr, standards and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s