This article was originally written for Iguana 5 so it uses version 5 screenshots, and may have some outdated references.
Extracting patient height and weight from an ADT message is more tricky than it sounds. The problem is that this information is typically stored in an OBX segment and encoded as a lab result. For instance:
MSH|^~\&|AcmeMed|Lab|Main HIS|St. Micheals|20110213144932||ADT^A03|9B38584D9903051F0D2B52CC0148965775D2D23FE4C51BE060B33B6ED27DA820|P|2.6| EVN||20110213144532||||20110213145902| PID|||4525285^^^ADT1||Smith^Tracy||19980210|F||Martian|86 Yonge St.^^ST. LOUIS^MO^51460|||||||10-346-6|284-517-569| NK1|1|Smith^Gary|Second Cousin| PV1||E||||||5101^Garland^Mary^F^^DR|||||||||||1318095^^^ADT1|||||||||||||||||||||||||20110213144956| OBX|||WT^WEIGHT||102|pounds| OBX|||HT^HEIGHT||32|cm|
One needs to write code to iterate through message, to find the appropriate OBX segment with the right code. Then the units are often non standard. Extracting this data is a problem which lends itself well to writing a reusable module. I have done this and here is an example of using it: You can see that the functions return four values:
- The quantity converted into metric units.
- The metric unit.
- The original value.
- The original unit.
This makes it easy for the interface programmer to validate that mapping is safe and valid. If weight or height information is not found then the function returns nil. We can optionally supply a second parameter to these functions to determine the rounding. In the next screenshot I tweaked the call for getting the patient weight to round to zero decimal places: It may be necessary to add more units and expected codes that describe height and weight in the module. The code should be relatively clear to read and see where that needs to be done. Be good to get feedback from what variability people see in the field with this information.
Source code for the htwt patient height and weight extraction library
Here’s the source code for the htwt module. To use it:
- Create a new shared module called “htwt” and copy paste in the below.
- Add the code require(‘htwt’) at the top of the main module.
- Test using sample data.
htwt={} function htwt.GetPatientWeight(Msg, Round) return GetObxProperty(Msg, htwt.Set{"WT", "WEIGHT", "WGT"}, Round) end function htwt.GetPatientHeight(Msg, Round) return GetObxProperty(Msg, htwt.Set{"HT", "HEIGHT", "HGT"}, Round) end function GenerateAlias(UnitMap) for k,v in pairs(UnitMap) do if not v.alt then break end for _, Alias in pairs(v.alt) do UnitMap[Alias] = v end end return UnitMap end -- This map assumes we are mapping to metric units. It is incomplete. You -- will need to add more unit definitions. htwt.unitmap=GenerateAlias{ pound={'kg', 0.45359237, 1, alt={'pounds', 'lb', 'lbs'}}, stone={'kg', 6.35029318, 1, alt={'st'}}, kg ={'kg', 1, 1, alt={'kilo', 'kilos'}}, cm ={'m', .01, 2, alt={'cms', 'centimetre'}}, } function GetObxProperty(Msg, CodeSet, Round) local OBX = htwt.findSegment(Msg, htwt.ObxFilter, CodeSet) if not OBX then return end local V = OBX[5][1]:nodeValue() local U = OBX[6][1]:nodeValue() local Vout,Uout = MapUnit(V,U,Round) return tostring(Vout), Uout, V, U end function htwt.Round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end function MapUnit(V,U, Round) local M = htwt.unitmap[U:lower()] if not M then error("Unit "..U..' is not defined.') end U = M[1] if not Round then Round = M[3] end local Vout,Uout = MapUnit(V,U,Round) return tostring(Vout), Uout, V, U end function htwt.Set(List) local set = {} for _, V in ipairs(List) do set[V] = true end return set end function htwt.ObxFilter(Segment, CodeSet) print(CodeSet) if Segment:nodeName() == 'OBX' then if CodeSet[Segment[3][1]]:nodeValue() then return true end end return false end function htwt.findSegment(Msg, Filter, Param) for i=1, #Msg do if (Msg[i]:nodeType() == 'segment' and Filter(Msg[i], Param)) then return Msg[i] end end for i=1, #Msg do local T = Msg[i]:nodeType() if (T == 'segment_group' or T == 'segment_repeated') then local R = htwt.findSegment(Msg[i], Filter, Param) if R ~= nil then return R end end end end function node.S(ANode) return tostring(ANode) end