<strong>Test</strong>: Compare Outputs
Contents
One of the powerful things about the Translator is the ability to traverse messages as “node trees” programmatically.
This makes it possible to write expressive code which can list differences between HL7 messages in a convenient manner where you can see the results in real time.
That’s exactly what I did for the next phase. I tweaked the dbfill.CompareMessage routine to obtain the original message and parse it into an HL7 node tree:
local function LoadMessage(Base, Msg)
local FileName = 'D:temp'..Base
..Msg.MSH[10]..'.txt'
trace(FileName)
local F = io.open(FileName, "r")
return F:read("*a")
end
function dbfill.CompareMessage(Data)
local Result = nil
local Out = hl7.parse{vmd='CVISOutbound.vmd', data=Data}
local Orig = LoadMessage('orig', Out)
if (Orig ~= Data) then
Result = 'Original and current messages differ!'
end
return hl7.parse{vmd='CVISOutbound.vmd', data=Orig}, Result, Orig
end
And then I wrote a utility module called ‘diff’ would returns a nice human readable list of differences between the two trees like this:

This made it very easy to locate the last few differences between the old interface and the new interface. The dialog would update in real time as I corrected the mappings. Here’s how it was called from the mapping routine:

There was still one small difference which my diff routine did not detect – this is because the older interface was appending a constant to a subfield using python whereas the vmd had it configured as a single field. The difference showed up when comparing the HL7 messages directly.
To resolve that problem would require a tweak to the vmd file.
Here’s the source code for the diff module, you need to create the diff module and paste this code into it.
Here’s the mapping file after the last set of changes:
require 'dateparse'
require 'node'
require 'dbfill'
require 'diff'
local conn = db.connect{
api=db.SQLITE,
name='test',
live=true
}
local function trace(a,b,c,d) return end
function main(Data)
local R = conn:query{
live=true,
sql="SELECT * FROM NHCCVISREPORT WHERE MESSAGE_ID = "..Data
}
local Msg = hl7.message{vmd='CVISOutbound.vmd', name='NHCCVIS'}
if #R == 0 then
print("Odd - unable to find message matching this one.")
return
end
MapMSH(Msg.MSH, R[1])
MapPID(Msg.PID, R[1])
MapPV1(Msg.PV1, R[1])
MapOBR(Msg.OBR, R[1])
MapOBX(Msg.OBX, R[1])
local Out = Msg:S()
if iguana.isTest() then
Compare(Msg, 'CVISOutbound.vmd')
end
queue.push{data=Out}
end
function Compare(Msg)
local Out = Msg:S()
local Orig = dbfill.CompareMessage(Out)
local R = diff.Compare(Orig:S(), Msg:S(), vmd)
trace('There were '..#R..' differences.')
end
function MapMSH(MSH, T)
MSH[9][1]='ORU'
MSH[9][2]='R01'
MSH[3][1] = 'NHCCVIS'
MSH[4][1] = 'NHC'
MSH[5][1] = 'PCS'
MSH[6][1] = 'EMR'
MSH[12] = '2.3'
MSH[10] = T.MSHMessageControlID
MSH[7] = T.MSHDateTimeofMessage:HT()
MSH[11][1] = 'T'
return MSH
end
function node.HD(N)
return os.date('%Y%m%d', dateparse.parse(N:S()))
end
function node.HT(N)
return os.date('%Y%m%d%H%M%S', dateparse.parse(N:S()))
end
function MapPID(PID, T)
PID[2][1] = T.PIDPatientIDExternalIDID
PID[2][3] = '11'
PID[2][4][1] = 'EMI Primary'
PID[3][1] = T.PIDPatientIDInternalIDID
PID[3][2] = T.PIDPatientIDInternalIDCheckDigit
PID[3][3] = '11'
PID[3][4][1] = 'MRN'
PID[5][1] = T.PIDPatientNameFamilyName
PID[5][2] = T.PIDPatientNameGivenName
PID[7] = T.PIDDateTimeofBirth:HD()
PID[8] = T.PIDSex
PID[18][1] = T.PIDPatientAccountNumberID
PID[18][4][1] = "Visit"
return PID
end
function MapPV1(PV1, T)
PV1[2] = 'OUTPATIENT'
PV1[3][1] = 'NHCCVIS Assign'
PV1[3][4][1] = 'NHC'
PV1[18] = 'NA'
PV1[19][1] = T.PVVisitNumberID
PV1[19][4][1] = 'Visit'
PV1[44] = T.PVAdmitDateTime:HT()
end
function MapOBR(OBR, T)
OBR[2][2] = 'PCS'
OBR[3][1] = T.OBRFillerOrderNumberEntityIdentifier
OBR[3][2] = 'NHCCVIS'
OBR[4][1] = T.OBRUniversalServiceIDIdentifier
OBR[4][2] = T.OBRUniversalServiceIDText
OBR[4][3] = 'NHCCVIS'
OBR[7] = T.OBRObservationDateTime:HT()
OBR[18] = T.OBRPlacerField
OBR[25] = 'F'
OBR[27][6] = 'ROUTINE'
return OBR
end
function MapOBX(OBX, T)
OBX[1][1] = '1'
OBX[1][2] = 'FT'
OBX[1][3][1] = T.OBXObservationIdentifierIdentifier
OBX[1][3][3] = 'NHCCVIS'
OBX[1][5][1] = T.OBXObservationValue
OBX[1][11] = 'F'
OBX[2][1] = '2'
OBX[2][2] = 'RP'
OBX[2][5][1] = T.OBXObservationValue1
OBX[2][3][1] = T.OBXObservationIdentifierIdentifier1
OBX[2][3][3] = 'NHCCVIS'
OBX[2][11] = 'F'
OBX[3][1] = '3'
OBX[3][2] = 'FT'
OBX[3][3][1] = T.OBXObservationIdentifierIdentifier2
OBX[3][3][2] = T.OBXObservationIdentifierText2
OBX[3][3][3] = 'NHCCVIS'
OBX[3][5][1] = T.OBXObservationValue2
OBX[3][11] = 'F'
end
Next Step?
The final step is make our last tweaks to code and the VMD file. However before that we will show the the source code for the diff module.