1 Pseudo Worflow Language (PWL)

PWL is a pMineR internal formalism for representing workflows and guidelines. The class implementing PWL is called confCheck_easy() : it let the traces flow through the workflow and then observe the behaviors.

2 first of all

We have to load the needed libraries

library(pMineR,quietly = TRUE)
library(kableExtra,quietly = TRUE)

3 An example of Event Log

First of all let’s suppose to have an Event Log composed from the following events: Imaging, MedicalVisit, Therapy, Dismission. A possible trace can be:

aaa <- read.csv2(file = "./csv/one.overview.csv",sep = ",")
aaa %>%
  kbl() %>%
  kable_minimal()
ID DATE EVENT
66738 02/10/2016 Imaging
66738 09/10/2016 MedicalVisit
66738 18/10/2016 Imaging
66738 02/11/2016 MedicalVisit
66738 10/11/2016 Chemotherapy
66738 01/12/2016 Dismission

Which can be the meaning of that? For example the patient got some Image investigation (fist event) and then he went to the first Medical Visit (second Event). In such Visit the clinician decided to go more in deep with another diagnostic image analysis (the third event). With the report of the new investigation, the patients was evaluated in a new Medical visit (the fourth event) where the therapy was planned (the fifth event). After almost 20 days, the therapy ended and the patient was dismissed (sixth and last event).

4 A simple WORKFLOW

A simple workflow can be aimed at identifying the DIAGNOSTIC time interval, the THERAPY time interval and the DISMISSION. In this WF, we will create a dummy-state called BEGIN (in green) and we will define as final state the DISMISSION (in red):

objPWL <- confCheck_easy()
objPWL$loadWorkFlow(WF.fileName = "./XML-PWL/one.overview.xml")

grViz( objPWL$plot(giveBack.grVizScript = TRUE) )

The corresponding XML, in PWL, is the following:

<xml>
  <workflow>
    <node name='Diagnosis'></node>
    <node name='Therapy'></node>
    <node name='Dismission' type='END'></node>
    
      <trigger name='Trigger 1'>
          <condition>'BEGIN' %in% $st.ACTIVE$ AND ( $ev.NOW$=='Imaging' or $ev.NOW$=='MedicalVisit' )</condition>
          <set>'Diagnosis'</set>
          <unset>'BEGIN'</unset>
      </trigger>   
      
      <trigger name='Trigger 2'>
          <condition>'Diagnosis' %in% $st.ACTIVE$ AND  $ev.NOW$=='Chemotherapy' </condition>
          <set>'Therapy'</set>
          <unset>'Diagnosis'</unset>
      </trigger>   
      
      <trigger name='Trigger 3'>
          <condition>'Therapy' %in% $st.ACTIVE$ AND  $ev.NOW$=='Dismission' </condition>
          <unset>'Therapy'</unset>
          <set>'Dismission'</set>
      </trigger>  
      
    </workflow>
</xml>

Now we will analyze the computation from the point of view of the confChech_easy engine. He places a cursor at the first event of the track, then moves the cursor along the events in chronological order. In this activity it checks which triggers can be fired and which corresponding states have to be set or unset. At the end of the computation it returns a report. In or specific case.

Note: with events we mean the events as they are present in the Event Log while the states are freely definable by the Process Mining Analyst and represent the different states or phases or steps in the process we want to check.

5 Let’s run the trace

As usual, we need a dataLoader object

objDL = dataLoader(verbose.mode = FALSE)
objDL$load.csv(nomeFile = "./csv/one.overview.csv", IDName = "ID", EVENTName = "EVENT", dateColumnName = "DATE",  sep = ",", format.column.date = "%d/%m/%Y");

we can now load the Event Log into the object objPWL:

objPWL$loadDataset(dataList = objDL$getData())

and run the conformance checking:

objPWL$replay()
## 
##  Doing: 66738
## Beginning Pat 66738...
##   processing:Imaging
##   processing:MedicalVisit
##   processing:Imaging
##   processing:MedicalVisit
##   processing:Chemotherapy
##   processing:Dismission
## Pat 66738 done;

6 Getting results

One of the ways to get the results is the following:

aaa <- objPWL$get.list.replay.result()

resultingTale <- aaa$list.computation.matrix$stati.timeline

resultingTale[["66738"]] %>%
  kbl() %>%
  kable_minimal()
node node.status eventDateTime deltaTimeFromBegin
Diagnosis begin 02/10/2016 00:00:00 0
BEGIN end 02/10/2016 00:00:00 0
Therapy begin 10/11/2016 00:00:00 56220
Diagnosis end 10/11/2016 00:00:00 56220
Dismission begin 01/12/2016 00:00:00 86460
Therapy end 01/12/2016 00:00:00 86460

note : This table does not show the Event in the Event Log but what happened to the nodes in the PWL XML. Here, for example, we can read that:

7 Debugging

With the confCheck_easy::method get.XML.replay.result(), as shown below, we can write on an xml the cursor point of view

objPWL$get.XML.replay.result(fileName = "./text.xml",writeToFile = TRUE)

The output is the following:

<xml>
    <computation n='1' IDPaz='66738'>
      
        <step n='1' trg='TRUE' evt='Imaging' date='02/10/2016 00:00:00' pMineR.internal.ID.Evt='1'>
            <st.ACTIVE.PRE name='BEGIN'></st.ACTIVE.PRE>
            <fired.trigger name='Trigger 1'></fired.trigger>
            <st.ACTIVE.POST name='Diagnosis'></st.ACTIVE.POST>
        </step>
        
        <step n='2' trg='FALSE' evt='MedicalVisit' date='09/10/2016 00:00:00' pMineR.internal.ID.Evt='2'>
        </step>
        
        <step n='3' trg='FALSE' evt='Imaging' date='18/10/2016 00:00:00' pMineR.internal.ID.Evt='3'>
        </step>
        
        <step n='4' trg='FALSE' evt='MedicalVisit' date='02/11/2016 00:00:00' pMineR.internal.ID.Evt='4'>
        </step>
        
        <step n='5' trg='TRUE' evt='Chemotherapy' date='10/11/2016 00:00:00' pMineR.internal.ID.Evt='5'>
            <st.ACTIVE.PRE name='Diagnosis'></st.ACTIVE.PRE>
            <fired.trigger name='Trigger 2'></fired.trigger>
            <st.ACTIVE.POST name='Therapy'></st.ACTIVE.POST>
        </step>
        
        <step n='6' trg='TRUE' evt='Dismission' date='01/12/2016 00:00:00' pMineR.internal.ID.Evt='6'>
            <st.ACTIVE.PRE name='Therapy'></st.ACTIVE.PRE>
            <fired.trigger name='Trigger 3'></fired.trigger>
            <st.ACTIVE.POST name='Dismission'></st.ACTIVE.POST>
        </step>
        
        <atTheEnd>
            <finalState name='Dismission'></finalState>
            <last.fired.trigger name='Trigger 3'></last.fired.trigger>
        </atTheEnd>
        
    </computation>
</xml>