Hi @jakkok - Thanks for the python code to demonstrate the issue.
The JLS file format is very powerful and flexible, but that also means that there are a few challenges in processing the data. You script does not account for:
- Sample rate: The sample rate for current is 1,000,000, but the sample rate for GPI0 is 2,000,000. The easiest solution is to display the x-axis as time (seconds) rather than samples.
- data packing: The GPI0 digital data is packed into a u8 and needs to be unpacked. For what its worth, this is documented.
- signal alignment: Data is not necessarily sample aligned, even for the same instrument. It is definitely not aligned if you record from multiple instruments. See extract.py for the general case.
Here is the updated code that works:
import numpy as np
from pyjls import Reader, time64
import matplotlib.pyplot as plt
FILE_PATH = r"20250212_162935.jls"
FIXED_VAL = 1000
with Reader(FILE_PATH) as r:
current_signal = r.signal_lookup('current')
print(f'current = {current_signal}')
gpi0_signal = r.signal_lookup('gpi[0]')
print(f'gpi0 = {gpi0_signal}')
signals = [current_signal, gpi0_signal]
t_start = max([r.sample_id_to_timestamp(signal.signal_id, 0) for signal in signals])
t_stop = min([r.sample_id_to_timestamp(signal.signal_id, signal.length - 1) for signal in signals])
t_duration = (t_stop - t_start) / time64.SCALE
print(f'duration = {t_duration}')
x_start = r.timestamp_to_sample_id(current_signal.signal_id, t_start)
x_stop = r.timestamp_to_sample_id(current_signal.signal_id, t_stop)
reading_fsrstats_current = r.fsr_statistics(current_signal.signal_id, x_start, FIXED_VAL,
int((x_stop - x_start) / FIXED_VAL))[:, 0]
reading_fsrstats_current_tvec = np.arange(0, reading_fsrstats_current.size) * (t_duration / reading_fsrstats_current.size)
reading_fsr_current = r.fsr(current_signal.signal_id, x_start, (x_stop - x_start))
reading_fsr_current_tvec = np.arange(0, reading_fsr_current.size) * (t_duration / reading_fsr_current.size)
x_mask = 0xffff_ffff_ffff_fff8
x_start = r.timestamp_to_sample_id(gpi0_signal.signal_id, t_start) & x_mask
x_stop = (r.timestamp_to_sample_id(gpi0_signal.signal_id, t_stop) + 7) & x_mask
reading_fsrstats_gpi0 = r.fsr_statistics(gpi0_signal.signal_id, x_start, FIXED_VAL,
int((x_stop - x_start) / FIXED_VAL))[:, 0]
reading_fsrstats_gpi0_tvec = np.arange(0, reading_fsrstats_gpi0.size) * (t_duration / reading_fsrstats_gpi0.size)
reading_fsr_gpi0_u8 = r.fsr(gpi0_signal.signal_id, x_start, (x_stop - x_start))
reading_fsr_gpi0 = np.unpackbits(reading_fsr_gpi0_u8, bitorder='little')
reading_fsr_gpi0_tvec = np.arange(0, reading_fsr_gpi0.size) * (t_duration / reading_fsr_gpi0.size)
# Plot current signal
plt.figure()
plt.subplot(2,1,1)
plt.plot(reading_fsrstats_current_tvec, reading_fsrstats_current)
plt.title('Current measurement (fsr_statistics): mean for every %d samples' % FIXED_VAL)
plt.xlabel('Time (s)')
plt.ylabel('Amplitude [~]')
plt.grid()
plt.subplot(2,1,2)
plt.plot(reading_fsr_current_tvec, reading_fsr_current)
plt.title('Current measurement (fsr)')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude [~]')
plt.grid()
# Plot GPIO[0] signal
plt.figure()
plt.subplot(2,1,1)
plt.plot(reading_fsrstats_gpi0_tvec, reading_fsrstats_gpi0)
plt.title('GPI[0] measurement (fsr_statistics): mean for every %d samples' % FIXED_VAL)
plt.xlabel('Sample')
plt.ylabel('Amplitude [~]')
plt.grid()
plt.subplot(2,1,2)
plt.plot(reading_fsr_gpi0_tvec, reading_fsr_gpi0)
plt.title('GPI[0] measurement (fsr)')
plt.xlabel('Sample')
plt.ylabel('Amplitude [~]')
plt.grid()
plt.show()
Here are the resulting plots:
Does this make sense and answer your questions?