Data logging: midas files
mlogger reads data from an event buffer and writes it to disk. The data is generally produced by frontends, but in principle any midas client can write events to a buffer. mlogger can also handle special types of "event" including messages and storing a full copy of the ODB at the start/end of each file.
Data format primer
Details of the event data format are available in Event data format. The key thing to note for now is that midas does not care about the content of the event - it just provides a standard way to tag metadata such as:
- event ID - which program produced the event
- trigger mask - an extra identifier set by the program that generated the event (often used to distinguish the trigger source - physics-like event, periodic event, calibration event etc)
- timestamp - the time the event was generated
Multiple channels
mlogger can handle multiple "channels" of data. The channels can read from different event buffers, and even filter the data based on the event ID and trigger mask.
The vast majority of experiments just use a single logging channel, recording all events that get written to the SYSTEM buffer. This is the default configuration.
To add an extra channel, create more entries in /Logger/Channels. Although the default channel is called 0, you do not have to just use numbers for your channel names. You can even rename the default channel if desired. To add more channels, you should copy/paste an existing channel, using either the web interface or the command-line:
odbedit -c 'copy "/Logger/Channels/0" "/Logger/Channels/new_channel"'
The Statistics subdirectory contains information about the amount of data written
Whether data should get written
The global boolean ODB key /Logger/Write data determines whether to write data to disk or not. This only affects event data - the history system has its own keys for determining whether data gets written.
There are also per-channel ODB keys /Logger/Channels/xxx/Active that can disable a channel even if the global Write data is true.
Data sources
Frontends
The main data logger to midas files is midas events written to an event buffer. Frontends are the main producers of such events, but in principle any midas client can write events to a buffer.
You must specify which buffer mlogger should read from, and can filter events based on event header metadata.
/Logger/Channels/xxx/Bufferspecifies the buffer to read from. The default isSYSTEM./Logger/Channels/xxx/Event IDspecifies which equipment's events to log. The default value of -1 means "no filtering"./Logger/Channels/xxx/Trigger maskspecifies a bitmask to compare against each event's trigger mask. If any bit matches, the event is logged. The default value of -1 means "no filtering".
Each logging channel can only read from a single buffer.
Messages
Midas messages are automatically saved to the midas message log text files. However you can also log them to midas data files if desired.
The ODB key /Logger/Channels/xxx/Log messages enables this, and allows you to specify which message types get logged. mlogger will automatically connect to the SYSMSG buffer if you ask for messages to be logged in data files.
Log messages bitmask
The Log messages ODB key is a bitmask with the following meanings:
- 1 = Error messages
- 2 = Info messages
- 4 = Debug messages
- 8 = User messages
- 16 = Log messages
- 32 = Talk messages
- 64 = Call messages
Set it to 255 to log all messages in the midas data file; set it to 0 (the default) to only log in the message log, not in midas data files.
Details of how message events appear in the file are found in Event data format.
ODB at begin/end of file
mlogger can automatically save a copy of the ODB to a text file at the start of each run.
It can also store a copy at the start and end of each midas file. This is particularly useful when you are analyzing data, as all your configuration parameters are recorded in the same file as the raw data itself.
/Logger/Channels/xxx/ODB dumpis a boolean that says whether to save a copy of the ODB in each midas file/Logger/Channels/xxx/ODB dump formatspecifies the format to use -jsonorxml.
Details of how message events appear in the file are found in Event data format. Note that although documentation (and the acronyms BOR/EOR) refer to these as begin-of-run and end-of-run dumps, they are actually written at the begin/end of each subrun.
Where to write the data
The channel Output determines what happens to the data - valid options are FILE and FTP. The default is FILE.
Obsolete and internal options
- The
Outputoption ofROOTis obsolete. Instead, users should either implement a custom program that reads events from buffers and writes them to a ROOT file, use post-processing tools to convert a midas file, or implement a lazylogger script to perform the conversion. - The
Outputoptions ofPIPEandNULLare only used for internal testing. - The
Typekey is obsolete. It should be left asDisk, as writing toTapeis no longer supported.
Writing to disk
Setting /Logger/Channels/xxx/Output to FILE results in midas files getting written to disk.
The location where midas files get written is based on:
- the global directory specified in
/Logger/Data dir - the per-channel sub-directory specified in
/Logger/Channels/xxx/Subdir format. This can use a strftime format to create new subdirectories based on date/time. This can help you avoid having thousands of files in the same directory, which can be unwieldy to handle. - the per-channel filename specified in
/Logger/Channels/xxx/Filename. This can use%dplaceholders to replace the run and/or subrun. - whether any compression is enabled using
/Logger/Channels/xxx/Compress. This automatically appends a compression suffix such as.lz4or.gz.
Example destination settings
| ODB key | Value |
|---|---|
| /Logger/Data dir | /path/to/dir |
| /Logger/Channels/xxx/Subdir format | %Y_%m_%d |
| /Logger/Channels/xxx/Filename | run%05d_%04d.mid |
| /Logger/Channels/xxx/Subrun byte limit | 10000000 |
| /Logger/Channels/xxx/Compress | lz4 |
Resulting path for subrun 0 of run 1234 taken on 31 Dec 2026:
/path/to/dir/2026_12_31/run01234_0000.mid.lz4
Details
- The
Subdir formatis optional (and empty by default, meaning all files get written to the same directory). - If the
Filenamecontains only one%character, only the run number gets substituted. If it contains two, it is always the run number first, then the subrun number. - Subdirectories are created automatically if needed.
Subdir formatuses the time that each file is created, not the time that the run started! So if you are using subruns, have a run that lasts several days, and have a subdir format of%y%m%d, your files for that run could be split across multiple directories!- If the
Filenamestarts with a/, theData dirandSubdir formatare ignored. In this case, you must ensure that the relevant directory exists, as it is NOT created automatically. - lazylogger doesn't look in subdirectories. If you use it to copy the files, leave
Subdir formatempty.
Writing to FTP
Setting /Logger/Channels/xxx/Output to FTP results in midas files getting written to an FTP server. mlogger streams the data (i.e. the FTP connection remains open while data is being acquired, rather than writing data to a temporary local file and then copying the final file via FTP).
The /Logger/Channels/xxx/Filename key specifies all the FTP connection details. Subdir format and Data dir are not used for FTP channels.
The Filename can take one of two formats:
ftp_host,port,user,password,remote_directory,filename_format
ftp_host,port,user,password,remote_directory,filename_format,mode
Example FTP settings
# Run number substitution only, no explicit permissions
myhost.my.domain,21,john,password,/usr/users/data,run%05d.mid
# Run and subrun number substitution, with explicit permissions
myhost.my.domain,21,john,password,/usr/users/data,run%05d_%04d.mid,660
Details
- The default FTP
portis 21, or 1021 for a Unitree Archive. - The
filenameformat can use%dplaceholders to replace the run and/or subrun. If it contains only one%character, only the run number gets substituted. If it contains two, it is always the run number first, then the subrun number. - The optional
modeis the UNIX access permissions to apply to the file.666will allow all users to read/write the file;600will allow only the owner to read/write the file etc.
Data compression
The /Logger/Channels/xxx/Compress key allows you to compress a file so it takes up less space on disk (at the cost of being slower to read the file later, as you need to then decompress it).
Valid compression algorithms are gzip, lz4, bzip2 and pbzip2. The default is lz4, and this will be sufficient for most users. You can disable compression by setting the Compress key to none.
| Algorithm | File extension | Is the default | Supported writing to disk |
Supported writing over FTP |
|---|---|---|---|---|
none |
N/A | |||
lz4 |
.lz4 |
|||
gzip |
.gz |
|||
bzip2 |
.bz2 |
|||
pbzip2 |
.bz2 |
There are extra options available for the gzip, bzip2 and pbzip2 algorithms to fine-tune the compression level:
- lz4 always uses the default compression level.
- The gzip compression level can be set using the
Gzip compressionkey. Valid numbers are 1-9, with 1 giving the fastest speed, and 9 giving maximum compression. 0 means no compression! A common value is 6. - The bzip2 compression level can be set using the
Bzip2 compressionkey. Valid numbers are 1-9, with 1 giving the fastest speed, and 9 giving maximum compression. 0 will result in the system default (probably 9). - pbzip2 has 3 settings.
Pbzip2 compressionsets the compression block size. Valid numbers are 1-9, with 1 giving the fastest speed, and 9 giving maximum compression. 0 will result in the system default (probably 9).Pbzip2 num cpusets the number of CPUs to use for the parallel compression code.Pbzip2 optionsis a string containing any other parameters you wish to pass to thepbzip2command-line program. The-zand-coptions are already set.-pis also already set ifPbzip2 num cpuis > 0.
Key name is Compress not Compression!
Note that the Compression key (an integer) is obsolete. The Compress key (a string) is the one to use to enable compression.
Checksums for data corruption checks
Checksums are small strings of data that let you check if a file has been corrupted. They don't let you fix the corruption, but are useful for verifying data integrity.
Midas provides checksums for both the pre-compressed data and compressed data. Both support the same checksum algorithms: CRC32C, SHA256, SHA512 and ZLIB. You can also disable writing of checksum files by setting an algorithm of NONE.
/Logger/Channels/xxx/Data checksumspecifies the pre-compressed checksum algorithm/Logger/Channels/xxx/File checksumspecifies the post-compressed checksum algorithm
The checksums are written to small text files containing the checksum itself, the size of the file in bytes, and the filename:
Example of a .crc32c file
For a given run, we may end up with 3 files:
run30805.mid.crc32c # Data checksum
run30805.mid.lz4 # Data file
run30805.mid.lz4.crc32c # File checksum
The below content would be found in run30805.mid.lz4.crc32c:
8285ea51 334379 /path/to/run30805.mid.lz4
The fields are: checksum, size in bytes, filename.
The available algorithms are:
| Checksum | Is the default | File extension | Tool to verify with |
|---|---|---|---|
NONE |
N/A | N/A | |
CRC32C |
.crc32c |
cat <file> | crc32c_sum |
|
SHA256 |
.sha256 |
sha256 -q <file> |
|
SHA512 |
.sha512 |
sha512 -q <file> |
|
ZLIB |
.crc32zlib |
crc32 <file> |
Example of verifying a checksum
This example uses the crc32c option (which is the default). See the table above for the tools to use for the other checksum types.
# See that midas wrote 3 files for this run.
# The checksum files are very small; the .mid.lz4 is the real data.
$ ls run30805.mid*
run30805.mid.crc32c
run30805.mid.lz4
run30805.mid.lz4.crc32c
# Compute checksum of .mid.lz4 file
$ cat run30805.mid.lz4 | crc32c_sum
8285ea51
# Note it matches the first entry in the .mid.lz4.crc32c file
$ cat run30805.mid.lz4.crc32c
8285ea51 334379 /path/to/run30805.mid.lz4
# The 2nd entry in the .mid.lz4.crc32c file matches the file size of the .mid.lz4 file
$ ls -l run30805.mid.lz4
-r--r--r-- 1 ben staff 334379 1 Jun 14:42 run30805.mid.lz4
# Decompress the .lz4 and compute the checksum of the .mid file
$ unlz4 run30805.mid.lz4
$ cat run30805.mid | crc32c_sum
ee53b826
# Note it matches the first entry in the .mid.crc32c file
$ cat run30805.mid.crc32c
ee53b826 10451573 /Users/ben/DAQ/test_expt/run30805.mid
Details about the filenames
If compression is enabled:
- the "data checksum" is written to
<file>.<cksum_ext>(e.g. file.mid.crc32c) - the "file checksum" is written to
<file>.<compress_ext>.<cksum_ext>(e.g. file.mid.lz4.crc32c)
If compression is disabled:
- the "data checksum" is written to
<file_minus_last_ext>.<cksum_ext>(e.g. file.crc32c) - the "file checksum" is written to
<file>.<cksum_ext>(e.g. file.mid.crc32c)
In the latter case, both checksums are based on the same (uncompressed) data.
Run and subrun duration
mlogger can automatically stop a run after a certain time period has elapsed, and can split data from one run across multiple files (called subruns). More advanced run control logic can be implemented using the sequencer.
| Variable | Stop run | Move to next subrun |
|---|---|---|
| Time | ||
| Data size (bytes) | ||
| Number of events |
Run duration
mlogger can automatically stop a run based on 3 criteria:
/Logger/Run durationspecifies a time in seconds/Logger/Channels/xxx/Byte limitspecifies a total data size in bytes/Logger/Channels/xxx/Event limitspecifies a total number of events
In all cases, a value of 0 means no limit. For the per-channel settings, the first channel to reach the limit will cause the run to stop.
Auto restart
You can request that mlogger automatically restart the run if it is stopped due to one of the above criteria. /Logger/Auto restart enables this feature, and /Logger/Auto restart delay specifies a time in seconds to wait between one run stopping and the next one starting.
mlogger will not automatically restart a run if it is stopped for any other reason (e.g. the user stopping a run manually, or the disk getting full).
Subrun duration
mlogger can automatically start a new subrun based on 3 criteria:
/Logger/Subrun durationspecifies a time in seconds/Logger/Channels/xxx/Subrun Byte limitspecifies a file size in bytes/Logger/Next subrunis a boolean that a user (or code) can set to request a new subrun
A duration or size limit of 0 means no limit. Subruns start at 0 and increment each time a new file is opened.
Note that if you are using subruns, you should ensure that your filename format includes a placeholder for both the run number and subrun number!
Warning if you have multiple channels
When a user sets Next subrun to true, there is a race condition between channels. The first one to react and start a new subrun will set the flag back to false. The other channels will then not handle the Next subrun request.
It is strongly recommended that you do not use the Next subrun flag unless you only have one channel active.
In practice, the vast majority of experiments use size-based limits on their subruns.
Note that the checks are performed only AFTER an event has been written. That means that a new subrun is only started once the limit has been exceeded.
Analyzing midas files
Analysis of midas files generally requires one to write some code, and this is covered in Data analysis.
Statistics and disk level
The ODB directory /Logger/Channels/xxx/Statistics contains details about the amount of data written and the current disk fullness. Full details of all the keys can be found in the ODB reference.
Stopping the run if disk is getting full
If mlogger is writing files to disk (not via FTP), the amount of space left on the disk will be checked, and the fraction of the disk that is full (from 0 for empty to 1 for full) will be written to /Logger/Channels/xxx/Statistics/Disk level.
A fullness bar is shown on the main status webpage.
If the Type is Disk (not anything else) and the Output is FILE (not FTP), then the run will stop automatically when the disk is getting full. The limits are hardcoded:
- if the disk is > 100GB, the run will stop when there is less than 1GB free
- if the disk is 10-100GB, the run will stop when there is less than 100MB free
- if the disk is < 10GB, the run will stop when there is less than 10MB free
These checks are only performed if a channel is active and data-writing is enabled.