Skip to content
Christopher Watford edited this page Aug 29, 2014 · 4 revisions

Sierra ECG Tools

This project provides reference implementations of readers for the Philips Sierra ECG XML format (v. 1.03 and 1.04), specifically focusing on the XLI compression format used. There are sample libraries for:

The XLI compression scheme utilizes LZW compression of deinterleaved delta codes. The format itself is not documented publicly, and the example applications given by Philips are not cross platform. This project enables end users of Sierra ECG data to utilize it in the language or their choice and on the platform of their choice.

XLI Compression in Detail

The XLI compression format is relatively straightforward. Each lead is stored in a contiguous block of data, delimited by header records. Each header record describes the information necessary to decompress a given lead. The general decompression process is as follows:

  1. Read the 8-byte header
  • Bytes 0-3: compressed data size (32-bit integer)
  • Bytes 4-5: currently unknown what it signifies, but always 1 (16-bit signed integer).
  • Bytes 6-7: first delta code in the sequence (16-bit signed integer).
  1. Read compressed data size bytes
  2. Decompress using LZW with 10-bit codes.
  3. The resulting buffer is split into two halves, interleave to create 16-bit delta codes
  • The first half contains the most significant bytes
  • The second half contains the least significant bytes
  1. Decode the data from the delta codes
  2. Reconstruct leads III, aVR, aVL, and aVF from leads I and II

Decompressed Data in Detail

The decompressed data is split into two halves, the MSB in the first half and the LSB in the second half. This is presumably done to improve the compression as the is little difference among the MSBs.

# input contains the decompressed data
# output will contain the interleaved 16-bit delta codes
fun unpack( input[], output[], nSamples )
    for i <- 1..nSamples
        output[i] <- (input[i] << 8) | input[nSamples + i]
    endfor
endfun

Delta Coding Scheme in Detail

The delta coding scheme used appears to require the two prior samples and is bias-64; this is possibly a form of linear predictive coding.

# output contains the 16-bit delta codes
# first is the 16-bit delta code from the chunk header
fun deltaDecompression( output[], nSamples, first )
    x <- output[1]
    y <- output[2]
    prev <- first
    for i <- 3..nSamples
        z <- (2 * y) - x - prev
        prev <- output[i] - 64
        output[i] <- z
        x <- y
        y <- z
    endfor
endfun

Limb Lead Reconstruction in Detail

Reconstruction of the remaining limb leads (III, aVR, aVL, and aVF) should be done after the completion of the delta decompression. The channel data for each of the leads appears to be used to ensure the proper sign of the output data, and also includes what may be a noise component.

# Lead III
for i <- 1..nSamples
    leads{III}[i] = leads{II}[i] - leads{I}[i] - leads{III}[i]
endfor

# Leads aVR, aVL, and aVF
# (these rely on Lead III, so be sure to calculate it first)
for i <- 1..nSamples
    leads{aVR}[i] = -leads{aVR}[i] - (leads{I}[i] + leads{II}[i]) / 2
    leads{aVL}[i] = (leads{I}[i] - leads{III}[i]) / 2 - leads{aVL}[i]
    leads{aVF}[i] = (leads{II}[i] + leads{III}[i]) / 2 - leads{aVF}[i]
endfor