For some time now I have been thinking of writing an app to help with running a resuscitation protocol. The resuscitation protocol as provided by the Dutch Advanced Pediatric Life Support is rather straight forward. Yet to adhere to this protocol in a stressful situation for a patient with a life threatening condition is a challenge to many physicians or health care providers.
The protocol itself is not overly complex, there are some common pitfalls where mistakes can occur. Also, in the event of a blackout (which can happen even to the most experienced practitioner), it would be most helpful if there would be an app to guide you through the various steps in the protocol.
The first thing to notice is that a protocol is very much event driven. Basically there are two kinds of events: 1) Observations, 2) Interventions. This results in the following domain model.
The observations drive the subsequent interventions which subsequently will be evaluated by … observations. So, the whole cycle is like:
Observation -> Intervention (one or more) -> Evaluation (by observation)
There are two major groups of observations: 1) Observations for signs of life and 2) observations what the current rhythm is, the rhythm check in the protocol. So you can implement the evaluations like:
If you check for life, the observation can be signs of life, or no signs of life. When you check the rhythm, the result can be either a ‘shock-able rhythm’ or a ‘non shock-able rhythm’ or a return of spontaneous circulation (ROSC). Pretty straightforward, huh.
The interventions and subsequent evaluation belong together and are triggered by an observation. So, let’s call this an intervention block.
Then things get slightly more complicated as an intervention block can be run once, or be repeated. For example, the initial basic life support (BLS) is just performed once, but the shock-able rhythm and the non shock-able rhythm interventions are repeated over and over until ROSC. Therefore, you get:
So, a protocol item can either be a repeatable or a non-repeatable intervention block. Note that one observation can trigger multiple protocol items (that are either repeatable or non repeatable) and that they can be defined as a protocol block. Taken together, a list of protocol blocks form a protocol.
An example of a combination of non-repeatable intervention blocks with repeated intervention blocks is the shock-able protocol block:
This can be nicely modeled like:
Note that the first 5 protocol items are non repeatable. Meaning that when this protocol block is observed 5 times, these will not be run again. The remaining 2 protocol items will be run over and over again as long as the observation of a shock-able rhythm is made.
The events and commands that result from running the protocol are:
So, actually, really simple. The event is that an observation has been observed or that an intervention has been ‘intervened’. The commands are that an observation has to be made (remember the evaluate in the intervention block) or that an intervention has to be performed.
To run the protocol the following processes have to be implemented:
First from what previously has happened (the event list) I can figure out where in the protocol I currently am, the GetCurrentProtocolBlock.
When I have this block, again using previous events, the non repeatable intervention blocks have to be removed, otherwise we keep repeating. The result is a number which is a count of remaining observations that triggers the protocol items. Remember, after 5 shock-able rhythm observations, there only remains a repeatable sequence of shock, CPR and de-charge defibrillator and shock, CPR, de-charge and give adrenaline. The RemoveNonRepeatableFromBlock takes care of that.
Next when it is known exactly what protocol item list has to be processed, the current protocol item is identified using the remaining number of observations. This is handled by the GetCurrentProtocolItem.
Finally, the list of interventions or (when the interventions have all been ‘Intervened’), the list of observations (the evaluation part of the intervention block) are turned into a list of commands that can be chosen from. The GetCommandsFromProtocolItem function.
This setup enables a protocol definition that drives the correct processing of the protocol. The protocol itself is quite readable for non programmer medical professionals.
As a nice proof of concept I can run the resuscitation protocol by randomly selecting commands and read the output.
Also, testing is very easy to do. Just feed the test with a list of events and check whether the processing produces the appropriate command list.
This is I think a very nice example to showcase the power of event driven design using a algebraic type system like F# has. The code can be found on GitHub.