This page is part of the Personal Health Device FHIR IG (v0.1.0: STU 1 Draft) based on FHIR R3. The current version which supercedes this version is 1.0.0. For a full list of available versions, see the Directory of published versions

DIM Metrics to FHIR Mapping: Details

In this section the details of the mapping of the 11073 20601 Metric objects to FHIR resources are discussed.

Definition of a Metric Measurement

The 11073 20601 protocol is not only extensible but self-describing. The PHG does not need to know, in advance, anything about the type of measurements the PHD supports. All of this information is provided in the protocol exchanges. That exchange may involve the sending of data that is not a measurement, for example the user may change the units on a weight scale from pounds to kilograms. The scale will inform the PHG of this change. If that change is sent without an accompanying weight, the incidence of the change alone makes no sense to send downstream. Consequently, a measurement is only reported if the PHD sends one of twelve attributes in the metric event (called a Scan Event Report in 11073-20601 language). These attributes are:

Mesurement Attribute Description
Basic-Nu-Observed-Value Contains a single number encoded as an Mder SFLOAT
Simple-Nu-Observed-Value Contains a single number encoded as a Mder FLOAT
Compound-Basic-Nu-Observed-Value Contains multiple numbers encoded as Mder SFLOATs
Compound-Simple-Nu-Observed-Value Contains multiple numbers encoded as Mder FLOATs
Nu-Observed-Value Contains single number encoded as an Mder FLOAT along with units and type data
Compound Nu-Observed-Value Contains multiple numbers encoded as an Mder FLOATs with units and type data
Simple-Sa-Observed-Value Contains a sequence of scaled periodic numeric values
Enum-Observed-Value-Simple-OID Contains a measurement that is an MDC code
Enum-Observed-Value-Basic-Bit-Str Contains a measurement that is an ASN1 BITs string in 16-bits
Enum-Observed-Value-Simple-Bit-Str Contains a measurement that is an ASN1 BITs string in 32-bits
Enum-Observed-Value-Simple-Str Contains a measurement that is human-readable string (rare)
Enum-Observed-Value Contains a measurement that is a 32-bit ASN1 BITs, MDC code, or String plus type data

A metric measurement always contains one and only one of the above attributes. If a metric event is sent by the PHD that does NOT contain one of the 12 measurement attributes, the metric event is providing information so the PHG can decode any subsequently sent measurements.

Again, these details are only of concern to the encoder of the FHIR resources, the consumer of the FHIR resources is not concerned with the types of attributes delivered by the PHD.

Metric Protocol-Only Attributes

Protocol-Only attributes are not mapped to FHIR.

In the 11073 20601 specification measurements are mapped to Metric Objects. The Metric Object contains several attributes that are used to describe the measurement such as the Type, Unit-Code, and Simple-Nu-Observed-Value. However, it also contains attributes that are only of interest to the PHG for the purposes of decoding the measurement. For the purposes of optimization on the wire, the PHD only sends attributes that have changed when it sends a measurement. The PHG is expected to retain static and dynamic information. There are also techniques used to more efficiently encode the data and tell the PHG how big and in what sense this data may come. To accomplish this encoding the PHD sends keys describing the encoding and the PHG uses these keys to decode the data. These keys are not meant for security purposes but just to minimize data transmission.

Attributes are also used for these keys. Once the measurement has been reconstructed using these keys and the retained static and dynamic data, the attributes providing these keys are no longer of interest. This guide will refer to these attributes as 'Protocol-Only' attributes.

Protocol-Only Attribute Description
Handle Provides the PHG with a key to access the static and dynamic information associated with this metric
Metric-Spec-Small Gives info about the delivery and nature of the metric events
Metric-Structure-Small Gives info about the number of entries in compound attributes
Capability-Mask-Basic Inicates which of the 16-bit ASN1 BITs are supported by PHD
Capability-Mask-Simple Inicates which of the 32-bit ASN1 BITs are supported by PHD
State-Flag-Basic Inicates whether the 16-bit ASN1 BITs are a 'state' or an 'event'
State-Flag-Simple Inicates whether the 32-bit ASN1 BITs are a 'state' or an 'event'

The last four attributes are essential for the decoder to properly map ASN1 BITS measurements to FHIR using the ASN1 coding system but the attributes themselves are not of interest once mapped. For example, the Capability-Mask-* attribute tells which bits are supported by the PHD. The encoder needs to know which bits these are but once known, the attribute value itself is no longer of interest. The State-Flag-* indicates to the decoder whether the bit is an event or a state. If an event, only the set case (event occured) needs to be recorded, for example, 'sensor malfunctioned' in the sensor status measurement of several specializations. If a 'state' both the set or cleared case needs to be reported, for example 'patient in room' or 'patient not in room' in the independent living case.

Mder FLOATs and SFLOATs

Mder FLOATs and SFLOATs are the 11073 20601 means of encoding floating point numbers. The primary reason for this encoding is to indicate the precision of the measurement. The SFLOAT is 16-bits and the FLOAT is 32-bits. In the SFLOAT, the most significant 4 bits is the exponent and the remaining 12 bits the mantissa. In the FLOAT, the most significant byte is the exponent and the remaining 24 bits the mantissa. Both the exponent and mantissa are signed.

The exponent gives the precision. It indicates where the decimal point goes in the mantissa. A negative exponent of -N moves the decimal point to the left N places and a positive exponent of +N moves the decimal point to the right N places.

Thus it is possible in this encoding to distinguish between the value 2, 2.0, 2.00, etc. Numerically, they all have the same value, but 2.00 indicates that the value is two but taken with a sensor that has a precision to the hundredths.

The table below gives some examples of SFLOAT values and how they shall be encoded into the FHIR valueQuantity.value:

SFLOAT Hex SFLOAT decimal exponent mantissa FHIR encoding
0x0002 2 0 2 2
0xF014 61460 -1 20 2.0
0xE0C8 57544 -2 200 2.00
0x1002 4098 1 2 20
0x2002 8194 2 2 200
0x00C8 200 0 200 200
0x04D2 1234 0 1234 1234
0x0B2E 2862 0 -1234 -1234

In the FLOAT case the above values would be encoded as follows:

FLOAT Hex FLOAT decimal exponent mantissa FHIR encoding
0x00000002 2 0 2 2
0xFF000014 4278190100 -1 20 2.0
0xFE0000C8 4261413064 -2 200 2.00
0x01000002 4098 1 2 20
0x02000002 33554434 2 2 200
0x000000C8 200 0 200 200
0x000004D2 1234 0 1234 1234
0x00FFFB2E 16775982 0 -1234 -1234

Special Values

The Mder encoding also has a set of 5 reserved special values which represent some type of error condition. They are as follows:

FLOAT Case SFLOAT case meaning FHIR encoding
0x007FFFFF 0x7FF Not a Number (NaN) .dataAbsentReason set to 'NaN'
0x007FFFFE 0x7FE Positive Infinity (+inf) .dataAbsentReason set to 'PINF'
0x00800002 0x802 Negative Infinity (-inf) .dataAbsentReason set to 'NINF'
0x00800000 0x800 Not at this resolution .dataAbsentReason set to 'error'
0x00800001 0x801 Reserved for future use .dataAbsentReason set to 'error'

CodeableConcepts

In this guide there will be several instances where the 11073 10101 nomenclature (MDC) codes are mapped to FHIR. In almost all cases this mapping involves an element that is a CodeableConcepts data type. The mapping is as follows:

  • CodeableConcept.coding.code = partition * 216 + term code
  • CodeableConcept.coding.system = urn:iso:std:iso:11073:10101
  • CodeableConcept.coding.display = reference identifier (optional)

The display element is optional since the uploader may not know what the code means, in particular if the uploader works with a PHD specialization developed after the uploader had been released. However, this guide strongly encourages that the display element contain at least the normative reference identifier for the MDC code if it is known.

Obtaining the Observation.code

Every 11073 20601 metric instance is required to have a Type attribute. In most cases, the Type attribute value maps directly to the Observation.code element. However, the metric object may contain other attributes which modify or change this value. The following algorithm indicates the procedure an encoder can take to obtain the Observation.code entry:

  • set partition = Type.partition
  • set termCode = Type.code
  • if there is a Metric-Id attribute:
    • set termCode = Metric-Id
    • if there is a Metric-Id-Partition attribute:
      • set partition = Metric-Id-Partition
  • if there is a Nu-Observed-Value or Enum-Observed-Value
    • set termCode = *-Observed-Value.metric
  • final 32-bit MDC code: value = partition * 216 + termCode

Once this MDC code value is obtained, the Observation.code element is populated as follows:

  • if the application wishes to transcode this MDC code into other coding systems the application is free to do so but
    • the MDC code shall be in the first Observation.code.coding element
    • if the code matches one of the FHIR LOINC magic codes, the LOINC magic code shall be in the second Observation.code.coding element
    • any other coding translations desired are placed in subsequent Observation.code.coding elements.
  • for the MDC code the mapping is as follows:
    • Observation.code.coding.code = value
    • Observation.code.coding.system = "urn:iso:std:iso:11073:10101"
    • Observation.code.display should contain the reference identifier as part of the text.

The requirement for the MDC reference identifier is not mandatory and is not used as the Observation.code.coding.code value because the reference identifier is not provided by the sensor device in the exchange protocol. Requiring the reference identifier would require that the PHG have an internal map. However, the main reason for not requiring the reference identifier is that doing so would defeat future interoperability. An older PHG would not know the reference identifier of a new specialization.

The consumer of PHD data does not need to concern itself with this complexity. All it needs to do is obtain the first Observation.code.coding.code element to get the measurement type.

Obtaining the Unit Code

Measurements that are quantities (numerics and real-time-sample-arrays) will have units. Though the 11073 20601 specification allows units for enumeration measurements, the use of units for such measurements does not make sense and this profile assumes that enumeration measurements will never have units.

Obtaining the units in most cases is a simple as decoding the Unit-Code attribute. However, the Nu-Observed-Value and Compound-Nu-Observed-Value attributes have their own unit code, and this value overrides the value in the Unit-Code attribute. When these attributes are received applications will need to obtain the unit code from the unit_code subtructure.

11073-20601 unit codes are 11073-10101 MDC values in partition DIM which has a value of 4. The partition value is assumed in the 20601 exchange and only the term code value of the units are actually sent. The FHIR encoder will need to create the 32 bit code from the term code and the assumed partition value of 4.

ASN1 BITs Value Set

11073 PHDs report some measurements as a 16- or 32-bit integer where each bit in the integer may mean something. There is no HL7 data type that treats this kind of measurement. Continua has created a value set where each of the possible bit settings in a given measurement is mapped to a code. The code can be reported in a CodeableConcept data type.

The uploader can generate the code from the data received from the PHD. No external information is necessary unless the uploader wants to populate the 'display' element of the CodeableConcept data type. It is recommended that the uploader populate the display element with at least the 11073 specialization ASN1 name for the bit setting. It is not required because it is desired to have an uploader that can still work with future specializations and in that case it is not possible for the uploader to know what the 11073 specialization ASN1 name is as it is not sent over the wire; it is only available from the specialization documents.

To generate the code, the uploader obtains the code for the type of measurement which is used to populate the Observation.code.coding.code element. Then for each bit to be reported, the new ASN1 code is generated by appending a period followed by the Mder Bit position being mapped. Thus a 16-bit ASN1 BITs measurement may correspond to 16 codes, and a 32-bit ASN1 BITs measurement may correspond to 32 codes!

Each code is reported in an Observation.component.code.coding.code element which means there may be up to 16 or 32 component elements in the measurement. An ASN1 bit can only have two values, set or cleared. Thus the value is reported in the Observation.component.valueCodeableConcept.coding.code element using the HL7 Version 2 binary coding system; "Y" for set and "N" for cleared.

  • As an example, the continuous glucose monitor specialization has a Device status measurement whose type is given by the code 8418060. If the value reported in the BITs field is 0001 1000 0000 0000 the Mder bits set are bits 3 and 4. Note that Mder bit 0 is the HIGH order bit. Bit 3 means 'sensor malfunction' and bit 4 means 'device specific alert'. This measurement would require two component elements and one would be 8418060.3 and the other would be 8418060.4. Note these are alpha-numeric strings and not decimal numbers. If one took the code 8418060.3 and looked it up in the ASN1 Bits vocabulary one would find it meant 'sensor malfunctioned'.

Reporting Requirements

If the ASN1 bit represents an event, only the set condition needs to be reported. If the ASN1 bit represents a state, both the set and cleared conditions need to be reported. If the device does not support the bit, it is not required to report the value. If the uploader would, nevertheless, desire to report the unsupported situation it is done in an Observation.component.dataAbsentReason.coding.code element with code "unsupported". The Observation.component.value[x] element is absent.

In an upcoming version of the 11073 20601 specification the enumeration metric object will support both a Capability-Mask-Simple/Basic and State-flag-Simple/Basic attribute that must be present when an enumeration BITs measurement is reported. The Capability-Mask attribute will have a bit set when the corresponding bit in the actual measurement is supported by the device. The State-Flag attribute will have a bit set if the corresponding bit is an state. If cleared, the corresponding bit is a event.

However, these attribute are not present in the versions of the 11073-20601 specification that are currently used by PHDs. Thus the uploader will need to obtain this information from the ASN1 mapping tables (TODO).

Mder Bit Position

In order to generate this code the uploader needs to understand that Mder Bit position 0 is the most significant bit of the 16- or 32-bit integer and the Mder Bit position 15 or 31 is the least significant bit of the 16- or 32-bit integer, respectively. The following table shows the Mder bit position and the corresponding integer value representing it when that bit is set.

Mder Bit Position 16-bit integer value 32-bit integer value
0 0x8000 0x80000000
1 0x4000 0x40000000
2 0x2000 0x20000000
3 0x1000 0x10000000
4 0x800 0x8000000
5 0x400 0x4000000
6 0x200 0x2000000
7 0x100 0x1000000
8 0x80 0x800000
9 0x40 0x400000
10 0x20 0x200000
11 0x10 0x100000
12 0x8 0x80000
13 0x4 0x40000
14 0x2 0x20000
15 0x1 0x10000
16 0x8000
17 0x4000
18 0x2000
19 0x1000
20 0x800
21 0x400
22 0x200
23 0x100
24 0x80
25 0x40
26 0x20
27 0x10
28 0x8
29 0x4
30 0x2
31 0x1

Example mapping

A pulse Oximeter sends a ‘Device and sensor annunciation status’ measurement. The Type attribute value for this measurement is MDC_PULS_OXIM_DEV_STATUS which has a term code 19532 in the partition SCADA (2). The 32-bit code value is then 2 * 216 + 19532 or 150604. The defined ASN.1 bits for this measurement in the pulse oximeter specialization are:

bit position ASN.1 Item Description
0 sensor-disconnected Agent reports that the sensor is disconnected from the instrument.
1 sensor-malfunction Agent reports that the sensor is malfunctioning or faulting.
2 sensor-displaced Agent reports that the sensor is not properly attached or has been dislodged, and accurate measurement is, therefore, prevented.
3 sensor-unsupported An unsupported sensor is connected to the agent.
4 sensor-off Agent reports that sensor is not connected to the user.
5 sensor-interference Agent reports that there is interference due to ambient light or electrical phenomena.
6 signal-searching Signal analysis is currently in progress prior to measurement availability.
7 signal-pulse-questionable Agent determines that a questionable pulse is detected.
8 signal-non-pulsatile Agent detects a nonpulsatile signal.
9 signal-erratic Agent reports that the signal is erratic or is not plausible.
10 signal-low-perfusion Agent reports a consistently low perfusion condition exists.
11 signal-poor Agent reports a poor signal exists, possibly affecting accuracy.
12 signal-inadequate Agent reports that the incoming signal cannot be analyzed or is inadequate for producing a meaningful result.
13 signal-processing-irregularity Agent has determined that some irregularity has been detected while processing the signal.
14 device-equipment-malfunction A general device fault has occurred in the agent.
15 device-extended-update An extended display update is currently active.

The mapped codes reported in the FHIR Observation.component.coding.code elements are given by

HL7 Code ASN.1 name bit type
150604.0 sensor-disconnected event
150604.1 sensor-malfunction event
150604.2 sensor-displaced event
150604.3 sensor-unsupported event
150604.4 sensor-off event
150604.5 sensor-interference event
150604.6 signal-searching event
150604.7 signal-pulse-questionable event
150604.8 signal-non-pulsatile event
150604.9 signal-erratic event
150604.10 signal-low-perfusion event
150604.11 signal-poor event
150604.12 signal-inadequate event
150604.13 signal-processing-irregularity event
150604.14 device-equipment-malfunction event
150604.15 device-extended-update event

Generating the PHD Reported Time Stamp Identifier

This algorithm shows how one generates the time stamp as reported by the PHD for use in the Observation.identifier element. The Observation.identifier element is used in the PHD profiles to perform conditional creates and thus eliminate data duplication.

  • If the sensor reports absolute time this string will be encoded as an HL7 DTM YYYYMMDDTHHMMSS.ss.
    • Example 1: The sensor reports absolute time as an 8-byte Binary Coded Decimal (BCD) Mder OCTET STRING: 0x20 0x07 0x02 0x01 0x12 0x05 0x20 0x86 which is the date and then the time. reported_sensor_timestamp = 20070201120520.86
    • Example 2: The BTLE sensor reports absolute time as a 7-byte string with no hundredths and it is not BCD or Mder. The year is the first two bytes in little endian thus 0x7E0 = 2016: 0xE0, 0x07, 0x05, 0x17, 0x11, 0x34, 0x11 reported_sensor_timestamp = 20160523T175217.00
  • If the sensor reports base-offset time this string will be encoded as seconds.fractional_seconds.offset. The sensor reports base offset time as an 8-byte string. The first four bytes are the seconds since 1900/01/01 00:00:00 (not the Unix Epoch!), the next two bytes the fractional seconds in units of 1/65536th of a second and the last two bytes are the offset in minutes. Only the offset is signed.
    • Example: 8-byte Mder OCTET STRING: 0xD4 0x67 0x40 0x38 0x13 0x14 0xFE 0xD4. The seconds are 0xD4674038 = 3563536440, fractional seconds 0x1314 = 4884, and offset -300.
      • The reported_sensor_timestamp = 3563536440.4884.-300.
      • If offset is positive: reported_sensor_timestamp = 3563536440.4884.+300
  • If the sensor reports relative time the string will be the reported value in units of 1/8th seconds as a decimal unsigned integer with no leading zeros. On the wire this value is an Mder sequence of 4 bytes with the MSB to the left.
  • If the sensor reports high resolution relative time, the string will be the number of microseconds as an unsigned integer with no leading zeros. On the wire this value is an Mder sequence of 8 bytes with the MSB to the left.