HL7 to HL7

Mapping Codes

Now add the codemap module:

require 'codemap'

The codemap module has some helpful code to make it easy to write mapping code like this:

This map is translating F and M into Female and Male. There is also a default value of unknown for all other entries.

Here’s another example of a map you might use:

PatientClassMap = codemap.map{
   E='Emergency', 
   A='Ambulatory', 
   T='Trauma', 
   U='Urgent', 
   O='Outpatient'
}

-- with default added
PatientClassMap = codemap.map({
   E='Emergency', 
   A='Ambulatory', 
   T='Trauma', 
   U='Urgent', 
   O='Outpatient'},'unknown')

Another way of doing mapping from the Translator is to use database queries. Doing SQL SELECT queries from the Translator is extremely easy. We will cover those interfaces in the next module on database interfaces.

Tip: The call to codemap.map{} uses a “table syntax shorthand”, which allows character table indexes like [‘M’] to be replace with the single character M. This only works with letters as string indexes, if you wish to use a numeric string index you must use the longhand syntax.

-- shorthand table syntax
-- Lua knows M, m, F and f must be strings so it works
SexMap = codemap.map({
      M='Male',
      m='Male',
      F='Female',
      f='Female'
   }, 'unknown')

-- longhand version
SexMap = codemap.map({
      ['M']='Male',
      ['m']='Male',
      ['F']='Female',
      ['f']='Female'
   }, 'unknown')

-- you must use the longhand version with numeric indexes
SexMap = codemap.map({
      ['1']='Male',
      ['2']='Male',
      ['3']='Female',
      ['4']='Female'
   }, 'unknown')

-- shorthand version does not work with numeric indexes
-- Lua does not know if 1, 2, 3, 4 are strings or numbers so it does not work
SexMap = codemap.map({
      1='Male',
      2='Male',
      3='Female',
      4='Female'
   }, 'unknown')

If you need to catchup here is the code:

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

   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

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