Raw Files
Because we don’t parse the PPG2, Accelerometer and BioZ files in the app, we’ve written an description on how to read these values.
General header and PPG2
Multi-color PPG file (PPG2):
This file contains a header and a body section. The file (header and body) contain some records. every record starts with 3 bytes with predefined values of 0x4F, 0x48, 0x52. The general format of the records is as following:
Record Format:
The 3 bytes at the beginning (called Sync pattern) [S0][S1] [S2], fixed values: [0x4F][0x48] [0x52] => ASCII “OHR”
Length [Llsb][Lmsb] Length of chunk,3. ID [ID] Chunk ID4. Payload [P0] .. [PLength-2] Payload (the data).
The header:
The header contains 3 records:
Time-size header:
- The 3 bytes Sync pattern [0x4F][0x48] [0x52] => ASCII “OHR”
- Length [Llsb][Lmsb] Length of the record excluding the first 5 bytes. normally it should be 0x00 0x11 = 17.
- ID [ID] = 0x0A
- Payload : p0-p3 : 4 bytes: The size of the file.
- p4-p11: 8 bytes reserved (normally zero).
- p12-p15: start time of the measurement. (this is the start time of the PPG2 measurement).
Version Header:
The 3 bytes Sync pattern [0x4F][0x48] [0x52] => ASCII “OHR” Length [Llsb][Lmsb] Length of the record excluding the first 5 bytes. it should be 0x00 0x1A. ID [ID] = 0x0B Payload : p0-p7 : 8 bytes reserved (normally zero). p8-p10: 3 bytes, FW version. something like 0, 3, 120
p11-p24: The name of the product (MMT287-2ph2) followed by 2 zeros at the end.
Host version header The 3 bytes Sync pattern [0x4F][0x48] [0x52] => ASCII “OHR” Length [Llsb][Lmsb] Length of the record excluding the first 5 bytes. it should be 0x00 0x20. ID [ID] = 0x0C Payload : p0-p30 : 31 bytes reserved
The body
The body of the file contains records of measurements.
measurements are from different metrics. each metric has its own ID. here is the list of IDs:
0x0F: PPG_multicolor
Multicolor PPF record:
The 3 bytes Sync pattern [0x4F][0x48] [0x52] => ASCII “OHR” Length [Llsb][Lmsb] Length of the record excluding the first 5 bytes. ID [ID] = 0x0F Payload : The payload contains the actual measurements of the PPG channels. since we have different channels (green, red, IR , ambient). one record may contain more than one channel of measurements. we have the following format for the data of each channel:
PPG chunk format:
- the Metric ID. PPG Green: 0x7E PPG Red: 0x7C PPG Red middle: 0x7D PPG InfraRed: 0x7E PPG Ambinet: 0x7F
- for every metric we have the following data:
Length (2 bytes) [Llsb][Lmsb] Length of the metric
index (1 byte): the packet index from 0 to 255.
quality (1 byte) : 4. // Deprecated, to ignore
BPI (1 byte) : Body position index
PF (1 byte): PPG sample format ( normally 0x60 )
SI (1 byte): Stream locations identifier* bit7 - bit4: Led bit3 - bit0: Photodiode
OFS (1 byte): PPG Offset bit7 – bit0: Offset
exp (1 byte): 0
Li (4 byte): Relative LED power [%] for each quarter of samples (M/4) 0..100: power
Gi (4 byte): Relative ADC gain used to obtain Pi for each quarter of samples (M/4) 0: gain factor 1x 1: gain factor 2x 2: gain factor 4x 3: gain factor 8x
Pi (N bytes) : Relative PPG level values (16 bit unsigned), translated into 32 bit unsigned: (Pi << Exponent) + (Offset 32768) = absolute PPG level relative ADC gain factor.
Accelerometer
Accelerometer File:
The format of the acceleromenter records are exactly like the ones for the multi-color PPG, only the metric ID is different as mentioned below.
The 3 bytes Sync pattern [0x4F][0x48] [0x52] => ASCII “OHR” Length [Llsb][Lmsb] Length of the record excluding the first 5 bytes. ID [ID] = 0x2B Payload : The payload contains the actual measurements of the 3-axis accelerometer, as following: Length [Llsb][Lmsb] Length of the payload
index: the packet index from 0 to 255.
quality : 4. // Deprecated, to ignore
BPI: Body position index
AF: Acceleration sample format , set to 6E for 32 Hz.
Then <X0,L> <X0,H> <Y0,L> <Y0,H> <Z0,L> <Z0,H>…<XM-1,L> <XM-1,H> <YM-1,L> <YM-1,H> <ZM-1,L> <ZM-1,H>
where:Xi : Acceleration along X axisYi : Acceleration along Y axisZi : Acceleration along Z axis
BioZ
BioZ File:
The BioZ file contains the skin conductance data of the user.
The format of the BioZ records are exactly like the ones for the multi-color PPG, only the metric ID is different as mentioned below.
The 3 bytes Sync pattern [0x4F][0x48] [0x52] => ASCII “OHR” Length [Llsb][Lmsb] Length of the record excluding the first 5 bytes. ID [ID] = 0x3E Payload : The payload contains the actual measurements of the skin conductance, as following: Length [Llsb][Lmsb] Length of the payload
Index: an index counter from 0 to 255.
quality: set to 4. // Deprecated, to ignore
BPI: Body position index
BioZF: BioZ sample format: 01 for 25 Hz.
Then <B0,0> <B0,1><B0,2> <B1,0> <B1,1><B1,2> …<B24,0> <B24,1><B24,2>
where:Bx,0 : Bioz index x the least significant byte (of 24 bits)
Bx,1 : Bioz index x the byte in the middle (of 24 bits)
Bx,2 : Bioz index x the most significant byte (of 24 bits)
Python script for parsing
You can use the script below to parse the WIFF files into readable data for PPG2, Accelerometer and BioZ.