Date: Fri, 29 Mar 2024 10:38:53 +1000 (AEST) Message-ID: <1476762293.1152.1711672733692@dsp-kbconf-01.ad.medicalobjects.com> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_1151_773613809.1711672733684" ------=_Part_1151_773613809.1711672733684 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
This worked example will walk you through the insertion of GELLO code on= decision arms for the '? anaemia' decision in the GORD (Gastro-oesop= hageal reflux) example. A GLIF file is provided (GORD_start.GLIF) tha= t is suitable to use; along with some test patient data in xml format.
Anaemia is a low haemoglobin (hemoglobin) level, and in the GORD guideli= ne example represents a compelling reason for early endoscopy, as there may= be a cancer of the esophagus or stomach causing the reflux symptom.
Open and unzip the attached folder. Open the GLIF file with = the GLIF Editor.
It opens at the "top level" guideline. There are three sub-guidelines an= d they can be accessed by clicking through the guideline itself or by scrol= ling down on right hand side (RHS) of the menu bar:
Go to the "consider early endoscopy" sub-guideline.
Notice the decisions, as elsewhere are pink. They are not automated as yet=
. So we will do that for the anaemia decision.
You can write GELLO for GLIF decisions and test it against loaded patient =
data. Let's load some data. This is in xml format and you can look at=
the test data in notepad++ as well if you like.
Go back to the top level guideline then go File, =
Load xml Test data. Choose test.xml. Go back to the "consider earl=
y endoscopy" guideline.
Now click on the Allow modifications button&n= bsp;
Position the cursor on the "yes" arrow coming out of the "Anaemia?" decisi=
on such that you get a little hand with the finger pointing onto the arrow.=
Double click and go Edit:
.. to get to the GELLO editor screen:
The main panes are the middle workspace and the RHS Model Explorer, Data E=
xplorer and Results Explorer.
Lets take a minute to look at the Model Explorer.
Unfold on System Packages. From the bottom up, GLIF_VMR models a representation of GLIF that accords with 'level B' described =
on page 7 of the document GLIF_=
TECH_SPEC_May_4_2004.pdf. So this is the model that understands where&n=
bsp; and what we can see and do with GELLO in Level A GLIF artifacts such a=
s nodes/steps. Make particular note of the attributes required for a GLIFDe=
cision Result as we use them later on. Above GLIF_VMR is HL7_v2_VMR_V1. Thi=
s is a draft HL7 standard virtual medical record model that Medical Objects=
balloted successfully in 2013. Most of the world uses V2 messaging so we c=
an build a CDS suitable model out of what people currently use and send bac=
k and forth.
Notice some classes in there such as Allergy and Observation. These clas= ses have attributes that use ISO 21090 data types such as CD and TS:<= /p>
Fold all that up and the next level up is SNOMED CT.&nb= sp; SNOMED CT is a large medical ontology looked after by IHTSDO.org. GELLO= uses it especially for subsumption queries, with the "implies"method. We w= on't see this today but it is useful in the homework at the end ;-)
IHTSDO Licenses
= span>Above this is iso_21090_datatypes. If you look up the C=
D datatype in here you can see that is about coded values and that the impl=
ies method is understood by this datatype.
Ok lets go back to the middle workspace. Notice the editor puts the first =
line in for you. We are in a context of a GLIF Decision node.
Our first line of GELLO below this context statement will be:
1 + 1
Compile it (five buttons in from LHS top menu). All good, now run it (se= ven buttons in from LHS top menu). Can you see the result now in Results Ex= plorer?
Because we have loaded test data we can see it and start to think about ho=
w we can get to the data we need for a decision as to whether the lat=
est hemoglobin result (if it exists) is too low.
To just see what we have loaded, clear the '1 + 1' line and simply= type 'vmr'
Run that and unfold the result in Results Explorer. Can you see 31 Obser= vations? Have a look at the first one:
Class Observation gets used a lot. Here we can see it has an observation=
Code (unfold that too for a look - see it in turn has a code, a codeSystem =
and a codeSystemName); a value which is of type Physical Quantity and a dat=
eTime.
Returning to the workspace code, when using the stand alone GELLO editor&n=
bsp; we can specify what packages are being imported. This is useful for an=
extended vmr model or to import a Library with its pre-made functions.
Saying 'Imports HL7_v2_VMR_V1 ' directly after the Context=
statement is important in other contexts, but is usually not needed in the=
GLIFEditor environment.
Lets get all the Hemoglobin observations.
We can see in the image from just above that observations is a sequence of=
instances of class Observation. So we can use a select operator as this is=
a sequence and make use of the observationCode.
Here's two lines to put in now in the workspace. We will make local variab=
les with 'Let' statements. Clear the 'vmr' line we had and cut and paste:=
p>
Let hemoglobin:CD =3D CD{code =3D '718-7',
= codeSyst= em =3D '2.16.840.1.113883.6.1',
&nb= sp; codeSystemName =3D'LN'}
<= br> Let allHbObservations =3D vmr.observations->select(observationCo= de =3D hemoglobin)
Compile and run. The first line makes a local variable of type CD that i=
s then plugged in the select operator in the second. The codeSystemName is =
'LN" which is short for LOINC and 718-7 is the code. [Find this in the text=
.xml data if you like. You can read about this code by googling "hipaa 718-=
7". Loinc is produced by the Regenstrief Institute.]
Now are there any error messages? - look down the bottom... Unlike '=
hemoglobin:CD' we haven't specified a datatype for the variable 'allHbObser=
vations'. This compile error didn't stop the code we have running, so its n=
ot critical. It is in fact sometimes useful to leave a LHS variable untyped=
and to see what is actually being returned from the RHS; but let's put in =
what is now suggested, and the line in question becomes:
Let allHbObservations: Sequence(Observation) =3D vmr.observations-= >select(observationCode =3D hemoglobin)
Note vmr.observations is a sequence of Observation = p>
The second error message is that there is no final expression. Gello is ma=
de of an inner expression (in) an outer expression. We haven't done the fin=
al declarative line yet that constitutes the outer expression. This will be=
the GLIFDecisionResult object we come up with at the end of this GEL=
LO expression.
Making use of the populated dateTime attribute in class Observation:
Let mostRecentHb =3D allHbObservations->last()
If you run/compile that couple of times you should again get the error s= uggesting a type for LHS, so becomes:
Let mostRecentHb: Observation =3D allHbObservations->sortedBy(d= ateTime)->last()
and screenshot after running is :
Now we need to see if mostRecentHb is too low ( ie if the patient is ane= mic). Make a threshold for anaemia, say 115 g/l.
Let anaemiaThreshold: PQ =3D factory.PQ(115,'g/L')
Yup - there is a factory to which we send a method PQ (to make a Physica=
l quantity - which has attributes of value: Real and units: String)
Need to make 'mostRecentHb' a PQ as well (currently an Observation); so&nb=
sp;
Let mostRecentHBAsPQ: PQ =3D mostRecentHb.value.oclAsType(PQ)
We are getting the value of the Observation ( which here is a P=
Q type) but we need to make it explicitly a PQ using the oclAsType(PQ=
) method. Its a GELLO 2 thing...
[As an aside when you have just put a dot after some code, there is code a=
utocomplete available which can help guide you ]
Now we compare the two to get a boolean intermediate answer:
Let hemoglobinIsLow:Boolean =3D mostRecentHBAsPQ < anaemiaThres= hold
and running this returns true for the 'hemoglobinIsLow' variable.
But we need a final declarative statement, and this should be a type of GL=
IFDecisionResult as we are in a GLIF decision arrow for "yes" , so the fina=
l GELLO to be added is:
--need to return a GLIFDecisionResult as we are doing a GLIF D= ecision
let q: String =3D "Is haemoglobin below 115 g/l?"
= let aWeight: Integer =3D 50
Let result:GLIFDecisionResult = =3D
if not mostRecentHb.oclIsDefined() then
GLIFDecis= ionResult{Question =3D q,Answer =3D unknown, Reason =3D "No haemoglob= in observations",Weight =3D aWeight}
else
if hemoglo= binIsLow
then
GLIFDecisionResult{Q= uestion =3D q,Answer =3D true, Reason =3D "Haemoglobin is above thres= hold",Weight =3D aWeight}
else
GLI= FDecisionResult{Question =3D q,Answer =3D false, Reason =3D "Haemoglo= bin in not above threshold",Weight =3D aWeight}
endif
endi= f
result
Ok here we have two new variables for the result object ( as required fo=
r a GLIFDEcisionResult - see the model in model explorer), a test for no da=
ta, and if-then statements for the final result.
Here is screen shot of this working in the GLIFeditor's gello editor we ar=
e using:
Not quite finished. Its a good idea to put GELLO in all decision arrows =
coming out of an automated GLIF Decision. So for "no" we would be very simi=
lar to this but just change around the final result.
This is how it looks now after clicking through the first pink colored dec=
ision:
You can save and reuse the state of this GLIF by File, =
Save State; then re open the GLIF file as a new instance i=
n the editor and go File, Run Glif with State.
Maybe you can try building a new simple GLIF file now as 'homework', for a=
decision as to whether a patient (test.xml) has a penicillin allergy .
=
This GLIF file is not yet complete. Another exercise we could do is to loo=
k at the Decisions in management subguideline, adding GELLO to make the dec=
isions automatic but using persisted, previously entered archetype data fro=
m the top level. Using ISO 13606 archetypes in GLIF will be another tutoria=
l topic.