<jupyter_start><jupyter_text>DS2000 Rigol Waveform Examples**<NAME>****March 2021**This notebook demonstrates extracting signals from `.wfm` files created by Rigol DS2000 oscilloscopes.  It also validates that the process works by comparing with `.csv` and screenshots.*If RigolWFM is not installed, uncomment the following cell (i.e., delete the ) and run (shift-enter)*<jupyter_code>#!pip install --user RigolWFM
import numpy as np
import matplotlib.pyplot as plt

try:
    import RigolWFM.wfm as rigol
except ModuleNotFoundError:
    print('RigolWFM not installed. To install, uncomment and run the cell above.')
    print('Once installation is successful, rerun this cell again.')

repo = "https://github.com/scottprahl/RigolWFM/raw/master/wfm/"

def read_rigol_csv(name):
    csv_data = np.genfromtxt(name, delimiter=',', skip_header=2).T
    lines = len(csv_data[0])
    offset, scale = np.genfromtxt(name, delimiter=',', skip_header=1, skip_footer=lines, usecols=(3, 4)).T
    csv_data[0] = offset + scale * csv_data[0]
    return csv_data<jupyter_output><empty_output><jupyter_text>A list of Rigol scopes in the DS2000 family is:<jupyter_code>print(rigol.DS2000_scopes)<jupyter_output>['2', '2000', 'DS2000', 'DS2072A', 'DS2102A', 'MSO2102A', 'MSO2102A-S', 'DS2202A', 'MSO2202A', 'MSO2202A-S', 'DS2302A', 'MSO2302A', 'MSO2302A-S']<jupyter_text>DS2000-A Look at a screen shotStart with a `.wfm` file from a Rigol DS2000 scope.  It should look something like this Look at the data in the `.csv` fileFirst let's look at plot of the data from the corresponding `.csv` file. Unfortunately this wfm file did not comewith a `.csv` file generated by the Rigol oscilloscope.  Instead, the `.csv` was generated by RigolWFM andverifies that the `.csv` generation matches that expected.<jupyter_code>filename = "DS2000-A.csv"

csv_data = np.genfromtxt(repo+filename, delimiter=',', skip_header=2).T

plt.subplot(211)
plt.plot(csv_data[0]*1e6,csv_data[1], color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
plt.ylim(-10,10)
plt.grid(True)
plt.xticks([])

plt.subplot(212)
plt.plot(csv_data[0]*1e6,csv_data[2], color='red')
plt.xlabel("Time (µs)")
plt.ylabel("Volts (V)")
plt.grid(True)
plt.ylim(-4,4)

plt.show()<jupyter_output><empty_output><jupyter_text>Now for the `.wfm` dataFirst a textual description.<jupyter_code># raw=true is needed because this is a binary file
wfm_url = repo + "DS2000-A.wfm" + "?raw=true"  
w = rigol.Wfm.from_url(wfm_url, '2000')

description = w.describe()
print(description)
ch = w.channels[0]
plt.subplot(211)
plt.plot(ch.times*1e6, ch.volts, color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
plt.ylim(-10,10)
plt.grid(True)
plt.xticks([])

ch = w.channels[1]
plt.subplot(212)
plt.plot(ch.times*1e6, ch.volts, color='red')
plt.xlabel("Time (µs)")
plt.ylabel("Volts (V)")
plt.ylim(-4,4)
plt.grid(True)

plt.show()<jupyter_output><empty_output><jupyter_text>DS2000-B First the `.csv` dataLet's look at what the accompanying `.csv` data looks like.<jupyter_code>filename = "DS2000-B.csv"

# unfortunately this csv file was generated by RigolWFM and by not the scope itself
csv_data = np.genfromtxt(repo+filename, delimiter=',', skip_header=2).T

plt.subplot(211)
plt.plot(csv_data[0]*1e6,csv_data[1], color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
plt.ylim(-10,10)
plt.grid(True)
plt.xticks([])

plt.subplot(212)
plt.plot(csv_data[0]*1e6,csv_data[2], color='red')
plt.xlabel("Time (µs)")
plt.ylabel("Volts (V)")
plt.grid(True)
plt.ylim(-2,2)

plt.show()<jupyter_output><empty_output><jupyter_text>Now for the `wfm` dataFirst let's have look at the description of the internal file structure. We see that only channel 1 has been enabled.<jupyter_code># raw=true is needed because this is a binary file
wfm_url = repo + "DS2000-B.wfm" + "?raw=true"  

w = rigol.Wfm.from_url(wfm_url, 'DS2000')
description = w.describe()
print(description)
ch = w.channels[0]
plt.subplot(211)
plt.plot(ch.times*1e6, ch.volts, color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
plt.ylim(-10,10)
plt.grid(True)
plt.xticks([])

ch = w.channels[1]
plt.subplot(212)
plt.plot(ch.times*1e6, ch.volts, color='red')
plt.xlabel("Time (µs)")
plt.ylabel("Volts (V)")
plt.ylim(-2,2)
plt.grid(True)

plt.show()<jupyter_output><empty_output><jupyter_text>DS2072A-1 Look at a screen shotStart with a `.wfm` file from a Rigol DS2072 scope.  Evidently the image capture on these scopes is buggy and shows no traces.  However, it does show the time scale and that both channels were active Look at the data in the `.csv` fileFirst let's look at plot of the data from the corresponding `.csv` file.<jupyter_code>filename = "DS2072A-1.csv"

csv_data = read_rigol_csv(repo+filename)

plt.subplot(211)
plt.plot(csv_data[0]*1e3,csv_data[1], color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
plt.grid(True)
plt.xticks([])

plt.subplot(212)
plt.plot(csv_data[0]*1e3,csv_data[2], color='red')
plt.xlabel("Time (ms)")
plt.ylabel("Volts (V)")
plt.grid(True)

plt.show()<jupyter_output><empty_output><jupyter_text>Now for the `.wfm` dataFirst a textual description.<jupyter_code># raw=true is needed because this is a binary file
wfm_url = repo + "DS2072A-1.wfm" + "?raw=true"  
w = rigol.Wfm.from_url(wfm_url, '2000')

description = w.describe()
print(description)
ch = w.channels[0]
plt.subplot(211)
plt.plot(ch.times*1e6, ch.volts, color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
plt.grid(True)
plt.xticks([])

ch = w.channels[1]
plt.subplot(212)
plt.plot(ch.times*1e6, ch.volts, color='red')
plt.xlabel("Time (µs)")
plt.ylabel("Volts (V)")
plt.grid(True)

plt.show()<jupyter_output><empty_output><jupyter_text>DS2072A-3 First the `.csv` dataLet's look at what the accompanying `.csv` data looks like.<jupyter_code>filename = "DS2072A-3.csv"
csv_data = read_rigol_csv(repo+filename)

plt.subplot(211)
plt.plot(csv_data[0]*1e3,csv_data[1], color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
#plt.ylim(-10,10)
plt.grid(True)
plt.xticks([])

plt.subplot(212)
plt.plot(csv_data[0]*1e3,csv_data[2], color='red')
plt.xlabel("Time (ms)")
plt.ylabel("Volts (V)")
plt.grid(True)
#plt.ylim(-2,2)

plt.show()<jupyter_output><empty_output><jupyter_text>Now for the `wfm` dataFirst let's have look at the description of the internal file structure. We see that only channel 1 has been enabled.<jupyter_code># raw=true is needed because this is a binary file
wfm_url = repo + "DS2072A-3.wfm" + "?raw=true"  

w = rigol.Wfm.from_url(wfm_url, 'DS2000')
description = w.describe()
print(description)
ch = w.channels[0]
plt.subplot(211)
plt.plot(ch.times*1e3, ch.volts, color='green')
plt.title(filename + " (CH1 Top, CH2 Bottom)")
plt.ylabel("Volts (V)")
#plt.ylim(-10,10)
plt.grid(True)
plt.xticks([])

ch = w.channels[1]
plt.subplot(212)
plt.plot(ch.times*1e3, ch.volts, color='red')
plt.xlabel("Time (ms)")
plt.ylabel("Volts (V)")
#plt.ylim(-2,2)
plt.grid(True)

plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16343723673125526, 'fraction_numerical': 0.044088739118225216, 'mean_word_length': 5.908826382153249, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '339591', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3134, 'n_tokens_neox': 2838, 'n_words': 654, 'path': 'docs/1-DS2000-Waveforms.ipynb', 'repo_name': 'scottprahl/rigolWFM', 'size': '7127'}