UNICORN result files
====================

UNICORN is a control/evaluation software supplied with ÄKTA chromatography systems from GE Healthcare. Every chromatography run generates a result file (res-file), which is a binary file containing metadata about the run and data retrieved from various sensors in the chromatography system. Common sensors included in most ÄKTA-Systems cover UV-absorption, pH, conductivity, system pressure etc.

The documentation supplied here is the result of reverse-engineering a limited number of such files obtained from ÄKTA Prime and ÄKTA Purifier systems. Different versions (especially newer ones) of UNICORN may generate files with different layout/encoding.

General layout (s. samples/sample1.res)
--------------------
START --> HEADER --> DATA_BLOCKS
To follow along - open sample1.res (under samples/) in a hex-viewer/editor. Hex numbers given in parenthesis are from the sample1.res. Padding bytes may not be explicitly described throughout this document.

---START---
Res-files start with a few check/info bytes:
- first 16 bytes are "11 47 11 47 18 00 00 00 B0 02 00 00 20 6C 03 00"
	most likely magic number to positively identify a res file
- next 4 bytes give EOF/file size (20 EA 0D 00)
	probably allow a check if recorded file size matches actual file
- next 4 bytes are empty
- next 12 bytes contain string "UNICORN 3.10" (55 4E 49 43 4F 52 4E 20 33 2E 31 30)
	file format version(?)
- at position 118 is the user name as used in Purifier systems or "prime" if the file originates from an ÄKTA Prime system. Length up to 40 characters. (70 72 69 6D 65)

---HEADER---
The header contains entries of the recorded data. Entries are made up of the original file name = run name ("Manual Run 3" for ex.) and name of data series (1_UV for ex.). Additionally their position in the file and several offsets are recorded. The header ends with the last entry called "LogBook" (notice capital "B").
- Entries start at position 686, first entry is either CONFIG or Methods
- Entries are 344 bytes
	FORMAT of entries
		- 8 bytes magic-id defining type of data (meta/sensor/aux etc). WARNING: If a file has been opened and resaved the 2nd last byte is incremented by one (see table at the end, ... 01 14 --> 02 14)
		- 296 bytes (incl. padding) Name of data entry (CONFIG, METHOD, Logbook, 1_UV, UV1_280nm etc.)
		- 4 bytes int, size of the data block
		- 4 bytes int, offset to next data block (from meta to meta)
		- 4 bytes int, adresse of the data block (including some metadata)
		- 4 bytes int, offset from metadata to actual data
			-> S. example below
		- entries that deal with data generated by the machine during the run (UV, pressure etc.) are preceeded by hex "00 00 01 00 04 00 01 14"
		- Last entry is called "LogBook" (notice capital B! LogBook only occurs once per file) preceeded by hex value "00 00 00 01 00 02 00 01 13"
The entries are followed by lots of padding and eventually the data blocks which hold the data.

Example values:
sample1.res	UV-entry (at 2366)
C8 A0 01 00 00 A2 01 00 20 92 03 00 F0 00 00 00
----V1----- ----V2----- ----V3----- ----V4-----
V1 (C8 A0 01 00) signed int, 106696 is the size of the data block including metadata
V2 (00 A2 01 00) signed int, 107008 is the offset to next data block (from meta to meta)
V3 (20 92 03 00) signed int, 234016 is the begin of the data block including metadata
V4 (F0 00 00 00) signed int, 240 is the offset from V2 to actual begin of data

---DATA_BLOCKS---
There are different types of data blocks:
- Sensor data, marked with "06 00 02 00 01 00 4E 00" (adresse specified in header)
- Metadata (type1, generated during the run), marked with "06 00 06 00 01 00 4E 00" (adresse specified in header)
- Metadata (type2, generated before run), no offset, pure string data, no special marker

Structure of sensor data
8 bytes per pair
4 bytes sig/int	Accumulated volume, divide by 100 to obtain value in ml
4 bytes sig/int	Sensor value, divide by 1000/100/10 depending on sensor type

Structure of meta-data/type1 (Logbook, Fractions etc.)
180 bytes per pair/trio
8 bytes double float	accumulated time (in minutes?)
8 bytes double float	accumulated volume (in ml)
164 bytes string		Logbook-event, Fraction number or "Waste"

Structure of meta-data/type2 (pure meta-data like method used during run)
- size defined in header (but maybe off by 1 or two bytes!)
- pure string
- string encoding is windows cp1250 / variants of it, depending on installed system

There are two logbooks per file. Logbook and LogBook (notice capital B in 2nd one). They contain similar but not exactly the same information. LogBook is always the last entry in a res-file. LogBook contains entries acc. to system time 
- strings in format like this "Concentration 0 %B.09, 21:51:45, Method : , Result : C:\...\prime\2009Jun16no001.RES"
- entries are separated by 202 bytes from begin to begin

----
Magic bytes preceeding header entries:
- System data shares same id
- Fractions and LogBook/Logbook have the same/similar format but have different id
- Ids are consistent across (at least two) different systems (Prime/Purifier)
- Ids for Logbook, sensor data (UV/cond/conc/...), Injection marks and fractions are changed if a file is opened and resaved (2nd last byte is incremented by one:
	Logbook 	... 48 04 --> ... 49 04
	Sens. data	... 01 14 --> ... 02 14
	Inj. mark	... 46 04 --> ... 47 04
	Fractions	... 44 04 --> ... 45 04

---Magic-ids---
The following magic_ids have been found and assigned so far:
AKTA PRIME
HEX VALUE					String
00 00 01 00 02 00 01 00		CONFIG
00 00 01 00 02 00 04 02		METHODINFO
00 00 01 00 02 00 03 22		CreationNotes = Program / plain text
00 00 01 00 04 00 48 04		Logbook
00 00 01 00 04 00 01 14		UV
00 00 01 00 04 00 01 14		Cond
00 00 01 00 04 00 01 14		pH
00 00 01 00 04 00 01 14		Pressure
00 00 01 00 04 00 01 14		Temp
00 00 01 00 04 00 01 14		Conc
00 00 01 00 04 00 44 04		Fractions
00 00 01 00 02 00 50 03		1
00 00 01 00 02 00 01 13		LogBook

AKTA PURIFIER
HEX VALUE					String
00 00 01 00 02 00 01 02		Methods
00 00 01 00 02 00 07 22 	MethodHistory
00 00 01 00 02 00 02 12 	DOCUMENT
00 00 01 00 02 00 03 22		CreationNotes
00 00 01 00 02 00 55 22 	StrategyInformation
00 00 01 00 02 00 10 22		MethodStrategyNotes
00 00 01 00 02 00 01 00		Methods Signatures
00 00 01 00 02 00 01 00		CONFIG
00 00 01 00 02 00 01 00		CALIB
00 00 01 00 02 00 04 02 	METHODINFO
00 00 01 00 02 00 10 22		ResultStrategyNotes
00 00 01 00 04 00 48 04		Logbook
00 00 01 00 04 00 01 14		UV1_280nm
00 00 01 00 04 00 01 14		UV2_254nm
00 00 01 00 04 00 01 14		UV3_0nm
00 00 01 00 04 00 01 14		Cond
00 00 01 00 04 00 01 14		Cond%
00 00 01 00 04 00 01 14		Conc
00 00 01 00 04 00 01 14		Pressure
00 00 01 00 04 00 01 14		Flow
00 00 01 00 04 00 01 14		Temp
00 00 01 00 04 00 01 14		AuxIn1
00 00 01 00 04 00 01 14		AuxOut1
00 00 01 00 04 00 01 14		P960_Press
00 00 01 00 04 00 01 14		P960_Flow
00 00 01 00 04 00 46 04		Inject
00 00 01 00 02 00 01 13		LogBook
