HL7 to HL7

Inserting NTE segments

We’re going to add some NTE (note) segments to the end of each Lab message. First we need to detect when we have a Lab message so we can call a function to add the NTE segments to Lab messages only:

And this is how we write the AddNote routine:

We use a few useful features of Lua here. Firstly, the note is expressed using Lua’s very convenient long string syntax. This makes it simple to write blocks of text over many lines with a very simple syntax.

The string has embedded \n characters which we can see if we click on it and change the View Mode to Escaped Text:

That makes it easy to split the string into the array of Lines:

Looping through those and setting up NTE segments is then easy.

The final node tree looks like

Which is rendered as a flatwire like:

And here is the code for the AddNote() function that you can copy if you need to:

local NoteTemplate=[[
Clown.  Good madonna, why mournest thou?
Olivia. Good fool, for my brother's death.
Clown.  I think his soul is in hell, madonna.
Olivia. I know his soul is in heaven, fool.

Clown.  The more fool, madonna, to mourn for your brother's
soul being in heaven--Take away the fool, gentleman.
]]

function AddNote(Out)
   local Lines = NoteTemplate:StripLastReturns():split('\n')
   for i=1, #Lines do
      Out.NTE[i][1] = i
      Out.NTE[i][3][1] = Lines[i]
   end
   return Out
end

And the complete code up till now:

require 'split'
require 'zsegment'
require 'diff'
require 'hl7util'
require 'dateparse'
require 'stringutil'
require 'clean_phone'
require 'codemap'

local function trace(a,b,c,d) return end

function main(Data)
   local Orig = hl7.parse  {vmd = 'transform.vmd', data = Data}

   if Orig:nodeName() == 'Catchall' then
      iguana.logInfo('Filtered '..Orig.MSH[9][1]..'^'..Orig.MSH[9][2])
      return
   end

   local Out  = hl7.message{vmd = 'transform.vmd', name = Orig:nodeName()}
   Out:mapTree(Orig)

   local Copy = zsegment.copyZSegments(Data, Out:S())
   CheckTransform(Data:StripLastReturns(), Copy:StripLastReturns())

   AlterMSH(Out.MSH)
   local PID = hl7util.findSegment(Out, FindPID)
   if PID then
      AlterPID(PID)   
   end

   if Out:nodeName() == 'Lab' then 
      AddNote(Out)
   end

   trace(Out)
   local Diff = diff.Compare(Orig:S(), Out:S(), 'transform.vmd')
   local DataOut = Out:S()
   DataOut = zsegment.copyZSegments(Data, DataOut)
   DataOut = DataOut:StripLastReturns()
   trace(DataOut)
   queue.push{data = DataOut}
end

local NoteTemplate=[[
Clown.  Good madonna, why mournest thou?
Olivia. Good fool, for my brother's death.
Clown.  I think his soul is in hell, madonna.
Olivia. I know his soul is in heaven, fool.

Clown.  The more fool, madonna, to mourn for your brother's
soul being in heaven--Take away the fool, gentleman.
]]

function AddNote(Out)
   local Lines = NoteTemplate:StripLastReturns():split('n')
   for i=1, #Lines do
      Out.NTE[i][1] = i
      Out.NTE[i][3][1] = Lines[i]
   end
   return Out
end

function FindPID(Segment)
   if Segment:nodeName() == 'PID' then
      return true
   end
end

SexMap = codemap.map({
      M='Male',
      m='Male',
      F='Female',
      f='Female'
      }, 'unknown')

function AlterPID(PID)
   local Date = dateparse.parse(PID[7]:nodeValue())
   PID[7]          = os.date("%Y%m%d", Date)
   PID[5][1][1][1] = PID[5][1][1][1]:nodeValue():capitalize()
   PID[5][1][2]    = PID[5][1][2]:nodeValue():capitalize()
   PID[13][1][1]   = PID[13][1][1]:CleanPhone()
   PID[8]          = SexMap[PID[8]]

   trace(SexMap['any other value'])
   return PID
end

function AlterMSH(MSH)
   MSH[3][1] = 'Acme'
   MSH[4][1] = 'Lab'
   return MSH
end

function CheckTransform(Orig, Copy)
   if Orig ~= Copy then
      trace(Orig)
      trace(Copy)
      error('Copy of HL7 message does not match the original')
   end   
end

function string.StripLastReturns(S)
   -- strip return(s) "\r" & "\n" from the end of a string
   local i = #S
   while S:byte(i) == 10 or S:byte(i) == 13 do
      i = i - 1
   end
   return S:sub(1,i)
end