<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.