JPK archive

JPK files are zipped archives of data.

  • There is a header file at the top-level
  • Header files are normal text files, nothing special needed to read them
  • There is a segments folder
    • the segments folder contains numbered folders, one per segment
    • each folder in segments contains another header file
    • each folder in segments contains a folder named channels
      • each channels folder contains several data files
      • data files contain data in C short format, at least in my example file
      • there seems to be no header in the .dat files, only pure (integer, i.e. short) data

Reading data from JPK archives

Most of this information on how to read JPKs using python I got from the JPKay module.

1. Open the zipped archive using zipfile


In [1]:
from zipfile import ZipFile
fname = "../examples/force-save-2016.07.05-10.00.50.062.jpk-nt-force"

In [2]:
z = ZipFile(fname)

It you can get the list of files stored in the zip archive, and you can open files using the instance's open function


In [3]:
list_of_files = z.filelist
for f in list_of_files:
    print f.filename


header.properties
segments/
segments/0/
segments/0/segment-header.properties
segments/0/channels/xSignal1.dat
segments/0/channels/ySignal1.dat
segments/0/channels/zSignal1.dat
segments/0/channels/xSignal2.dat
segments/0/channels/ySignal2.dat
segments/0/channels/zSignal2.dat
segments/0/channels/xySum1.dat
segments/0/channels/xySum2.dat
segments/0/channels/height.dat
segments/0/channels/xLaserOutput1.dat
segments/0/channels/yLaserOutput1.dat
segments/0/channels/xLaserOutput2.dat
segments/0/channels/yLaserOutput2.dat
segments/0/channels/precision-1.dat
segments/0/channels/precision-2.dat
segments/0/channels/precision-3.dat
segments/0/channels/precision-4.dat
segments/0/channels/capacitiveSensorXPosition.dat
segments/0/channels/capacitiveSensorYPosition.dat
segments/0/channels/capacitiveSensorHeight.dat
segments/0/channels/xPiezoOutput.dat
segments/0/channels/yPiezoOutput.dat
segments/0/channels/trapDistance.dat
segments/1/
segments/1/segment-header.properties
segments/1/channels/xSignal1.dat
segments/1/channels/ySignal1.dat
segments/1/channels/zSignal1.dat
segments/1/channels/xSignal2.dat
segments/1/channels/ySignal2.dat
segments/1/channels/zSignal2.dat
segments/1/channels/xySum1.dat
segments/1/channels/xySum2.dat
segments/1/channels/height.dat
segments/1/channels/xLaserOutput1.dat
segments/1/channels/yLaserOutput1.dat
segments/1/channels/xLaserOutput2.dat
segments/1/channels/yLaserOutput2.dat
segments/1/channels/precision-1.dat
segments/1/channels/precision-2.dat
segments/1/channels/precision-3.dat
segments/1/channels/precision-4.dat
segments/1/channels/capacitiveSensorXPosition.dat
segments/1/channels/capacitiveSensorYPosition.dat
segments/1/channels/capacitiveSensorHeight.dat
segments/1/channels/xPiezoOutput.dat
segments/1/channels/yPiezoOutput.dat
segments/2/
segments/2/segment-header.properties
segments/2/channels/xSignal1.dat
segments/2/channels/ySignal1.dat
segments/2/channels/zSignal1.dat
segments/2/channels/xSignal2.dat
segments/2/channels/ySignal2.dat
segments/2/channels/zSignal2.dat
segments/2/channels/xySum1.dat
segments/2/channels/xySum2.dat
segments/2/channels/height.dat
segments/2/channels/xLaserOutput1.dat
segments/2/channels/yLaserOutput1.dat
segments/2/channels/xLaserOutput2.dat
segments/2/channels/yLaserOutput2.dat
segments/2/channels/precision-1.dat
segments/2/channels/precision-2.dat
segments/2/channels/precision-3.dat
segments/2/channels/precision-4.dat
segments/2/channels/capacitiveSensorXPosition.dat
segments/2/channels/capacitiveSensorYPosition.dat
segments/2/channels/capacitiveSensorHeight.dat
segments/2/channels/xPiezoOutput.dat
segments/2/channels/yPiezoOutput.dat
segments/2/channels/trapDistance.dat
shared-data/header.properties

In [4]:
print list_of_files[0].filename
f = z.open(list_of_files[0].filename)
lines = f.readlines()
print lines[0]
print lines[1]
print lines[2]


header.properties
#Tue Jul 05 10:00:59 CEST 2016

jpk-data-file=pfm-forcefile

file-format-version=2.0

2. Parse header files to dictionaries

As printed above, the first line of the top-level header.properties file contains date and time, preceded by a '#'.
The following lines contain properties of the form "key=value".

To extract the time, one can use dateutil.parser


In [5]:
from dateutil import parser

In [6]:
t = parser.parse(lines[0][1:])
print t


2016-07-05 10:00:59+02:00

The remainder of the lines should contain properties following the syntax mentioned above. They can easily be parsed to a dictionary.


In [7]:
_properties = {}
for line in lines[1:]:
    key, value = line.split("=")
    value.strip()
    _properties[key] = value

In [8]:
for p in _properties:
    print p," = ",_properties[p]


force-scan-series.header.force-settings.retract-scan-time  =  7.999999999999998

force-scan-series.header.force-settings.pause-before-first.pause-option.type  =  constant-height

force-scan-series.header.force-settings.end.x  =  7.620000124584494E-6

force-scan-series.header.force-settings.start.z  =  2.449293598294708E-22

force-scan-series.header.force-settings.start.x  =  1.1620000124584497E-5

force-scan-series.header.force-settings.start.y  =  -2.499999874362724E-6

force-scan-series.header.force-settings.feedback  =  xSignal1

force-scan-series.header.force-settings.end.y  =  -2.499999874362724E-6

force-scan-series.header.force-settings.force-baseline-adjust-settings.interval  =  1

force-scan-series.header.force-settings.retract-k-length  =  16384

force-scan-series.header.force-settings.control-settings-type  =  segment-control-settings

force-scan-series.header.force-settings.extended-pause-k-length  =  0

force-scan-series.header.force-settings.line-clock.active.extend  =  false

force-scan-series.header.force-settings.z-end-pause-option.type  =  constant-height

force-scan-series.description.source-software  =  3.0.11

force-scan-series.header.force-settings.retracted-pause-k-length  =  2048

force-scan-series.header.force-settings.data-description.comment  =  

force-scan-series.header.force-settings.pause-before-first.height-limit  =  NaN

force-scan-series.description.name  =  

force-scan-series.header.force-settings.force-baseline-adjust-settings.deadtimeBeforeSamples  =  100

force-scan-series.header.force-settings.retracted-pause-time  =  0.9999999999999996

force-scan-series.description.probe  =  

force-scan-series.header.force-settings.ttl-outputs.pins.list  =  

force-scan-series.header.force-settings.pause-before-first.identifier.type  =  standard

force-scan-series.header.force-settings.force-baseline-adjust-settings.liquid  =  true

force-scan-series.header.type  =  nt-force-scan-series-header

force-scan-series.force-segments.count  =  3

force-scan-series.header.force-settings.data-description.source-software  =  

force-scan-series.header.force-settings.force-baseline-adjust-settings.enabled  =  false

file-format-version  =  2.0

force-scan-series.description.user-name  =  jpkuser

force-scan-series.header.force-settings.data-description.name  =  

force-scan-series.description.modification-software  =  

force-scan-series.header.force-settings.extend-k-length  =  16384

force-scan-series.header.force-settings.pause-before-first.identifier.name  =  pause-pfm

force-scan-series.header.force-settings.type  =  absolute-force-settings-3d

force-scan-series.header.force-settings.force-baseline-adjust-settings.beginOfLine  =  true

force-scan-series.header.force-settings.data-description.modification-software  =  

force-scan-series.description.instrument  =  JPK10040

force-scan-series.header.force-settings.closed-loop  =  false

force-scan-series.header.force-settings.end.z  =  0.0

force-scan-series.header.force-settings.start-option.type  =  continue

force-scan-series.header.force-settings.data-description.instrument  =  

force-scan-series.header.force-settings.data-description.user-name  =  

force-scan-series.header.force-settings.extended-pause-time  =  0.0

force-scan-series.header.force-settings.line-clock.active.retract  =  false

force-scan-series.description.comment  =  

type  =  force-scan-series

force-scan-series.header.force-settings.z-start-pause-option.type  =  constant-height

jpk-data-file  =  pfm-forcefile

force-scan-series.header.force-settings.pause-before-first.num-points  =  0

force-scan-series.header.force-settings.extend-scan-time  =  7.999999999999998

force-scan-series.header.force-settings.data-description.probe  =  

force-scan-series.header.force-settings.pause-before-first.type  =  constant-height-pause

file-format-features  =  4004013

force-scan-series.header.force-settings.force-baseline-adjust-settings.averageSamples  =  100

force-scan-series.header.force-settings.pause-before-first.style  =  pause

force-scan-series.header.force-settings.start-with-retract  =  true

force-scan-series.header.force-settings.pause-before-first.duration  =  0.0

2.1 Parsing properties into tree-like dictionary

Properties seem to have a tree like structure, with node labels separated by dots. It appears more appropriate to parse them into a dictionary with sub-dictionaries recursively.


In [9]:
properties = {}
for line in lines[1:]:
    key,value = line.split("=")
    value = value.strip()
    
    split_key = key.split(".")
    d = properties
    if len(split_key) > 1:
        for s in split_key[:-1]:
            if d.keys().count(s):
                d = d[s]
            else:
                d[s] = {}
                d = d[s]
    d[split_key[-1]] = value

In [10]:
for p in properties:
    print p, " = ",properties[p]


type  =  force-scan-series
file-format-version  =  2.0
jpk-data-file  =  pfm-forcefile
force-scan-series  =  {'header': {'force-settings': {'closed-loop': 'false', 'feedback': 'xSignal1', 'start-with-retract': 'true', 'extend-scan-time': '7.999999999999998', 'pause-before-first': {'style': 'pause', 'pause-option': {'type': 'constant-height'}, 'num-points': '0', 'height-limit': 'NaN', 'duration': '0.0', 'identifier': {'type': 'standard', 'name': 'pause-pfm'}, 'type': 'constant-height-pause'}, 'retract-k-length': '16384', 'extend-k-length': '16384', 'data-description': {'comment': '', 'source-software': '', 'user-name': '', 'name': '', 'probe': '', 'instrument': '', 'modification-software': ''}, 'retracted-pause-k-length': '2048', 'extended-pause-k-length': '0', 'start-option': {'type': 'continue'}, 'start': {'y': '-2.499999874362724E-6', 'x': '1.1620000124584497E-5', 'z': '2.449293598294708E-22'}, 'extended-pause-time': '0.0', 'line-clock': {'active': {'retract': 'false', 'extend': 'false'}}, 'z-start-pause-option': {'type': 'constant-height'}, 'type': 'absolute-force-settings-3d', 'z-end-pause-option': {'type': 'constant-height'}, 'force-baseline-adjust-settings': {'deadtimeBeforeSamples': '100', 'liquid': 'true', 'averageSamples': '100', 'interval': '1', 'enabled': 'false', 'beginOfLine': 'true'}, 'end': {'y': '-2.499999874362724E-6', 'x': '7.620000124584494E-6', 'z': '0.0'}, 'ttl-outputs': {'pins': {'list': ''}}, 'retracted-pause-time': '0.9999999999999996', 'retract-scan-time': '7.999999999999998', 'control-settings-type': 'segment-control-settings'}, 'type': 'nt-force-scan-series-header'}, 'description': {'comment': '', 'source-software': '3.0.11', 'user-name': 'jpkuser', 'name': '', 'probe': '', 'instrument': 'JPK10040', 'modification-software': ''}, 'force-segments': {'count': '3'}}
file-format-features  =  4004013

In [11]:
properties['force-scan-series']['header']['force-settings']['force-baseline-adjust-settings']


Out[11]:
{'averageSamples': '100',
 'beginOfLine': 'true',
 'deadtimeBeforeSamples': '100',
 'enabled': 'false',
 'interval': '1',
 'liquid': 'true'}

2.2 In contrast to jpk-force archives, lower level header files appear to have the same beginning with time stamp in first line

No lines need to be skipped.


In [21]:
fname = z.filelist[-25].filename
print fname


segments/2/segment-header.properties

In [22]:
f = z.open(fname)
lines = f.readlines()
print(lines[0])
print(lines[1])


#Tue Jul 05 10:00:59 CEST 2016

force-segment-header.type=xyz-position-segment-header

3. Read data from files

Data files (.dat) contain data apparently exclusively in C short format. To convert it to python-compatible integers, use the struct module.


In [23]:
from struct import unpack

In [24]:
fname = z.filelist[-12].filename
print fname


segments/2/channels/yLaserOutput2.dat

In [25]:
f = z.open(fname)
content = f.read()
print(len(content))


65536

According to the JPKay guys, every 4 items make one data point


In [26]:
content[0], content[1], content[2], content[3]


Out[26]:
('\xfe', '\xc0', '\x17', '@')

In [27]:
data = unpack(">i", content[0:4])
print data


(-20965568,)

3.1 How to figure out the number of items making up one data point, i.e., how to figure out the data format of the .dat files?

In jpk-force archives it was quite simple:

  • open header file
  • parse properties to dict
  • read channel.data.type

In [29]:
_z = ZipFile("force-save-2016.06.15-13.17.08.jpk-force")
fname = _z.filelist[-13].filename
print fname
"""open header file"""
f = _z.open(fname)
lines = f.readlines()
"""parse properties to dict"""
properties = {}
for line in lines[2:]:
    key,value = line.split("=")
    value = value.strip()
    
    split_key = key.split(".")
    d = properties
    if len(split_key) > 1:
        for s in split_key[:-1]:
            if d.keys().count(s):
                d = d[s]
            else:
                d[s] = {}
                d = d[s]
    d[split_key[-1]] = value
"""read one channel's data.type property"""
print properties['channel']['height']['data']['type']


segments/2/segment-header.properties
short

But where is this information in a tweezer archive's header?


In [31]:
fname = z.filelist[-25].filename
print fname
f = z.open(fname)
lines = f.readlines()
properties = {}
for line in lines[2:]:
    key,value = line.split("=")
    value = value.strip()
    
    split_key = key.split(".")
    d = properties
    if len(split_key) > 1:
        for s in split_key[:-1]:
            if d.keys().count(s):
                d = d[s]
            else:
                d[s] = {}
                d = d[s]
    d[split_key[-1]] = value
for key in properties:
    print key, " = ", properties[key]


segments/2/segment-header.properties
channels  =  {'list': 'xSignal1 ySignal1 zSignal1 xSignal2 ySignal2 zSignal2 xySum1 xySum2 height xLaserOutput1 yLaserOutput1 xLaserOutput2 yLaserOutput2 precision-1 precision-2 precision-3 precision-4 capacitiveSensorXPosition capacitiveSensorYPosition capacitiveSensorHeight xPiezoOutput yPiezoOutput distance trapDistance'}
force-segment-header  =  {'time-stamp': '2016-07-05 10\\:00\\:59.063 +0200', 'bead-id': '2016.07.05-06.56.10-00001', 'settings': {'style': 'extend', 'segment-settings': {'style': 'extend', 'end': {'y': '-2.499999874362724E-6', 'x': '7.620000124584494E-6', 'z': '0.0'}, 'feedback': 'xSignal1', 'start': {'y': '-2.499999874362724E-6', 'x': '1.1620000124584497E-5', 'z': '2.449293598294708E-22'}, 'num-points': '16384', 'duration': '7.999999999999998', 'identifier': {'type': 'standard', 'name': 'extend-pfm'}, 'type': 'xyz-extend-height'}, 'type': 'combined', 'feedback-mode': {'name': 'default'}}, 'environment': {'traps': {'trap-two': {'position': {'y': '-2.445009491336136E-6', 'x': '1.4285449264063058E-5'}, 'multiplexed': 'false', 'movable': 'true', 'scanner': 'laser-scanner-2'}, 'list': 'trap-one trap-two', 'trap-one': {'position': {'y': '-2.499999874362724E-6', 'x': '7.620000124584494E-6'}, 'multiplexed': 'false', 'movable': 'true', 'scanner': 'laser-scanner-1'}}, 'series-scan-direction': {'y': '0.0', 'x': '1.0', 'z': '6.123233995736766E-17'}, 'z-scanner-map': {'z-scanners': {'active-z-scanner': {'name': 'piezo'}, 'list': 'piezo'}, 'z-scanner': {'piezo': {'z-scanner-environment': {'z-scanner': {'measured-position': 'capacitiveSensorHeight', 'description': '100um Piezo Z Scanner', 'name': 'piezo', 'error-channel': 'error', 'fancy-name': 'Piezo Z Scanner', 'position-channel': 'height'}, 'internal': 'true', 'z-range': {'range': {'max': '5.0E-5', 'min': '-5.0E-5'}, 'fancyname': '100 \\u00B5m (max range)'}}}}}, 'segment-start-xy-scanner-position-map': {'xy-scanners': {'list': 'sample-scanner laser-scanner-1 laser-scanner-2', 'position-index': '-1', 'active-xy-scanner': {'name': 'laser-scanner-1'}}, 'xy-scanner': {'sample-scanner': {'xy-scanner': {'description': 'The sample scanner (100x100 um)', 'fancy-name': 'Sample scanner', 'scanner': 'sample-scanner', 'name': 'sample-scanner'}, 'start-position': {'y': '-1.7487426657707703E-12', 'x': '-4.508344436466238E-13'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}, 'laser-scanner-2': {'xy-scanner': {'description': 'The second trap', 'fancy-name': 'Trap 2', 'scanner': 'laser-scanner', 'scanner-id': '1', 'name': 'laser-scanner-2'}, 'start-position': {'y': '-2.445009491336136E-6', 'x': '1.4285449264063058E-5'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}, 'laser-scanner-1': {'xy-scanner': {'description': 'The first trap', 'fancy-name': 'Trap 1', 'scanner': 'laser-scanner', 'scanner-id': '0', 'name': 'laser-scanner-1'}, 'start-position': {'y': '-2.499999874362724E-6', 'x': '1.1619999897909252E-5'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}}}, 'series-start-xy-scanner-position-map': {'xy-scanners': {'list': 'sample-scanner laser-scanner-1 laser-scanner-2', 'position-index': '-1', 'active-xy-scanner': {'name': 'laser-scanner-1'}}, 'xy-scanner': {'sample-scanner': {'xy-scanner': {'description': 'The sample scanner (100x100 um)', 'fancy-name': 'Sample scanner', 'scanner': 'sample-scanner', 'name': 'sample-scanner'}, 'start-position': {'y': '-1.7487426657707703E-12', 'x': '-4.508344436466238E-13'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}, 'laser-scanner-2': {'xy-scanner': {'description': 'The second trap', 'fancy-name': 'Trap 2', 'scanner': 'laser-scanner', 'scanner-id': '1', 'name': 'laser-scanner-2'}, 'start-position': {'y': '-2.445009491336136E-6', 'x': '1.4285449264063058E-5'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}, 'laser-scanner-1': {'xy-scanner': {'description': 'The first trap', 'fancy-name': 'Trap 1', 'scanner': 'laser-scanner', 'scanner-id': '0', 'name': 'laser-scanner-1'}, 'start-position': {'y': '-2.499999874362724E-6', 'x': '7.620000124584494E-6'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}}}, 'xy-scanner-position-map': {'defined': 'true', 'xy-scanners': {'list': 'sample-scanner laser-scanner-1 laser-scanner-2', 'position-index': '0', 'active-xy-scanner': {'name': 'laser-scanner-1'}}, 'xy-scanner': {'sample-scanner': {'xy-scanner': {'description': 'The sample scanner (100x100 um)', 'fancy-name': 'Sample scanner', 'scanner': 'sample-scanner', 'name': 'sample-scanner'}, 'start-position': {'y': '-1.7487426657707703E-12', 'x': '-4.508344436466238E-13'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}, 'laser-scanner-2': {'xy-scanner': {'description': 'The second trap', 'fancy-name': 'Trap 2', 'scanner': 'laser-scanner', 'scanner-id': '1', 'name': 'laser-scanner-2'}, 'start-position': {'y': '-2.445009491336136E-6', 'x': '1.4285449264063058E-5'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}, 'laser-scanner-1': {'xy-scanner': {'description': 'The first trap', 'fancy-name': 'Trap 1', 'scanner': 'laser-scanner', 'scanner-id': '0', 'name': 'laser-scanner-1'}, 'start-position': {'y': '-2.499999874362724E-6', 'x': '1.1619999897909252E-5'}, 'xy-scanner-mode': {'name': 'hardwareFeedback'}}}}}, 'num-points': '16384', 'duration': '7.999999999999998', 'force-scan-flags': {'z-start-out-of-range': 'false', 'done-scanning': 'false', 'z-end-out-of-range': 'false', 'tipsaver-limit-exceeded': 'false', 'aborted': 'false', 'setpoint-out-of-range': 'false', 'series-done': 'false', 'data-segment': 'true'}, 'name': {'type': 'standard', 'name': 'extend-pfm'}}
channel  =  {'xySum1': {'data': {'num-points': '16384', 'file': {'name': 'channels/xySum1.dat', 'format': 'raw'}}, 'lcd-info': {'*': '6'}}, 'xySum2': {'data': {'num-points': '16384', 'file': {'name': 'channels/xySum2.dat', 'format': 'raw'}}, 'lcd-info': {'*': '7'}}, 'height': {'data': {'num-points': '16384', 'file': {'name': 'channels/height.dat', 'format': 'raw'}}, 'lcd-info': {'*': '8'}}, 'yLaserOutput2': {'data': {'num-points': '16384', 'file': {'name': 'channels/yLaserOutput2.dat', 'format': 'raw'}}, 'lcd-info': {'*': '12'}}, 'yLaserOutput1': {'data': {'num-points': '16384', 'file': {'name': 'channels/yLaserOutput1.dat', 'format': 'raw'}}, 'lcd-info': {'*': '10'}}, 'xSignal1': {'data': {'num-points': '16384', 'file': {'name': 'channels/xSignal1.dat', 'format': 'raw'}}, 'lcd-info': {'*': '0'}}, 'xSignal2': {'data': {'num-points': '16384', 'file': {'name': 'channels/xSignal2.dat', 'format': 'raw'}}, 'lcd-info': {'*': '3'}}, 'trapDistance': {'data': {'num-points': '16384', 'file': {'name': 'channels/trapDistance.dat', 'format': 'raw'}}, 'lcd-info': {'*': '23'}}, 'capacitiveSensorXPosition': {'data': {'num-points': '16384', 'file': {'name': 'channels/capacitiveSensorXPosition.dat', 'format': 'raw'}}, 'lcd-info': {'*': '17'}}, 'xPiezoOutput': {'data': {'num-points': '16384', 'file': {'name': 'channels/xPiezoOutput.dat', 'format': 'raw'}}, 'lcd-info': {'*': '20'}}, 'ySignal2': {'data': {'num-points': '16384', 'file': {'name': 'channels/ySignal2.dat', 'format': 'raw'}}, 'lcd-info': {'*': '4'}}, 'ySignal1': {'data': {'num-points': '16384', 'file': {'name': 'channels/ySignal1.dat', 'format': 'raw'}}, 'lcd-info': {'*': '1'}}, 'xLaserOutput2': {'data': {'num-points': '16384', 'file': {'name': 'channels/xLaserOutput2.dat', 'format': 'raw'}}, 'lcd-info': {'*': '11'}}, 'xLaserOutput1': {'data': {'num-points': '16384', 'file': {'name': 'channels/xLaserOutput1.dat', 'format': 'raw'}}, 'lcd-info': {'*': '9'}}, 'yPiezoOutput': {'data': {'num-points': '16384', 'file': {'name': 'channels/yPiezoOutput.dat', 'format': 'raw'}}, 'lcd-info': {'*': '21'}}, 'zSignal2': {'data': {'num-points': '16384', 'file': {'name': 'channels/zSignal2.dat', 'format': 'raw'}}, 'lcd-info': {'*': '5'}}, 'zSignal1': {'data': {'num-points': '16384', 'file': {'name': 'channels/zSignal1.dat', 'format': 'raw'}}, 'lcd-info': {'*': '2'}}, 'precision-1': {'data': {'num-points': '16384', 'file': {'name': 'channels/precision-1.dat', 'format': 'raw'}}, 'lcd-info': {'*': '13'}}, 'precision-2': {'data': {'num-points': '16384', 'file': {'name': 'channels/precision-2.dat', 'format': 'raw'}}, 'lcd-info': {'*': '14'}}, 'precision-3': {'data': {'num-points': '16384', 'file': {'name': 'channels/precision-3.dat', 'format': 'raw'}}, 'lcd-info': {'*': '15'}}, 'precision-4': {'data': {'num-points': '16384', 'file': {'name': 'channels/precision-4.dat', 'format': 'raw'}}, 'lcd-info': {'*': '16'}}, 'distance': {'data': {'start': '3.999877929687502E-6', 'step': '-2.4414062500000014E-10', 'num-points': '16384'}, 'lcd-info': {'*': '22'}}, 'capacitiveSensorYPosition': {'data': {'num-points': '16384', 'file': {'name': 'channels/capacitiveSensorYPosition.dat', 'format': 'raw'}}, 'lcd-info': {'*': '18'}}, 'capacitiveSensorHeight': {'data': {'num-points': '16384', 'file': {'name': 'channels/capacitiveSensorHeight.dat', 'format': 'raw'}}, 'lcd-info': {'*': '19'}}}

In [ ]: