In addition to the FHIR-based L3 representation formalisms that are the focus of this implementation guide,
the BPM+ family of knowledge representation standards from Object Modeling Group (OMG) are being used to
represent clinical guideline and pathway content. This section describes potential approaches for using
the BPM+ standards in coordination with this implementation guide. Readers of this section are expected to
have some level of familiarity with the BPM+ standards, specifically BPMN, CMMN, and DMN.
Within the overall framework of levels of knowledge, the visual representation aspects of the BPM+ family of
standards fit within L2, diagrams, workflows, and process models, while the executable aspects of these
standards range into L3 and even L4, given systems that are capable of executing BPMN, CMMN, and DMN content.
TODO: Diagram depicting placement of BPMN, CMMN, DMN along-side the FHIR-based specifications
In particular, this implementation guide defines 3 layers of process-modeling structures:
Pathway - BPMN/CMMN (Leaning towards BPMN)
Strategy - BPMN/CMMN (Leaning towards CMMN)
Recommendation - BPMN/DMN (Leaning towards DMN)
Of course, this correspondence is a rough equivalence, there are aspects of process- and decision-modeling throughout
each of the layers, but this provides a starting point for approaching integrated use of these standards.
BPMN and FHIR
Focusing on process semantics, this section provides mappings between BPMN and PlanDefinition, informed by the
workflow patterns work done at the Eindhoven University of Technology and Queensland
University of Technology, and applied to FHIR by a joint project between the University of Applied Sciences Upper Austria (“FH Hagenberg”) and CGM Clincal Austria for a prototype for medical boards (project “KIMBo”).
The definition of a Process is specified using either BPMN or a FHIR PlanDefinition, then the Atlas Transformation Language (ATL)
can be used to transform between the two, using the Control Flow and Data Flow patterns as a metamodel.
The following sections consider specific patterns and the BPMN and PlanDefinition representations of each.
Sequence Flow
Definition
A sequence flow is a directed arc from one source node to exactly one target node.
BPMN
Start-Event, End-Event, Sequence
PlanDefinition
PlanDefinition.relatedAction, Before-Start
BPMN Representation
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:dc= "http://www.omg.org/spec/DD/20100524/DC" xmlns:bpmndi= "http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpmn= "http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:di= "http://www.omg.org/spec/DD/20100524/DI" xmlns:xmi= "http://schema.omg.org/spec/XMI" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" targetNamespace= "http://aist.fh-hagenberg.at/msbpmn" >
<bpmn:process isExecutable= "true" id= "Process_d1fe3661-9a23-44ad-b6c3-0abe614324ee" name= "Process_d1fe3661-9a23-44ad-b6c3-0abe614324ee" >
<bpmn:endEvent id= "end4" name= "end" >
<bpmn:incoming> sf_ad_3_end4</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id= "sf_ad_1_ad_2" targetRef= "ad_2" sourceRef= "ad_1" />
<bpmn:sequenceFlow id= "sf_ad_2_ad_3" targetRef= "ad_3" sourceRef= "ad_2" />
<bpmn:sequenceFlow id= "sf_ad_3_end4" targetRef= "end4" sourceRef= "ad_3" />
<bpmn:sequenceFlow id= "sf_start3_ad_1" targetRef= "ad_1" sourceRef= "start3" />
<bpmn:startEvent id= "start3" name= "start" >
<bpmn:outgoing> sf_start3_ad_1</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:userTask id= "ad_2" name= "Task 2" >
<bpmn:incoming> sf_ad_1_ad_2</bpmn:incoming>
<bpmn:outgoing> sf_ad_2_ad_3</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_3" name= "Task 3" >
<bpmn:incoming> sf_ad_2_ad_3</bpmn:incoming>
<bpmn:outgoing> sf_ad_3_end4</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_1" name= "Task 1" >
<bpmn:incoming> sf_start3_ad_1</bpmn:incoming>
<bpmn:outgoing> sf_ad_1_ad_2</bpmn:outgoing>
</bpmn:userTask>
</bpmn:process>
</bpmn:definitions>
PlanDefinition Representation
<PlanDefinition xmlns= 'http://hl7.org/fhir' >
<id value= 'protocol-example' />
<text>
<status value= 'generated' />
</text>
<!-- The status of the protocol.draft | active | retired -->
<status value= 'draft' />
<action>
<id value= 'ad_1' />
<title value= 'Task 1' />
<!-- related action definition -->
<relatedAction>
<actionId value= 'ad_2' />
<relationship value= 'before-start' />
</relatedAction>
</action>
<action>
<id value= 'ad_2' />
<title value= 'Task 2' />
<!-- related action definition -->
<relatedAction>
<actionId value= 'ad_3' />
<relationship value= 'before-start' />
</relatedAction>
</action>
<action>
<id value= 'ad_3' />
<title value= 'Task 3' />
</action>
</PlanDefinition>
Parallel Split
Definition
A parallel split is separating the sequence flow in parallel branches that are executed concurrently.
BPMN
ParallelGateway
PlanDefinition
PlanDefinition.groupingBehavior, PlanDefinition.selectionBehavior
Remarks
A merge element is created implicitly
BPMN Representation
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:dc= "http://www.omg.org/spec/DD/20100524/DC" xmlns:bpmndi= "http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpmn= "http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:di= "http://www.omg.org/spec/DD/20100524/DI" xmlns:xmi= "http://schema.omg.org/spec/XMI" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" targetNamespace= "http://aist.fh-hagenberg.at/msbpmn" >
<bpmn:process isExecutable= "true" id= "Process_7883a5c7-7ab9-40fc-ab09-b55ac064d172" name= "Process_7883a5c7-7ab9-40fc-ab09-b55ac064d172" >
<bpmn:endEvent id= "end8" name= "end" >
<bpmn:incoming> sf_ad_4_end8</bpmn:incoming>
</bpmn:endEvent>
<bpmn:parallelGateway id= "join_of_par_group" name= "join" >
<bpmn:incoming> sf_ad_2_join_of_par_group</bpmn:incoming>
<bpmn:incoming> sf_ad_3_join_of_par_group</bpmn:incoming>
<bpmn:outgoing> sf_join_of_par_group_ad_4</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:parallelGateway id= "par_group" name= "par_group" >
<bpmn:incoming> sf_ad_1_par_group</bpmn:incoming>
<bpmn:outgoing> sf_par_group_ad_2</bpmn:outgoing>
<bpmn:outgoing> sf_par_group_ad_3</bpmn:outgoing>
</bpmn:parallelGateway>
<bpmn:sequenceFlow id= "sf_ad_4_end8" targetRef= "end8" sourceRef= "ad_4" />
<bpmn:sequenceFlow id= "sf_start7_ad_1" targetRef= "ad_1" sourceRef= "start7" />
<bpmn:sequenceFlow id= "sf_ad_1_par_group" targetRef= "par_group" sourceRef= "ad_1" />
<bpmn:sequenceFlow id= "sf_par_group_ad_2" targetRef= "ad_2" sourceRef= "par_group" />
<bpmn:sequenceFlow id= "sf_ad_2_join_of_par_group" targetRef= "join_of_par_group" sourceRef= "ad_2" />
<bpmn:sequenceFlow id= "sf_ad_3_join_of_par_group" targetRef= "join_of_par_group" sourceRef= "ad_3" />
<bpmn:sequenceFlow id= "sf_join_of_par_group_ad_4" targetRef= "ad_4" sourceRef= "join_of_par_group" />
<bpmn:sequenceFlow id= "sf_par_group_ad_3" targetRef= "ad_3" sourceRef= "par_group" />
<bpmn:startEvent id= "start7" name= "start" >
<bpmn:outgoing> sf_start7_ad_1</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:userTask id= "ad_1" name= "Task 1" >
<bpmn:incoming> sf_start7_ad_1</bpmn:incoming>
<bpmn:outgoing> sf_ad_1_par_group</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_4" name= "Task 4" >
<bpmn:incoming> sf_join_of_par_group_ad_4</bpmn:incoming>
<bpmn:outgoing> sf_ad_4_end8</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_2" name= "Task 2" >
<bpmn:incoming> sf_par_group_ad_2</bpmn:incoming>
<bpmn:outgoing> sf_ad_2_join_of_par_group</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_3" name= "Task 3" >
<bpmn:incoming> sf_par_group_ad_3</bpmn:incoming>
<bpmn:outgoing> sf_ad_3_join_of_par_group</bpmn:outgoing>
</bpmn:userTask>
</bpmn:process>
</bpmn:definitions>
PlanDefinition Representation
<?xml version="1.0" encoding="UTF-8"?>
<PlanDefinition xmlns= "http://hl7.org/fhir" >
<id value= "protocol-example" />
<text>
<status value= "generated" />
</text>
<!-- The status of the protocol.draft | active | retired -->
<status value= "draft" />
<action>
<id value= "ad_1" />
<title value= "Task 1" />
<!-- related action definition -->
<relatedAction>
<actionId value= "par_group" />
<relationship value= "before-start" />
</relatedAction>
</action>
<action>
<id value= "par_group" />
<title value= "par_group" />
<groupingBehavior value= "logical-group" />
<selectionBehavior value= "all" />
<action>
<id value= "ad_2" />
<title value= "Task 2" />
<relatedAction>
<actionId value= "par_group" />
<relationship value= "before-end" />
</relatedAction>
</action>
<action>
<id value= "ad_3" />
<title value= "Task 3" />
<relatedAction>
<actionId value= "par_group" />
<relationship value= "before-end" />
</relatedAction>
</action>
<relatedAction>
<actionId value= "ad_4" />
<relationship value= "before-start" />
</relatedAction>
</action>
<action>
<id value= "ad_4" />
<title value= "Task 4" />
</action>
</PlanDefinition>
Exclusive Split
Definition
An exclusive choice is an element where the sequence flow is split into two or more branches, whereas only one of the branches can be activated with respect to a specified condition on the exclusive choice element.
Remarks
A synchronization element is created implicitly
BPMN
EclusiveGateway, ExtensionElement, TaskListener
PlanDefinition
PlanDefinition.groupingBehavior, PlanDefinition.selectionBehavior
BPMN Representation
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:dc= "http://www.omg.org/spec/DD/20100524/DC" xmlns:bpmndi= "http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpmn= "http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:di= "http://www.omg.org/spec/DD/20100524/DI" xmlns:xmi= "http://schema.omg.org/spec/XMI" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" targetNamespace= "http://aist.fh-hagenberg.at/msbpmn" >
<bpmn:process isExecutable= "true" id= "Process_aaa0c995-5dfd-43bc-bb05-3c08bda5f900" name= "Process_aaa0c995-5dfd-43bc-bb05-3c08bda5f900" >
<bpmn:endEvent id= "end12" name= "end" >
<bpmn:incoming> sf_ad_4_end12</bpmn:incoming>
</bpmn:endEvent>
<bpmn:exclusiveGateway id= "xor_group" name= "Xor_group" >
<bpmn:incoming> sf_ad_1_xor_group</bpmn:incoming>
<bpmn:outgoing> sf_xor_group_ad_2</bpmn:outgoing>
<bpmn:outgoing> sf_xor_group_ad_3</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:exclusiveGateway id= "join_of_xor_group" name= "join" >
<bpmn:incoming> sf_ad_2_join_of_xor_group</bpmn:incoming>
<bpmn:incoming> sf_ad_3_join_of_xor_group</bpmn:incoming>
<bpmn:outgoing> sf_join_of_xor_group_ad_4</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:sequenceFlow id= "sf_xor_group_ad_2" targetRef= "ad_2" sourceRef= "xor_group" >
<bpmn:conditionExpression id= "sf_xor_group_ad_2_condition" />
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id= "sf_ad_2_join_of_xor_group" targetRef= "join_of_xor_group" sourceRef= "ad_2" />
<bpmn:sequenceFlow id= "sf_ad_3_join_of_xor_group" targetRef= "join_of_xor_group" sourceRef= "ad_3" />
<bpmn:sequenceFlow id= "sf_join_of_xor_group_ad_4" targetRef= "ad_4" sourceRef= "join_of_xor_group" />
<bpmn:sequenceFlow id= "sf_ad_4_end12" targetRef= "end12" sourceRef= "ad_4" />
<bpmn:sequenceFlow id= "sf_xor_group_ad_3" targetRef= "ad_3" sourceRef= "xor_group" >
<bpmn:conditionExpression id= "sf_xor_group_ad_3_condition" />
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id= "sf_ad_1_xor_group" targetRef= "xor_group" sourceRef= "ad_1" />
<bpmn:sequenceFlow id= "sf_start11_ad_1" targetRef= "ad_1" sourceRef= "start11" />
<bpmn:startEvent id= "start11" name= "start" >
<bpmn:outgoing> sf_start11_ad_1</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:userTask id= "ad_4" name= "Task 4" >
<bpmn:incoming> sf_join_of_xor_group_ad_4</bpmn:incoming>
<bpmn:outgoing> sf_ad_4_end12</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_2" name= "Task 2" >
<bpmn:incoming> sf_xor_group_ad_2</bpmn:incoming>
<bpmn:outgoing> sf_ad_2_join_of_xor_group</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_3" name= "Task 3" >
<bpmn:incoming> sf_xor_group_ad_3</bpmn:incoming>
<bpmn:outgoing> sf_ad_3_join_of_xor_group</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_1" name= "Task 1" >
<bpmn:incoming> sf_start11_ad_1</bpmn:incoming>
<bpmn:outgoing> sf_ad_1_xor_group</bpmn:outgoing>
</bpmn:userTask>
</bpmn:process>
</bpmn:definitions>
PlanDefinition Representation
<?xml version="1.0" encoding="UTF-8"?>
<PlanDefinition xmlns= "http://hl7.org/fhir" >
<id value= "protocol-example" />
<text>
<status value= "generated" />
</text>
<!-- The status of the protocol.draft | active | retired -->
<status value= "draft" />
<action>
<id value= "ad_1" />
<title value= "Task 1" />
<!-- related action definition -->
<relatedAction>
<actionId value= "xor_group" />
<relationship value= "before-start" />
</relatedAction>
</action>
<action>
<id value= "xor_group" />
<title value= "Xor_group" />
<groupingBehavior value= "logical-group" />
<selectionBehavior value= "exactly-one" />
<action>
<id value= "ad_2" />
<title value= "Task 2" />
<condition>
<kind value= "applicability" />
<expression>
<description value= "Some short description of the expression" />
<language value= "EL" />
<expression value= "$name==2" />
</expression>
</condition>
<relatedAction>
<actionId value= "xor_group" />
<relationship value= "before-end" />
</relatedAction>
</action>
<action>
<id value= "ad_3" />
<title value= "Task 3" />
<condition>
<kind value= "applicability" />
<expression>
<description value= "Some short description of the expression" />
<language value= "EL" />
<expression value= "$name==1" />
</expression>
</condition>
<relatedAction>
<actionId value= "xor_group" />
<relationship value= "before-end" />
</relatedAction>
</action>
<relatedAction>
<actionId value= "ad_4" />
<relationship value= "before-start" />
</relatedAction>
</action>
<action>
<id value= "ad_4" />
<title value= "Task 4" />
</action>
</PlanDefinition>
Timed Start
Definition
A TimedStartEvent is a special StartEvent that has a TimerEvent associated with it, which defines when the process has to be executed.
BPMN
Start-Event, End-Event, Sequence
PlanDefinition
PlanDefinition.relatedAction, Before-Start
Remarks
As PlanDefinition does not offer a specific action for either start or end, these BPMN-Elements are to be created implicitly. Whilst the start Event is based on the Elements in the first action in the list of actions in the PlanDefinition
BPMN Representation
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:dc= "http://www.omg.org/spec/DD/20100524/DC" xmlns:bpmndi= "http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpmn= "http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:di= "http://www.omg.org/spec/DD/20100524/DI" xmlns:xmi= "http://schema.omg.org/spec/XMI" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" targetNamespace= "http://aist.fh-hagenberg.at/msbpmn" >
<bpmn:process isExecutable= "true" id= "Process_efb1f872-e958-4e7d-949f-a4bbf0f6c58f" name= "Process_efb1f872-e958-4e7d-949f-a4bbf0f6c58f" >
<bpmn:endEvent id= "end16" name= "end" >
<bpmn:incoming> sf_ad_3_end16</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id= "sf_ad_1_ad_2" targetRef= "ad_2" sourceRef= "ad_1" />
<bpmn:sequenceFlow id= "sf_ad_2_ad_3" targetRef= "ad_3" sourceRef= "ad_2" />
<bpmn:sequenceFlow id= "sf_ad_3_end16" targetRef= "end16" sourceRef= "ad_3" />
<bpmn:sequenceFlow id= "sf_start15_ad_1" targetRef= "ad_1" sourceRef= "start15" />
<bpmn:startEvent id= "start15" name= "start" >
<bpmn:outgoing> sf_start15_ad_1</bpmn:outgoing>
<bpmn:timerEventDefinition id= "sampleTriggerDef" >
<bpmn:timeDate id= "sampleTriggerDef_timeDate" />
</bpmn:timerEventDefinition>
</bpmn:startEvent>
<bpmn:userTask id= "ad_1" name= "Task 1" >
<bpmn:incoming> sf_start15_ad_1</bpmn:incoming>
<bpmn:outgoing> sf_ad_1_ad_2</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_3" name= "Task 3" >
<bpmn:incoming> sf_ad_2_ad_3</bpmn:incoming>
<bpmn:outgoing> sf_ad_3_end16</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id= "ad_2" name= "Task 2" >
<bpmn:incoming> sf_ad_1_ad_2</bpmn:incoming>
<bpmn:outgoing> sf_ad_2_ad_3</bpmn:outgoing>
</bpmn:userTask>
</bpmn:process>
</bpmn:definitions>
PlanDefinition Representation
<PlanDefinition xmlns= 'http://hl7.org/fhir' >
<id value= 'protocol-example' />
<text>
<status value= 'generated' />
</text>
<!-- The status of the protocol.draft | active | retired -->
<status value= 'draft' />
<action>
<id value= 'ad_1' />
<title value= 'Task 1' />
<trigger>
<type value= "periodic" />
<name value= "sampleTriggerDef" />
<timingTiming>
<event value= "2015-02-07T13:28:17" />
</timingTiming>
</trigger>
<!-- related action definition -->
<relatedAction>
<actionId value= 'ad_2' />
<relationship value= 'before-start' />
</relatedAction>
</action>
<action>
<id value= 'ad_2' />
<title value= 'Task 2' />
<!-- related action definition -->
<relatedAction>
<actionId value= 'ad_3' />
<relationship value= 'before-start' />
</relatedAction>
</action>
<action>
<id value= 'ad_3' />
<title value= 'Task 3' />
</action>
</PlanDefinition>