Skip to main content

Joulescope™ file format

Project description

main

JLS

Welcome to the Joulescope® File Format project. The goal of this project is to provide performant data storage for huge, simultaneous, one-dimensional signals. This repository contains:

  • The JLS file format specification
  • The implementation in C
  • Language bindings for Python

Features

  • Cross-platform
    • Microsoft Windows x64
    • Apple macOS x64
    • Apple macOS ARM
    • Linux x64
    • Linux aarch64 (ARM 64-bit). Supports Raspberry Pi 4.
  • Support for multiple, simultaneous data sources
  • Support for multiple, simultaneous signal waveforms
  • Fixed sample rate signals (FSR)
    • Handles missing samples gracefully (interpolate) 🔜
    • Multiple data types including:
      • Floating point: f32, f64
      • Unsigned integers: u1, u4, u8, u16, u24, u32, u64
      • Signed integers: i4, i8, i16, i24, i32, i64
      • Fixed-point, signed integers (same bit sizes as signed integers)
      • Boolean (digital) 1-bit signals = u1
  • Variable sample rate (VSR) signals 🔜
  • Fast read performance
    • Signal Summaries
      • "Zoomed out" view with mean, min, max, standard deviation
      • Provides fast waveform load without any additional processing steps
    • Automatic load by summary level
    • Fast seek, next, previous access
  • Sample ID to Wall-clock time (UTC) for FSR signals
  • Annotations
    • Global VSR annotations
    • Signal annotations, timestamped to sample_id for FSR and UTC time for VSR
    • Support for text, marker, and user-defined (text, binary, JSON)
  • User data
    • Arbitrary data included in the same file
    • Support for text, binary, and JSON
  • Reliability
    • Integrated integrity checks using CRC32C
    • File data still accessible in the case of improper program termination 🔜
    • Uncorrupted data is still accessible in presence of file corruption 🔜
    • Write once, except for indices and the doubly-linked list pointers
  • Compression options 🔜
    • lossless 🔜
    • lossy 🔜
    • lossy with downsampling below threshold 🔜
    • Support level 0 DATA not written (only INDEX & SUMMARY) 🔜

Items marked with 🔜 are under development and coming soon. Items marked with ⏳ are planned for future release.

As of June 2023, the JLS v2 file structure is well-defined and stable. However, the compression storage formats are not yet defined and corrupted file recovery is not yet implemented.

Why JLS?

The world is already full of file formats, and we would rather not create another one. However, we could not identify a solution that met these requirements. HDF5 meets the large storage requirements, but not the reliability and rapid load requirements. The Saleae binary export file format v2 is also not suitable since it buffers stores single, contiguous blocks. Sigrok v2 is similar. The Sigrok v3 format (under development as of June 2023) is better in that it stores sequences of "packets" containing data blocks, but it still will does not allow for fast seek or summaries.

Timeseries databases, such as InfluxDB, are powerful tools. However, they are not well-designed for fast sample-rate data.

Media containers are another option, especially the ISO base media file format used by MPEG4 and many others:

However, the standard does not include the ability to store the signal summaries and our specific signal types. While we could add these features, these formats are already complicated, greatly reducing the advantage of repurposing them.

Why JLS v2?

This file format is based upon JLS v1 designed for pyjoulescope and used by the Joulescope test instrument. We leveraged the lessons learned from v1 to make v2 better, faster, and more extensible.

The JLS v1 format has been great for the Joulescope ecosystem and has accomplished the objective of long data captures (days) with fast sampling rates (MHz). However, it now has a long list of issues including:

  • Inflexible storage format (always current, voltage, power, current range, GPI0, GPI1).
  • Unable to store from multiple sources.
  • Unable to store other sources and signals.
  • No annotation support: 41, 93.
  • Inflexible user data support.
  • Inconsistent performance across sampling rates, zoom levels, and file sizes: 48, 103.
  • Unable to correlate sample times with UTC: 55.

The JLS v2 file format addressed all of these issues, dramatically improved performance, and added new capabilities, such as signal compression.

How?

At its lowest layer, JLS is an enhanced tag-length-value (TLV) format. TLV files form the foundation of many reliable image and video formats, including MPEG4 and PNG. The enhanced header contains additional fields to speed navigation and improve reliability. The JLS file format calls each TLV a chunk. The enhanced tag-length component the chunk header or simply header. The file also contains a file header, not to be confused with the chunk header. A chunk may have zero payload length, in which case the next header follows immediately. Otherwise, a chunk consists of a header followed by a payload.

The JLS file format defines sources that produce data. The file allows the application to clearly define and label the source. Each source can have any number of associated signals.

Signals are 1-D sequences of values over time consisting of a single, fixed data type. Each signal can have multiple tracks that contain data associated with that signal. The JLS file supports two signal types: fixed sample rate (FSR) and variable sample rate (VSR). FSR signals store their sample data in the FSR track using FSR_DATA and FSR_SUMMARY. FSR time is denoted by samples using timestamp. FSR signals also support:

  • Sample time to UTC time mapping using the UTC track.
  • Annotations with the ANNOTATION track.

VSR signals store their sample data in the VSR track. VSR signals specify time in UTC (wall-clock time). VSR signals also support annotations with the ANNOTATION track. The JLS file format supports VSR signals that only use the ANNOTATION track and not the VSR track. Such signals are commonly used to store UART text data where each line contains a UTC timestamp.

Signals support DATA chunks and SUMMARY chunks. The DATA chunks store the actual sample data. The SUMMARY chunks store the reduced statistics, where each statistic entry represents multiple samples. FSR tracks store the mean, min, max, and standard deviation. Although standard deviation requires the writer to compute the square root, standard deviation keeps the same units and bit depth requirements as the other fields. Variance requires twice the bit size for integer types since it is squared.

Before each SUMMARY chunk, the JLS file will contain the INDEX chunk which contains the starting time and offset for each chunk that contributed to the summary. This SUMMARY chunk enables fast O(log n) navigation of the file. For FSR tracks, the starting time is calculated rather than stored for each entry.

The JLS file format design supports SUMMARY of SUMMARY. It supports the DATA and up to 15 layers of SUMMARIES. timestamp is given as a 64-bit integer, which allows each summary to include only 20 samples and still support the full 64-bit integer timestamp space. In practice, the first level summary increases a single value to 4 values, so summary steps are usually 50 or more.

Many applications, including the Joulescope UI, prioritize read performance, especially visualizing the waveform quickly following open, over write performance. Waiting to scan through a 1 TB file is not a valid option. The reader opens the file and scans for sources and signals. The application can then quickly load the highest summary of summaries for every signal of interest. The application can very quickly display this data, and then start to retrieve more detailed information as requested.

Example file structure

sof
header
USER_DATA(0, NULL)    // Required, point to first real user_data chunk
SOURCE_DEF(0)         // Required, internal, reserved for global annotations
SIGNAL_DEF(0, 0.VSR)  // Required, internal, reserved for global annotations
TRACK_DEF(0.VSR)
TRACK_HEAD(0.VSR)
TRACK_DEF(0.ANNO)
TRACK_HEAD(0.ANNO)
SOURCE_DEF(1)         // input device 1
SIGNAL_DEF(1, 1, FSR) // our signal, like "current" or "voltage"
TRACK_DEF(1.FSR)
TRACK_HEAD(1.FSR)
TRACK_DEF(1.ANNO)
TRACK_HEAD(1.ANNO)
TRACK_DEF(1.UTC)
TRACK_HEAD(1.UTC)
USER_DATA           // just because
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_INDEX(1.FSR, lvl=0)
TRACK_SUMMARY(1.FSR, lvl=1)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_INDEX(1.FSR, lvl=0)
TRACK_SUMMARY(1.FSR, lvl=1)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_DATA(1.FSR)
TRACK_INDEX(1.FSR, lvl=0)
TRACK_SUMMARY(1.FSR, lvl=1)
TRACK_INDEX(1.FSR, lvl=1)
TRACK_SUMMARY(1.FSR, lvl=2)
USER_DATA           // just because
END
eof

Note that TRACK_HEAD(1.FSR) points to the first TRACK_INDEX(1.FSR, lvl=0) and TRACK_INDEX(1.FSR, lvl=1). Each TRACK_DATA(1.FSR) is in a doubly-linked list with its next and previous neighbors. Each TRACK_INDEX(1.FSR, lvl=0) is likewise in a separate doubly-linked list, and the payload of each TRACK_INDEX points to the summarized TRACK_DATA instances. TRACK_INDEX(1.FSR, lvl=1) points to each TRACK_INDEX(1.FSR, lvl=0) instance. As more data is added, the TRACK_INDEX(1.FSR, lvl=1) will also get added to the INDEX chunks at the same level.

Resources

References

License

This project is Copyright © 2017-2023 Jetperch LLC and licensed under the permissive Apache 2.0 License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyjls-0.11.1.tar.gz (359.9 kB view details)

Uploaded Source

Built Distributions

pyjls-0.11.1-cp313-cp313-win_amd64.whl (213.3 kB view details)

Uploaded CPython 3.13 Windows x86-64

pyjls-0.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.13 manylinux: glibc 2.17+ x86-64

pyjls-0.11.1-cp313-cp313-macosx_10_13_universal2.whl (452.2 kB view details)

Uploaded CPython 3.13 macOS 10.13+ universal2 (ARM64, x86-64)

pyjls-0.11.1-cp312-cp312-win_amd64.whl (213.8 kB view details)

Uploaded CPython 3.12 Windows x86-64

pyjls-0.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

pyjls-0.11.1-cp312-cp312-macosx_10_13_universal2.whl (456.3 kB view details)

Uploaded CPython 3.12 macOS 10.13+ universal2 (ARM64, x86-64)

pyjls-0.11.1-cp311-cp311-win_amd64.whl (219.2 kB view details)

Uploaded CPython 3.11 Windows x86-64

pyjls-0.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

pyjls-0.11.1-cp311-cp311-macosx_10_9_universal2.whl (462.6 kB view details)

Uploaded CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

pyjls-0.11.1-cp310-cp310-win_amd64.whl (218.3 kB view details)

Uploaded CPython 3.10 Windows x86-64

pyjls-0.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

pyjls-0.11.1-cp310-cp310-macosx_10_9_universal2.whl (460.9 kB view details)

Uploaded CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

File details

Details for the file pyjls-0.11.1.tar.gz.

File metadata

  • Download URL: pyjls-0.11.1.tar.gz
  • Upload date:
  • Size: 359.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.8

File hashes

Hashes for pyjls-0.11.1.tar.gz
Algorithm Hash digest
SHA256 587c3c0369ab9cb2ab7e8ffe8bbe3b41025cb36cc4b42a050f3d69c1368028a7
MD5 c18af49594ebf28a54c386ba9c40324c
BLAKE2b-256 3ac142be7ee868a23b9224852983fe519b9b7e28d656b8614373fa26a8b19dfc

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pyjls-0.11.1-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 213.3 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.8

File hashes

Hashes for pyjls-0.11.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 39f75b128ba7df73c8b664f553f5749a8077e5e02e77038fe98c5404750efe18
MD5 4d876c374e8d6e21c7876fcdd981dd21
BLAKE2b-256 16bd2718b0021af9556b2a660c55f9f450c3daa1c2bfa581f0202d6d5b25341e

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6f4d0f0b5d8b3851502da03ce38fc245868d706ede9d3536eb6aea58068cb044
MD5 d747d62dcf17efc51e88928068748168
BLAKE2b-256 b1dfda57558b13eb9608cb5530879eae0bca60764a4565e8fc971bc7e1c8a1ed

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp313-cp313-macosx_10_13_universal2.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp313-cp313-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 71b9ed37b810e68c137b74dd27a0a56ef2dc0b9f9d8fb86c0ad4c73faaafe226
MD5 d95be74a9e54a0feae37aeacba335023
BLAKE2b-256 90035e1f6f2d050e566b8974901f01a223043b72cd690814504cb8d93106b2f7

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pyjls-0.11.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 213.8 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.8

File hashes

Hashes for pyjls-0.11.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 c54ec1bb25d72a50bd3e528997befd66c435cffb097ffdb2560d68ca415a3154
MD5 8050739b0ee1fb25ca99c79b6e3878ad
BLAKE2b-256 8924f822c0341c62b34127ce5206647016014f3a36630d87246ecb6fafc73200

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 78e5de95966f72dfad668d90f009475e7cceb389d1385bf4ae2784153e75d16a
MD5 31c9ba695c25b35888dacb3fa59cb121
BLAKE2b-256 8d981be4f45a42c85e13183bd288eede3320a7e0263cb58c1f36e3193035e44c

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp312-cp312-macosx_10_13_universal2.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 c5fadeb64d35a984cda102dc383b14ad8aed445d138ffc2494b0a5cb3c9843a1
MD5 b382434069916f82cd3af141affedea5
BLAKE2b-256 d2e6206570af10e9f681f4c66c96f4a0241540e78c1dd3029597640e795c7975

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pyjls-0.11.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 219.2 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.8

File hashes

Hashes for pyjls-0.11.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 d1c179f84e786b1d1d8b7b1bd29c4761405fcbab78d211e440efb88581527e66
MD5 ca616557906935eaa26e4dbfdce45568
BLAKE2b-256 4ae425dee9b582e51103f0d2ed8d915bc205f856e7d3f2c313d7c2de9ec9f1d5

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cd0197e8d4a375be1af6e8aafec484c57513b05a1a934915190cb0f8bf7a1560
MD5 262626ccf794094ccfeef9083e66b1e5
BLAKE2b-256 bbd947adeb34cc683d4f1282528be0b3575995325d79d0489c14cbb4691ae6cd

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp311-cp311-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 8082177e27b38a9b77d8fb7cb96e5f1e5519247808ccc47c3d7c10f8d44852e2
MD5 c983250ba9edd8850fcecf78dd2acc06
BLAKE2b-256 392b658a7b2a9d184e8588356e3173cd43faa1b57c36efad9abe602fc70d3745

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: pyjls-0.11.1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 218.3 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.8

File hashes

Hashes for pyjls-0.11.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 e9f7fc6ca89607146c92aa813cc4811cf7a2c371f33b90126e73c1a9ee2c2ecd
MD5 0955304df69bc91d8c2ccda0ea4c615e
BLAKE2b-256 d9025ce0da009c7e04fcb9a5abebaf99694096a0eebda5fef47218c9fdddafac

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6fc4b2e3587a55ed5c5a5b5f0cc7ac4f31ef8f376b2f4e59a95d8d2f6330cdf5
MD5 8ee20480aa3e52bb462f6d9a71540655
BLAKE2b-256 67db479202d59afe7b9a5f6b25fdeb5bf26e6bb11b64236f14f46e187b5cb49a

See more details on using hashes here.

File details

Details for the file pyjls-0.11.1-cp310-cp310-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for pyjls-0.11.1-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 64488ba3d63cf8058986503f01c0491b8ac8c3685e44574aa7d67f80014d69fb
MD5 1c1bb7db47919c6117a43eb91e7264b4
BLAKE2b-256 13a17fca6308caa0ea781d46174b7ececa1c37b32073e036b5f2c6ebc9fa22f4

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page