diff --git a/README.md b/README.md
index 7123de6..49727aa 100644
--- a/README.md
+++ b/README.md
@@ -8,19 +8,19 @@ This software allows GUI (Graphical User Interface) driven live collection,
plotting and analysis of
digitized data inside a Jupyter notebook. The package was initially developed
to provide an inexpensive laboratory system for teaching based on
-the Raspberry Pi. __However, it now also works on other hardware__.
+the Raspberry Pi. **However, it now works on other hardware**.
Presently the working combinations are:
-__on Raspberry Pis__
+**on Raspberry Pis**
* Adafruit compliant ADS1115 boards
([example](https://www.amazon.com/KNACRO-4-Channel-Raspberry-ADS1115-Channel/dp/B07149WH7P),
also available from other vendors);
* The [π-Plates DAQC2 plate](https://pi-plates.com/daqc2r1/).
-__on Macs (and probably Windows)__
+**on Macs and Windows**
* [Vernier](https://www.vernier.com) LabQuest USB A-to-Ds.
-__demo mode on anything Jupyter runs on__
+**demo mode on anything Jupyter runs on**
* A demo mode will run on any computer with a Jupyter notebook install and
Python 3.6+. You can try the demo mode without installing on your own
computer by launching an instance on the MyBinder servers:
@@ -37,14 +37,14 @@ appropriate for the sensor, in addition to the raw voltage signal returned
by the sensor. Not all sensors are compatible with all boards.
The developer(s) attempt to keep this list of known sensors up-to-date, but the
code may provide additional sensors not listed here:
-* __ADS1115 compatible__ (board can provide 3.3 V of power/reference to
+* **ADS1115 compatible** (board can provide 3.3 V of power/reference to
sensors):
* voltage reading (V, mV) from any sensor that puts out a voltage in the
range +/-3.3 V.
* built-in thermistor (V, mV, K, C, F).
* Vernier SS temperature probe (V, mV, K, C, F).
-* __DAQC2 compatible__ (board can provide 5.0 V of power/reference to sensors):
+* **DAQC2 compatible** (board can provide 5.0 V of power/reference to sensors):
* voltage reading (V, mV) from any sensor that puts out a voltage in the
range +/- 12 V.
* Vernier SS temperature probe (V, mV, K, C, F).
@@ -54,7 +54,7 @@ code may provide additional sensors not listed here:
* Compatible with standard Vernier analog probes. Default calibrations
being added as time and sensors become available.
-* __LabQuest compatible__ (board provides 5.0 V of power/reference to sensors):
+* **LabQuest compatible** (board provides 5.0 V of power/reference to sensors):
* voltage reading (V, mV) from any sensor that puts out a voltage in the
range +/- 10 V.
* Vernier SS temperature probe (V, mV, K, C, F).
diff --git a/docs/Change_Log.md b/docs/Change_Log.md
index 4fda3ab..918418d 100644
--- a/docs/Change_Log.md
+++ b/docs/Change_Log.md
@@ -1,4 +1,9 @@
# Change Log
+* 0.8.1 (May 2, 2023)
+ * BUG FIX: Now always waits for all data to be transferred to plot before
+ writing backup to a file.
+ * More rapid update of display when using LabQuests.
+ * Docs now recommend launching `jupyter nbclassic` for old notebook interface.
* 0.8.0 (Apr. 20, 2023)
* Replaced `NewRun()` command with `Run()` command. This version works in
Jupyter Lab and removes the need for the `DisplayRun()` command because
diff --git a/docs/Development_Notes.md b/docs/Development_Notes.md
index 1231859..ca07d3d 100644
--- a/docs/Development_Notes.md
+++ b/docs/Development_Notes.md
@@ -9,7 +9,7 @@ pip and a Jupyter notebook.
See: [python.org](https://python.org) and
[Jupyter.org](https://jupyter.org).
-1. If not installed, install pipenv:`$ pip3 install --user pipenv`. You may
+1. If not installed, install pipenv:`pip3 install --user pipenv`. You may
need to add `~/.local/bin` to your `PATH` to make `pipenv`
available in your command shell. More discussion:
[The Hitchhiker's Guide to Python](https://docs.python-guide.org/dev/virtualenvs/).
@@ -17,21 +17,21 @@ available in your command shell. More discussion:
or has been downloaded to. Use `pipenv`to install an
["editable" package](https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs)
inside the directory as described below:
- 1. Start a shell in the environment `$ pipenv shell`.
+ 1. Start a shell in the environment `pipenv shell`.
1. Install using pip.
1. If you downloaded the git repository named "JupyterPiDAQ"
and have used that directory to build your virtual
- environment: `$ pip install -e ../JupyterPiDAQ/`.
+ environment: `pip install -e ../JupyterPiDAQ/`.
1. If you are downloading from PyPi
- `$ pip install -e JupyterPiDAQ`
+ `pip install -e JupyterPiDAQ`
1. Either should install all the additional packages this
package depends upon. On a Raspberry Pi this will take
a long time. It probably will not run without at least 1 GB of swap. See:
[Build Jupyter on a Pi
](https://www.uwosh.edu/facstaff/gutow/computer-and-programming-how-tos/installing-jupyter-on-raspberrian).
- 1. Still within the environment shell test
- this by starting jupyter `$ jupyter notebook`. Jupyter should launch in
- your browser.
+ 1. Still within the environment shell test this by starting jupyter
+ `jupyter nbclassic` or `jupyter lab`. Jupyter should launch in your
+ browser.
1. Open a new notebook using the default (Python 3) kernel.
1. In the first cell import all from DAQinstance.py:
`from jupyterpidaq.DAQinstance import *`.
@@ -43,10 +43,10 @@ inside the directory as described below:
possible to run this on any computer, not just a Pi.
1. If you wish, you can make this environment available to an alternate Jupyter
install as a special kernel when you are the user.
- 1. Make sure you are running in your virtual environment `$ pipenv shell`
+ 1. Make sure you are running in your virtual environment `pipenv shell`
in the directory for virtual environment will do that.
1. Issue the command to add this as a kernel to your personal space:
- `$ python -m ipykernel install --user --name=API Documentation
-
+
built with pdocStarting JupyterPiDAQ
@@ -490,7 +492,7 @@ jupyter notebook
or jupyter lab
.jupyter nbclassic
(for the old notebook interface) or jupyter
+lab
(for the newer lab interface).
JupyterPiDAQ
. The kernel name will depend upon what was chosen
during installation.Starting JupyterPiDAQ
pipenv shell
.
This assumes you set up pipenv
as described in the
Installation instructions.jupyter notebook
or jupyter lab
.jupyter nbclassic
(for the old
+notebook interface) or jupyter lab
(for the newer lab interface).Setting up Development Environment
Jupyter.org.
$ pip3 install --user pipenv
. You may
+pip3 install --user pipenv
. You may
need to add ~/.local/bin
to your PATH
to make pipenv
available in your command shell. More discussion:
The Hitchhiker's Guide to Python.$ pipenv shell
.pipenv shell
.$ pip install -e ../JupyterPiDAQ/
.pip install -e ../JupyterPiDAQ/
.$ pip install -e JupyterPiDAQ
pip install -e JupyterPiDAQ
$ jupyter notebook
. Jupyter should launch in
-your browser.
+jupyter nbclassic
or jupyter lab
. Jupyter should launch in your
+browser.
$ pipenv shell
+pipenv shell
in the directory for virtual environment will do that.$ python -m ipykernel install --user --name=<name-you-want-for-kernel>
.python -m ipykernel install --user --name=<name-you-want-for-kernel>
.jupyter nbclassic
for old notebook interface.NewRun()
command with Run()
command. This version works in
diff --git a/docs/jupyterpidaq/Boards.html b/docs/jupyterpidaq/Boards.html
index c45c3b3..bb9817b 100644
--- a/docs/jupyterpidaq/Boards.html
+++ b/docs/jupyterpidaq/Boards.html
@@ -3,7 +3,7 @@
-
+
126class DAQinstance(): -127 def __init__(self, idno, title='None', ntraces=4, **kwargs): -128 """ -129 Data Aquistion Instance (a run). -130 -131 :param idno : id number you wish to use to keep track -132 :param title: optional name -133 :param ntraces: number of traces (default = 4) more than 4 easily -134 overwhelms a pi4. -135 :param kwargs: -136 :ignore_skew: bool (default: True) if True only a single average -137 collection time will be recorded for each time in a multichannel -138 data collection. If False a separate set of time will be -139 recorded for each channel. -140 """ -141 from plotly import graph_objects as go -142 self.ignore_skew = kwargs.pop('ignore_skew',True) -143 self.idno = idno -144 self.livefig = go.FigureWidget(layout_template='simple_white') -145 self.title = str(title) -146 self.svname = title + '.jpidaq.html' -147 self.averaging_time = 0.1 # seconds adjusted based on collection rate -148 self.gain = [1] * ntraces -149 self.data = [] -150 self.timestamp = [] -151 self.stdev = [] -152 self.pandadf = None -153 self.ntraces = ntraces -154 self.separate_plots = True -155 self.traces = [] -156 # index map from returned data to trace, -157 self.tracemap = [] -158 self.tracefrdatachn = [] -159 self.tracelbls = [] -160 self.units = [] -161 for i in range(self.ntraces): -162 self.traces.append(ChannelSettings(i, availboards)) -163 self.ratemax = 20.0 # Hz -164 self.rate = 1.0 # Hz -165 self.deltamin = 1 / self.ratemax -166 self.delta = 1.0 / self.rate -167 self.setupbtn = widgets.Button( -168 description='Set Parameters', -169 disabled=False, -170 button_style='info', -171 # 'success', 'info', 'warning', 'danger' or '' -172 tooltip='Click to set collection parameters to displayed values.', -173 icon='') -174 self.collectbtn = widgets.Button( -175 description='Start Collecting', -176 disabled=False, -177 button_style='success', -178 # 'success', 'info', 'warning', 'danger' or '' -179 tooltip='Start collecting data and plotting it. ' -180 'Will make new graph.', -181 icon='') -182 self.separate_traces_checkbox = widgets.Checkbox( -183 value = self.separate_plots, -184 description = 'Display multiple traces as stacked graphs. ' \ -185 'Uncheck to display all on the same graph.', -186 layout = widgets.Layout(width='80%'), -187 disabled = False) -188 self.rateinp = widgets.BoundedFloatText( -189 value=self.rate, -190 min=0, -191 max=self.ratemax, -192 step=self.ratemax / 1000.0, -193 description='Rate (Hz):', -194 disabled=False) -195 self.timelbl = widgets.Text( -196 value='Time(s)', -197 placeholder='Type something', -198 description='X-axis label (time):', +@@ -1604,99 +1609,103 @@127class DAQinstance(): +128 def __init__(self, idno, title='None', ntraces=4, **kwargs): +129 """ +130 Data Aquistion Instance (a run). +131 +132 :param idno : id number you wish to use to keep track +133 :param title: optional name +134 :param ntraces: number of traces (default = 4) more than 4 easily +135 overwhelms a pi4. +136 :param kwargs: +137 :ignore_skew: bool (default: True) if True only a single average +138 collection time will be recorded for each time in a multichannel +139 data collection. If False a separate set of time will be +140 recorded for each channel. +141 """ +142 from plotly import graph_objects as go +143 self.ignore_skew = kwargs.pop('ignore_skew',True) +144 self.idno = idno +145 self.livefig = go.FigureWidget(layout_template='simple_white') +146 self.PLTconn, self.DAQconn = Pipe() +147 self.DAQCTL, self.PLTCTL = Pipe() +148 self.pltthread = threading.Thread(target=self.updatingplot, args=( +149 self.PLTconn, self.PLTCTL)) +150 self.title = str(title) +151 self.svname = title + '.jpidaq.html' +152 self.averaging_time = 0.1 # seconds adjusted based on collection rate +153 self.gain = [1] * ntraces +154 self.data = [] +155 self.timestamp = [] +156 self.stdev = [] +157 self.pandadf = None +158 self.ntraces = ntraces +159 self.separate_plots = True +160 self.traces = [] +161 # index map from returned data to trace, +162 self.tracemap = [] +163 self.tracefrdatachn = [] +164 self.tracelbls = [] +165 self.units = [] +166 for i in range(self.ntraces): +167 self.traces.append(ChannelSettings(i, availboards)) +168 self.ratemax = 20.0 # Hz +169 self.rate = 1.0 # Hz +170 self.deltamin = 1 / self.ratemax +171 self.delta = 1.0 / self.rate +172 self.setupbtn = widgets.Button( +173 description='Set Parameters', +174 disabled=False, +175 button_style='info', +176 # 'success', 'info', 'warning', 'danger' or '' +177 tooltip='Click to set collection parameters to displayed values.', +178 icon='') +179 self.collectbtn = widgets.Button( +180 description='Start Collecting', +181 disabled=False, +182 button_style='success', +183 # 'success', 'info', 'warning', 'danger' or '' +184 tooltip='Start collecting data and plotting it. ' +185 'Will make new graph.', +186 icon='') +187 self.separate_traces_checkbox = widgets.Checkbox( +188 value = self.separate_plots, +189 description = 'Display multiple traces as stacked graphs. ' \ +190 'Uncheck to display all on the same graph.', +191 layout = widgets.Layout(width='80%'), +192 disabled = False) +193 self.rateinp = widgets.BoundedFloatText( +194 value=self.rate, +195 min=0, +196 max=self.ratemax, +197 step=self.ratemax / 1000.0, +198 description='Rate (Hz):', 199 disabled=False) -200 self.runtitle = widgets.Text( -201 value=self.title, -202 placeholder='Type title/description', -203 description='Run title', +200 self.timelbl = widgets.Text( +201 value='Time(s)', +202 placeholder='Type something', +203 description='X-axis label (time):', 204 disabled=False) -205 self.defaultparamtxt = '' -206 self.defaultcollecttxt = '<span style="color:blue;"> To accurately ' -207 self.defaultcollecttxt += 'read point location on graph you can zoom ' -208 self.defaultcollecttxt += 'in. Drag to zoom. Additional controls show ' -209 self.defaultcollecttxt += 'above plot when you hover over it.</span>' -210 self.collecttxt = widgets.HTML( -211 value=self.defaultcollecttxt, -212 placeholder='', -213 description='') -214 self.setup_layout_bottom = widgets.HBox( -215 [self.rateinp, self.timelbl, self.setupbtn]) -216 self.setup_layout = widgets.VBox([self.separate_traces_checkbox, -217 self.setup_layout_bottom]) -218 self.collect_layout = widgets.HBox([self.collectbtn, self.collecttxt]) -219 self.output = widgets.Output() -220 def _make_defaultparamtxt(self): -221 """ -222 Uses AdvancedHTMLParser (mimics javascript) to generate valid HTML for -223 the default parameter text. -224 :return: valid html string for the default parameter text. -225 """ -226 from AdvancedHTMLParser import AdvancedTag as domel -227 run_info=domel('div') -228 run_info.setAttribute('id','DAQRun_' + str(self.idno) + '_info') -229 run_info.setAttribute('class','run_info') -230 run_id = domel('table') -231 run_id.setAttribute('id','run_id') -232 run_id.setAttribute('border', '1') -233 tr = domel('tr') -234 tr.appendInnerHTML('<th>Title</th><th>Id #</th>') -235 run_id.appendChild(tr) -236 tr = domel('tr') -237 tr.appendInnerHTML('<td>' + str(self.title) + '</td>' \ -238 '<td>' + str(self.idno) + '</td>') -239 run_id.appendChild(tr) -240 run_info.appendChild(run_id) -241 # table of run parameters -242 run_param = domel('table') -243 run_param.setAttribute('border','1') -244 run_param.setAttribute('id','run_param') -245 tr = domel('tr') -246 tr.setAttribute('style','text-align:center;') -247 tr.appendInnerHTML('<th>Approx. Rate (Hz)</th>' \ -248 '<th>Approx. Delta (s)</th>' \ -249 '<th>X-label </th>' \ -250 '<th>X-cols</th>' \ -251 '<th>Y-cols</th>' \ -252 '<th>err-cols<sup ' \ -253 'style="color:blue;">a</sup></th>' \ -254 '<th>One Plot</th>' ) -255 run_param.appendChild(tr) -256 run_info.appendChild(run_param) -257 tr = domel('tr') -258 tr.setAttribute('style','text-align:center;') -259 tr.appendInnerHTML('<td>' + str(self.rate) + '</td>' \ -260 '<td>' + str(self.delta) + '</td>' \ -261 '<td>' + self.timelbl.value + '</td>') -262 xlist = '[' -263 ylist = '[' -264 errlist = '[' -265 if self.ignore_skew: -266 xlist += '0]' -267 tempcount = 0 -268 for k in self.traces: -269 if k.isactive: -270 ylist += str(2 * tempcount + 1) + ',' -271 errlist += str(2 * tempcount + 2) + ',' -272 tempcount += 1 -273 ylist = ylist[:-1] + ']' -274 errlist = errlist[:-1] + ']' -275 else: -276 tempcount = 0 -277 for k in self.traces: -278 if k.isactive: -279 xlist += str(3 * tempcount) + ',' -280 ylist += str(3 * tempcount + 1) + ',' -281 errlist += str(3 * tempcount + 2) + ',' -282 tempcount += 1 -283 xlist = xlist[:-1] + ']' -284 ylist = ylist[:-1] + ']' -285 errlist = errlist[:-1] + ']' -286 tr.appendInnerHTML('<td>' + xlist + '</td><td>' + ylist + '</td>') -287 td = domel('td') -288 td.appendText(errlist) -289 tr.appendChild(td) -290 td = domel('td') -291 td.appendText(str(not (self.separate_plots))) -292 tr.appendChild(td) -293 run_param.appendChild(tr) -294 footer = domel('tfoot') -295 tr = domel('tr') -296 td = domel('td') -297 td.setAttribute('colspan','7') -298 td.appendInnerHTML('<sup style="color:blue;">a</sup>The ' \ -299 'standard deviation of the number in the ' \ -300 'column immediately to the left based on the ' \ -301 'variation in signal during the averaging time ' \ -302 'for the data point.') -303 tr.appendChild(td) -304 footer.appendChild(tr) -305 run_param.appendChild(footer) -306 # table of trace information -307 traceinfo = domel('table') -308 traceinfo.setAttribute('class','traceinfo') -309 traceinfo.setAttribute('id','traceinfo') -310 traceinfo.setAttribute('border','1') -311 tr = domel('tr') -312 tr.setAttribute('style','text-align:center;') -313 tr.appendInnerHTML('<th>Trace #</th><th>Title</th><th>Units</th>' \ -314 '<th>Board</th><th>Channel</th><th>Sensor</th>' \ -315 '<th>Gain</th>') -316 traceinfo.appendChild(tr) -317 for i in range(self.ntraces): -318 if (self.traces[i].isactive): -319 self.tracemap.append(i) -320 tr = domel('tr') -321 tr.setAttribute('style', 'text-align:center;') -322 tr.appendInnerHTML('<td>' + str(i) + '</td>' \ -323 '<td>' + self.traces[i].tracelbl.value + '</td>' \ -324 '<td>' + self.traces[i].units.value + '</td>' \ -325 '<td>' + str(self.traces[i].boardchoice.value) + \ -326 ' ' + self.traces[i].board.name + '</td>' \ -327 '<td>' + str(self.traces[i].channel) + '</td>' \ -328 '<td >' + self.traces[i].sensorchoice.value + '</td>' \ -329 '<td>' + str(self.traces[i].gains.value) + '</td>') -330 traceinfo.appendChild(tr) -331 run_info.appendChild(traceinfo) -332 return run_info.asHTML() -333 -334 def _load_from_html(self, file): -335 """ -336 Loads data and parameters for a completed run from a saved html file. -337 :param file: filename or path. -338 :return: -339 """ -340 import pandas as pd -341 from JPSLUtils import find_pandas_dataframe_names -342 from AdvancedHTMLParser import AdvancedHTMLParser as parser -343 from plotly import graph_objects as go -344 whichrun = pd.read_html(file, attrs={'id': 'run_id'})[0] -345 run_title = whichrun['Title'][0] -346 run_id = whichrun['Id #'][0] -347 svname = pd.read_html(file, attrs={'id': 'file_info'})[0]['Saved ' \ -348 'as'][0] -349 self.pandadf = pd.read_html(file, attrs={'class': 'dataframe'}, -350 index_col=0)[0] -351 self.title = run_title -352 self.svname = svname -353 run_param = \ -354 pd.read_html(file, attrs={'id': 'run_param'}, skiprows=[2])[0] -355 self.rate = run_param['Approx. Rate (Hz)'][0] -356 self.delta = run_param['Approx. Delta (s)'][0] -357 # reassiging timelbl to a value from a widget -358 self.timelbl = run_param['X-label'][0] -359 self.separate_plots = not (run_param['One Plot'][0]) -360 xcols = list(map(int,run_param['X-cols'][0].replace('[', -361 '').replace(']','').split(','))) -362 ycols = list(map(int,run_param['Y-cols'][0].replace('[', -363 '').replace(']','').split(','))) -364 errcols = list(map(int,run_param['err-colsa'][0].replace('[', -365 '').replace(']', '').split(','))) -366 htmldatafile = parser(file) -367 self.defaultparamtxt = htmldatafile.getElementsByClassName( -368 'run_info')[0].asHTML() -369 traceinfo = pd.read_html(file, attrs={'id': 'traceinfo'})[0] -370 for k in traceinfo.index: -371 # Do not refill the widgets. This truncates and changes the -372 # definitions of some things from widgets to values. -373 self.traces[k].isactive = True -374 self.traces[k].tracelbl= traceinfo['Title'][k] -375 self.traces[k].units = traceinfo['Units'][k] -376 boardchoice, boardname = (traceinfo['Board'][k]).split(' ',1) -377 self.traces[k].boardchoice = boardchoice -378 self.traces[k].board = boardname -379 self.traces[k].channel = traceinfo['Channel'][k] -380 self.traces[k].gains= traceinfo['Gain'][k] -381 self.traces[k].sensor = traceinfo['Sensor'][k] -382 # Plot -383 if self.separate_plots: -384 self.livefig.set_subplots(rows=len(ycols), cols=1, -385 shared_xaxes=True) -386 self.livefig.update_xaxes( -387 title=self.timelbl, row=len(ycols), col=1) -388 else: -389 self.livefig.update_xaxes(title=self.timelbl) -390 self.livefig.update_yaxes(title="Values") -391 for i in range(len(ycols)): -392 namestr = self.pandadf.columns[ycols[i]] -393 xcol = None -394 if len(xcols) == 1: -395 xcol = xcols[0] -396 else: -397 xcol = xcols[i] -398 scat = go.Scatter( -399 y=self.pandadf.iloc[0:, ycols[i]], -400 x=self.pandadf.iloc[0:,xcol], name=namestr) -401 if self.separate_plots: -402 self.livefig.update_yaxes(title=self.traces[i].units, -403 row=i+1, col=1) -404 self.livefig.add_trace(scat, row=i+1, col=1) -405 else: -406 self.livefig.add_trace(scat) -407 pass -408 -409 def setupclick(self, btn): -410 # Could just use the values in widgets, but this forces intentional -411 # selection and locks them for the run. -412 from copy import copy -413 self.title = copy(self.runtitle.value) -414 self.rate = copy(self.rateinp.value) -415 self.delta = 1 / self.rate -416 self.separate_plots = copy(self.separate_traces_checkbox.value) -417 self.defaultparamtxt = self._make_defaultparamtxt() -418 self.runtitle.close() -419 del self.runtitle -420 self.setup_layout.close() -421 del self.setup_layout -422 self.output.clear_output() -423 doRun(runs[self.idno-1]) -424 with self.output: -425 display(runs[self.idno - 1].livefig) -426 pass -427 -428 def setup(self): +205 self.runtitle = widgets.Text( +206 value=self.title, +207 placeholder='Type title/description', +208 description='Run title', +209 disabled=False) +210 self.defaultparamtxt = '' +211 self.defaultcollecttxt = '<span style="color:blue;"> To accurately ' +212 self.defaultcollecttxt += 'read point location on graph you can zoom ' +213 self.defaultcollecttxt += 'in. Drag to zoom. Additional controls show ' +214 self.defaultcollecttxt += 'above plot when you hover over it.</span>' +215 self.collecttxt = widgets.HTML( +216 value=self.defaultcollecttxt, +217 placeholder='', +218 description='') +219 self.setup_layout_bottom = widgets.HBox( +220 [self.rateinp, self.timelbl, self.setupbtn]) +221 self.setup_layout = widgets.VBox([self.separate_traces_checkbox, +222 self.setup_layout_bottom]) +223 self.collect_layout = widgets.HBox([self.collectbtn, self.collecttxt]) +224 self.output = widgets.Output() +225 def _make_defaultparamtxt(self): +226 """ +227 Uses AdvancedHTMLParser (mimics javascript) to generate valid HTML for +228 the default parameter text. +229 :return: valid html string for the default parameter text. +230 """ +231 from AdvancedHTMLParser import AdvancedTag as domel +232 run_info=domel('div') +233 run_info.setAttribute('id','DAQRun_' + str(self.idno) + '_info') +234 run_info.setAttribute('class','run_info') +235 run_id = domel('table') +236 run_id.setAttribute('id','run_id') +237 run_id.setAttribute('border', '1') +238 tr = domel('tr') +239 tr.appendInnerHTML('<th>Title</th><th>Id #</th>') +240 run_id.appendChild(tr) +241 tr = domel('tr') +242 tr.appendInnerHTML('<td>' + str(self.title) + '</td>' \ +243 '<td>' + str(self.idno) + '</td>') +244 run_id.appendChild(tr) +245 run_info.appendChild(run_id) +246 # table of run parameters +247 run_param = domel('table') +248 run_param.setAttribute('border','1') +249 run_param.setAttribute('id','run_param') +250 tr = domel('tr') +251 tr.setAttribute('style','text-align:center;') +252 tr.appendInnerHTML('<th>Approx. Rate (Hz)</th>' \ +253 '<th>Approx. Delta (s)</th>' \ +254 '<th>X-label </th>' \ +255 '<th>X-cols</th>' \ +256 '<th>Y-cols</th>' \ +257 '<th>err-cols<sup ' \ +258 'style="color:blue;">a</sup></th>' \ +259 '<th>One Plot</th>' ) +260 run_param.appendChild(tr) +261 run_info.appendChild(run_param) +262 tr = domel('tr') +263 tr.setAttribute('style','text-align:center;') +264 tr.appendInnerHTML('<td>' + str(self.rate) + '</td>' \ +265 '<td>' + str(self.delta) + '</td>' \ +266 '<td>' + self.timelbl.value + '</td>') +267 xlist = '[' +268 ylist = '[' +269 errlist = '[' +270 if self.ignore_skew: +271 xlist += '0]' +272 tempcount = 0 +273 for k in self.traces: +274 if k.isactive: +275 ylist += str(2 * tempcount + 1) + ',' +276 errlist += str(2 * tempcount + 2) + ',' +277 tempcount += 1 +278 ylist = ylist[:-1] + ']' +279 errlist = errlist[:-1] + ']' +280 else: +281 tempcount = 0 +282 for k in self.traces: +283 if k.isactive: +284 xlist += str(3 * tempcount) + ',' +285 ylist += str(3 * tempcount + 1) + ',' +286 errlist += str(3 * tempcount + 2) + ',' +287 tempcount += 1 +288 xlist = xlist[:-1] + ']' +289 ylist = ylist[:-1] + ']' +290 errlist = errlist[:-1] + ']' +291 tr.appendInnerHTML('<td>' + xlist + '</td><td>' + ylist + '</td>') +292 td = domel('td') +293 td.appendText(errlist) +294 tr.appendChild(td) +295 td = domel('td') +296 td.appendText(str(not (self.separate_plots))) +297 tr.appendChild(td) +298 run_param.appendChild(tr) +299 footer = domel('tfoot') +300 tr = domel('tr') +301 td = domel('td') +302 td.setAttribute('colspan','7') +303 td.appendInnerHTML('<sup style="color:blue;">a</sup>The ' \ +304 'standard deviation of the number in the ' \ +305 'column immediately to the left based on the ' \ +306 'variation in signal during the averaging time ' \ +307 'for the data point.') +308 tr.appendChild(td) +309 footer.appendChild(tr) +310 run_param.appendChild(footer) +311 # table of trace information +312 traceinfo = domel('table') +313 traceinfo.setAttribute('class','traceinfo') +314 traceinfo.setAttribute('id','traceinfo') +315 traceinfo.setAttribute('border','1') +316 tr = domel('tr') +317 tr.setAttribute('style','text-align:center;') +318 tr.appendInnerHTML('<th>Trace #</th><th>Title</th><th>Units</th>' \ +319 '<th>Board</th><th>Channel</th><th>Sensor</th>' \ +320 '<th>Gain</th>') +321 traceinfo.appendChild(tr) +322 for i in range(self.ntraces): +323 if (self.traces[i].isactive): +324 self.tracemap.append(i) +325 tr = domel('tr') +326 tr.setAttribute('style', 'text-align:center;') +327 tr.appendInnerHTML('<td>' + str(i) + '</td>' \ +328 '<td>' + self.traces[i].tracelbl.value + '</td>' \ +329 '<td>' + self.traces[i].units.value + '</td>' \ +330 '<td>' + str(self.traces[i].boardchoice.value) + \ +331 ' ' + self.traces[i].board.name + '</td>' \ +332 '<td>' + str(self.traces[i].channel) + '</td>' \ +333 '<td >' + self.traces[i].sensorchoice.value + '</td>' \ +334 '<td>' + str(self.traces[i].gains.value) + '</td>') +335 traceinfo.appendChild(tr) +336 run_info.appendChild(traceinfo) +337 return run_info.asHTML() +338 +339 def _load_from_html(self, file): +340 """ +341 Loads data and parameters for a completed run from a saved html file. +342 :param file: filename or path. +343 :return: +344 """ +345 import pandas as pd +346 from JPSLUtils import find_pandas_dataframe_names +347 from AdvancedHTMLParser import AdvancedHTMLParser as parser +348 from plotly import graph_objects as go +349 whichrun = pd.read_html(file, attrs={'id': 'run_id'})[0] +350 run_title = whichrun['Title'][0] +351 run_id = whichrun['Id #'][0] +352 svname = pd.read_html(file, attrs={'id': 'file_info'})[0]['Saved ' \ +353 'as'][0] +354 self.pandadf = pd.read_html(file, attrs={'class': 'dataframe'}, +355 index_col=0)[0] +356 self.title = run_title +357 self.svname = svname +358 run_param = \ +359 pd.read_html(file, attrs={'id': 'run_param'}, skiprows=[2])[0] +360 self.rate = run_param['Approx. Rate (Hz)'][0] +361 self.delta = run_param['Approx. Delta (s)'][0] +362 # reassiging timelbl to a value from a widget +363 self.timelbl = run_param['X-label'][0] +364 self.separate_plots = not (run_param['One Plot'][0]) +365 xcols = list(map(int,run_param['X-cols'][0].replace('[', +366 '').replace(']','').split(','))) +367 ycols = list(map(int,run_param['Y-cols'][0].replace('[', +368 '').replace(']','').split(','))) +369 errcols = list(map(int,run_param['err-colsa'][0].replace('[', +370 '').replace(']', '').split(','))) +371 htmldatafile = parser(file) +372 self.defaultparamtxt = htmldatafile.getElementsByClassName( +373 'run_info')[0].asHTML() +374 traceinfo = pd.read_html(file, attrs={'id': 'traceinfo'})[0] +375 for k in traceinfo.index: +376 # Do not refill the widgets. This truncates and changes the +377 # definitions of some things from widgets to values. +378 self.traces[k].isactive = True +379 self.traces[k].tracelbl= traceinfo['Title'][k] +380 self.traces[k].units = traceinfo['Units'][k] +381 boardchoice, boardname = (traceinfo['Board'][k]).split(' ',1) +382 self.traces[k].boardchoice = boardchoice +383 self.traces[k].board = boardname +384 self.traces[k].channel = traceinfo['Channel'][k] +385 self.traces[k].gains= traceinfo['Gain'][k] +386 self.traces[k].sensor = traceinfo['Sensor'][k] +387 # Plot +388 if self.separate_plots: +389 self.livefig.set_subplots(rows=len(ycols), cols=1, +390 shared_xaxes=True) +391 self.livefig.update_xaxes( +392 title=self.timelbl, row=len(ycols), col=1) +393 else: +394 self.livefig.update_xaxes(title=self.timelbl) +395 self.livefig.update_yaxes(title="Values") +396 for i in range(len(ycols)): +397 namestr = self.pandadf.columns[ycols[i]] +398 xcol = None +399 if len(xcols) == 1: +400 xcol = xcols[0] +401 else: +402 xcol = xcols[i] +403 scat = go.Scatter( +404 y=self.pandadf.iloc[0:, ycols[i]], +405 x=self.pandadf.iloc[0:,xcol], name=namestr) +406 if self.separate_plots: +407 self.livefig.update_yaxes(title=self.traces[i].units, +408 row=i+1, col=1) +409 self.livefig.add_trace(scat, row=i+1, col=1) +410 else: +411 self.livefig.add_trace(scat) +412 pass +413 +414 def setupclick(self, btn): +415 # Could just use the values in widgets, but this forces intentional +416 # selection and locks them for the run. +417 from copy import copy +418 self.title = copy(self.runtitle.value) +419 self.rate = copy(self.rateinp.value) +420 self.delta = 1 / self.rate +421 self.separate_plots = copy(self.separate_traces_checkbox.value) +422 self.defaultparamtxt = self._make_defaultparamtxt() +423 self.runtitle.close() +424 del self.runtitle +425 self.setup_layout.close() +426 del self.setup_layout +427 self.output.clear_output() +428 doRun(runs[self.idno-1]) 429 with self.output: -430 display(HTML("<h3 id ='RunSetUp' " -431 "style='text-align:center;'>Set Run Parameters</h3>")) -432 self.setupbtn.on_click(self.setupclick) -433 display(self.runtitle) -434 for i in range(self.ntraces): -435 self.traces[i].setup() -436 display(self.setup_layout) -437 display(self.output) -438 pass -439 -440 def collectclick(self, btn): -441 if (btn.description == 'Start Collecting'): -442 btn.description = 'Stop Collecting' -443 btn.button_style = 'danger' -444 btn.tooltip = 'Stop the data collection' -445 # do not allow parameters to be reset after starting run. -446 self.setupbtn.disabled = True -447 self.setupbtn.tooltip = 'Parameters locked. The run has started.' -448 self.rateinp.disabled = True -449 self.timelbl.disabled = True -450 PLTconn, DAQconn = Pipe() -451 DAQCTL, PLTCTL = Pipe() -452 nactive = 0 -453 for k in self.traces: -454 if k.isactive: -455 nactive += 1 -456 whichchn = [] -457 gains =[] -458 for i in range(self.ntraces): -459 if (self.traces[i].isactive): -460 brd = self.traces[i].board -461 chn = self.traces[i].channel -462 newchn = True -463 if len(whichchn) > 0: -464 for k in range(len(whichchn)): -465 if whichchn[k]['board'] == brd \ -466 and whichchn[k]['chnl'] == chn: -467 self.tracefrdatachn.append(k) -468 newchn = False -469 if newchn: -470 whichchn.append({'board': brd, -471 'chnl': chn}) -472 gains.append(self.traces[i].toselectedgain) -473 self.tracefrdatachn.append(len(whichchn)-1) -474 # Use up to 30% of the time for averaging if channels were spaced -475 # evenly between data collection times (with DACQ2 they appear -476 # more synchronous than that). -477 self.averaging_time = self.delta / nactive / 3 -478 DAQ = Process(target=DAQProc, -479 args=( -480 whichchn, gains, self.averaging_time, self.delta, -481 DAQconn, DAQCTL)) -482 DAQ.start() -483 thread = threading.Thread(target=self.updatingplot, args=( -484 PLTconn, PLTCTL)) -485 thread.start() -486 # self.updatingplot() hangs up user interface -487 else: -488 btn.description = 'Done' -489 btn.button_style = '' -490 btn.tooltip = '' -491 time.sleep(3) # wait a few seconds for end of data collection -492 self.data = data -493 self.timestamp = timestamp -494 self.stdev = stdev -495 self.fillpandadf() -496 # save data to html file so it is human readable and can be loaded -497 # elsewhere. -498 #self.svname = self.title + '_' + time.strftime('%y-%m-%d_%H%M%S', -499 # time.localtime()) + '.html' -500 svhtml = '<!DOCTYPE html>' \ -501 '<html><body>'+ self.defaultparamtxt + \ -502 '<table id="file_info" border="1"><tr><th>Saved as ' \ -503 '</th></tr><tr><td>' + \ -504 self.svname+'</td></tr></table>' \ -505 '<h2>DATA</h2>'+ \ -506 self.pandadf.to_html() + '</body></html>' -507 f = open(self.svname,'w') -508 f.write(svhtml) -509 f.close() -510 self.collectbtn.close() -511 del self.collectbtn -512 with self.output: -513 display(HTML( -514 '<span style="color:blue;font-weight:bold;">DATA SAVED TO:' + -515 self.svname + '</span>')) -516 return -517 -518 def fillpandadf(self): -519 datacolumns = [] -520 temptimes = np.transpose(self.timestamp) -521 tempdata = np.transpose(self.data) -522 tempstdev = np.transpose(self.stdev) -523 chncnt = 0 -524 for i in range(self.ntraces): -525 if (self.traces[i].isactive): -526 chncnt += 1 -527 for i in range(chncnt): -528 if self.ignore_skew and i > 0: -529 pass -530 else: -531 datacolumns.append(temptimes[i]) -532 datacolumns.append(tempdata[i]) -533 datacolumns.append(tempstdev[i]) -534 titles = [] -535 # Column labels. -536 chncnt = 0 -537 for i in range(self.ntraces): -538 if (self.traces[i].isactive): -539 chncnt += 1 -540 if self.ignore_skew: -541 if chncnt == 1: -542 titles.append(self.timelbl.value) -543 pass -544 else: -545 titles.append(self.traces[ -546 i].tracelbl.value + '_' + self.timelbl.value) -547 titles.append( -548 self.traces[i].tracelbl.value + '(' + self.traces[ -549 i].units.value + ')') -550 titles.append( -551 self.traces[i].tracelbl.value + '_' + 'stdev') -552 #print(str(titles)) -553 #print(str(datacolumns)) -554 self.pandadf = pd.DataFrame(np.transpose(datacolumns), columns=titles) -555 -556 def updatingplot(self, PLTconn, PLTCTL): -557 """ -558 Runs until a check of self.collectbtn.description does not return -559 'Stop Collecting'. This would probably be more efficient if set a -560 boolean. -561 Parameters -562 ---------- -563 PLTconn: Pipe -564 connection plotter end -565 DAQconn: Pipe -566 connection DAQ end -567 PLTCTL: Pipe -568 control pipe plotter end -569 DAQCTL: Pipe -570 control pipe DAQ end -571 """ -572 starttime = time.time() -573 global data -574 data = [] -575 global timestamp -576 timestamp = [] -577 global stdev -578 stdev = [] -579 datalegend = [] -580 timelegend = [] -581 stdevlegend = [] -582 whichchn = [] -583 gains = [] -584 toplotx = [] -585 toploty = [] -586 nactive = 0 -587 def convert_pkg(): -588 plttime = 0 -589 if self.ignore_skew: -590 plttime = sum(pkg[0]) / len(pkg[0]) -591 traceidx = 0 -592 tmptime = [] -593 tmpavg = [] -594 tmpstd = [] -595 tmpavg_std = [] -596 for i, k in zip(self.tracemap, self.tracefrdatachn): -597 -598 avg = pkg[1][k] -599 std = pkg[2][k] -600 avg_std = pkg[3][k] -601 avg_vdd = pkg[4][k] -602 avg, std, avg_std = self.traces[i].toselectedunits(avg, -603 std, avg_std, -604 avg_vdd) -605 avg, std, avg_std = sensors. \ -606 to_reasonable_significant_figures_fast(avg, std, avg_std) -607 tmptime.append(pkg[0][k]) -608 tmpavg.append(avg) -609 tmpstd.append(std) -610 tmpavg_std.append(avg_std) -611 if self.ignore_skew: -612 toplotx[traceidx].append(plttime) -613 else: -614 toplotx[traceidx].append(pkg[0][k]) -615 toploty[traceidx].append(avg) -616 traceidx += 1 -617 timestamp.append(tmptime) -618 data.append(tmpavg) -619 stdev.append(tmpavg_std) -620 return -621 -622 for k in self.traces: -623 if k.isactive: -624 nactive += 1 -625 if self.separate_plots: -626 self.livefig.set_subplots(rows = nactive, cols = 1, -627 shared_xaxes= True) -628 self.livefig.update_xaxes(title = self.timelbl.value, -629 row = nactive, col = 1) -630 else: -631 self.livefig.update_yaxes(title = "Values") -632 self.livefig.update_xaxes(title = self.timelbl.value) -633 active_count = 0 -634 for i in range(self.ntraces): -635 if (self.traces[i].isactive): -636 active_count += 1 -637 tempstr = self.traces[i].tracelbl.value + '(' + \ -638 self.traces[i].units.value + ')' -639 timelegend.append('time_' + tempstr) -640 datalegend.append(tempstr) -641 stdevlegend.append('stdev_' + tempstr) -642 if self.separate_plots: -643 scat = go.Scatter(y=[],x=[], name=tempstr) -644 self.livefig.add_trace(scat, row = active_count, -645 col = 1) -646 self.livefig.update_yaxes(title = self.traces[ -647 i].units.value, row = active_count, col = 1) -648 else: -649 self.livefig.add_scatter(y=[],x=[], name=tempstr) -650 toplotx.append([]) -651 toploty.append([]) -652 lastupdatetime = time.time() -653 -654 pts = 0 -655 oldpts = 0 -656 #print('about to enter while loop',end='') -657 while (self.collectbtn.description == 'Stop Collecting'): -658 #print('.',end='') -659 while PLTconn.poll(): -660 pkg = PLTconn.recv() -661 self.lastpkgstr = str(pkg) -662 #print(self.lastpkgstr) -663 # convert voltage to requested units. -664 convert_pkg() -665 currenttime = time.time() -666 mindelay = 1.0 -667 if self.separate_traces_checkbox.value: -668 mindelay = nactive*1.0 -669 else: -670 mindelay = nactive*0.5 -671 if (currenttime - lastupdatetime)>(mindelay+len(toplotx[0])*len( -672 toplotx)/1000): -673 lastupdatetime = currenttime -674 for k in range(len(self.livefig.data)): -675 self.livefig.data[k].x=toplotx[k] -676 self.livefig.data[k].y=toploty[k] -677 #time.sleep(1) -678 PLTCTL.send('send') -679 time.sleep(self.delta) -680 # print ('btn.description='+str(btn.description)) -681 endtime = time.time() -682 PLTCTL.send('stop') -683 time.sleep(0.5) # wait 0.5 second to collect remaining data -684 PLTCTL.send('send') -685 time.sleep(0.5) -686 msg = '' -687 while (msg != 'done'): -688 while PLTconn.poll(): -689 pkg = PLTconn.recv() -690 # print(str(pkg)) -691 # convert voltage to requested units. -692 convert_pkg() -693 PLTCTL.send('send') -694 time.sleep(0.2) -695 if PLTCTL.poll(): -696 msg = PLTCTL.recv() -697 # print (str(msg)) -698 if (msg != 'done'): -699 print('Received unexpected message: ' + str(msg)) -700 for k in range(len(self.livefig.data)): -701 self.livefig.data[k].x = toplotx[k] -702 self.livefig.data[k].y = toploty[k] +430 display(runs[self.idno - 1].livefig) +431 pass +432 +433 def setup(self): +434 with self.output: +435 display(HTML("<h3 id ='RunSetUp' " +436 "style='text-align:center;'>Set Run Parameters</h3>")) +437 self.setupbtn.on_click(self.setupclick) +438 display(self.runtitle) +439 for i in range(self.ntraces): +440 self.traces[i].setup() +441 display(self.setup_layout) +442 display(self.output) +443 pass +444 +445 def collectclick(self, btn): +446 if (btn.description == 'Start Collecting'): +447 btn.description = 'Stop Collecting' +448 btn.button_style = 'danger' +449 btn.tooltip = 'Stop the data collection' +450 # do not allow parameters to be reset after starting run. +451 self.setupbtn.disabled = True +452 self.setupbtn.tooltip = 'Parameters locked. The run has started.' +453 self.rateinp.disabled = True +454 self.timelbl.disabled = True +455 nactive = 0 +456 for k in self.traces: +457 if k.isactive: +458 nactive += 1 +459 whichchn = [] +460 gains =[] +461 for i in range(self.ntraces): +462 if (self.traces[i].isactive): +463 brd = self.traces[i].board +464 chn = self.traces[i].channel +465 newchn = True +466 if len(whichchn) > 0: +467 for k in range(len(whichchn)): +468 if whichchn[k]['board'] == brd \ +469 and whichchn[k]['chnl'] == chn: +470 self.tracefrdatachn.append(k) +471 newchn = False +472 if newchn: +473 whichchn.append({'board': brd, +474 'chnl': chn}) +475 gains.append(self.traces[i].toselectedgain) +476 self.tracefrdatachn.append(len(whichchn)-1) +477 # Use up to 30% of the time for averaging if channels were spaced +478 # evenly between data collection times (with DACQ2 they appear +479 # more synchronous than that). +480 self.averaging_time = self.delta / nactive / 3 +481 DAQ = Process(target=DAQProc, +482 args=( +483 whichchn, gains, self.averaging_time, self.delta, +484 self.DAQconn, self.DAQCTL)) +485 DAQ.start() +486 self.pltthread.start() +487 # self.updatingplot() hangs up user interface +488 else: +489 btn.description = 'Done' +490 btn.button_style = '' +491 btn.tooltip = '' +492 # wait a plotting thread to terminate +493 self.pltthread.join() +494 self.data = data +495 self.timestamp = timestamp +496 self.stdev = stdev +497 self.fillpandadf() +498 # save data to html file so it is human readable and can be loaded +499 # elsewhere. +500 #self.svname = self.title + '_' + time.strftime('%y-%m-%d_%H%M%S', +501 # time.localtime()) + '.html' +502 svhtml = '<!DOCTYPE html>' \ +503 '<html><body>'+ self.defaultparamtxt + \ +504 '<table id="file_info" border="1"><tr><th>Saved as ' \ +505 '</th></tr><tr><td>' + \ +506 self.svname+'</td></tr></table>' \ +507 '<h2>DATA</h2>'+ \ +508 self.pandadf.to_html() + '</body></html>' +509 f = open(self.svname,'w') +510 f.write(svhtml) +511 f.close() +512 self.collectbtn.close() +513 del self.collectbtn +514 with self.output: +515 display(HTML( +516 '<span style="color:blue;font-weight:bold;">DATA SAVED TO:' + +517 self.svname + '</span>')) +518 return +519 +520 def fillpandadf(self): +521 datacolumns = [] +522 temptimes = np.transpose(self.timestamp) +523 tempdata = np.transpose(self.data) +524 tempstdev = np.transpose(self.stdev) +525 chncnt = 0 +526 for i in range(self.ntraces): +527 if (self.traces[i].isactive): +528 chncnt += 1 +529 for i in range(chncnt): +530 if self.ignore_skew and i > 0: +531 pass +532 else: +533 datacolumns.append(temptimes[i]) +534 datacolumns.append(tempdata[i]) +535 datacolumns.append(tempstdev[i]) +536 titles = [] +537 # Column labels. +538 chncnt = 0 +539 for i in range(self.ntraces): +540 if (self.traces[i].isactive): +541 chncnt += 1 +542 if self.ignore_skew: +543 if chncnt == 1: +544 titles.append(self.timelbl.value) +545 pass +546 else: +547 titles.append(self.traces[ +548 i].tracelbl.value + '_' + self.timelbl.value) +549 titles.append( +550 self.traces[i].tracelbl.value + '(' + self.traces[ +551 i].units.value + ')') +552 titles.append( +553 self.traces[i].tracelbl.value + '_' + 'stdev') +554 #print(str(titles)) +555 #print(str(datacolumns)) +556 self.pandadf = pd.DataFrame(np.transpose(datacolumns), columns=titles) +557 +558 def updatingplot(self, PLTconn, PLTCTL): +559 """ +560 Runs until a check of self.collectbtn.description does not return +561 'Stop Collecting'. This would probably be more efficient if set a +562 boolean. +563 Parameters +564 ---------- +565 PLTconn: Pipe +566 connection plotter end +567 DAQconn: Pipe +568 connection DAQ end +569 PLTCTL: Pipe +570 control pipe plotter end +571 DAQCTL: Pipe +572 control pipe DAQ end +573 """ +574 starttime = time.time() +575 global data +576 data = [] +577 global timestamp +578 timestamp = [] +579 global stdev +580 stdev = [] +581 datalegend = [] +582 timelegend = [] +583 stdevlegend = [] +584 whichchn = [] +585 gains = [] +586 toplotx = [] +587 toploty = [] +588 nactive = 0 +589 def convert_pkg(): +590 plttime = 0 +591 if self.ignore_skew: +592 plttime = sum(pkg[0]) / len(pkg[0]) +593 traceidx = 0 +594 tmptime = [] +595 tmpavg = [] +596 tmpstd = [] +597 tmpavg_std = [] +598 for i, k in zip(self.tracemap, self.tracefrdatachn): +599 +600 avg = pkg[1][k] +601 std = pkg[2][k] +602 avg_std = pkg[3][k] +603 avg_vdd = pkg[4][k] +604 avg, std, avg_std = self.traces[i].toselectedunits(avg, +605 std, avg_std, +606 avg_vdd) +607 avg, std, avg_std = sensors. \ +608 to_reasonable_significant_figures_fast(avg, std, avg_std) +609 tmptime.append(pkg[0][k]) +610 tmpavg.append(avg) +611 tmpstd.append(std) +612 tmpavg_std.append(avg_std) +613 if self.ignore_skew: +614 toplotx[traceidx].append(plttime) +615 else: +616 toplotx[traceidx].append(pkg[0][k]) +617 toploty[traceidx].append(avg) +618 traceidx += 1 +619 timestamp.append(tmptime) +620 data.append(tmpavg) +621 stdev.append(tmpavg_std) +622 return +623 +624 for k in self.traces: +625 if k.isactive: +626 nactive += 1 +627 if self.separate_plots: +628 self.livefig.set_subplots(rows = nactive, cols = 1, +629 shared_xaxes= True) +630 self.livefig.update_xaxes(title = self.timelbl.value, +631 row = nactive, col = 1) +632 else: +633 self.livefig.update_yaxes(title = "Values") +634 self.livefig.update_xaxes(title = self.timelbl.value) +635 active_count = 0 +636 for i in range(self.ntraces): +637 if (self.traces[i].isactive): +638 active_count += 1 +639 tempstr = self.traces[i].tracelbl.value + '(' + \ +640 self.traces[i].units.value + ')' +641 timelegend.append('time_' + tempstr) +642 datalegend.append(tempstr) +643 stdevlegend.append('stdev_' + tempstr) +644 if self.separate_plots: +645 scat = go.Scatter(y=[],x=[], name=tempstr) +646 self.livefig.add_trace(scat, row = active_count, +647 col = 1) +648 self.livefig.update_yaxes(title = self.traces[ +649 i].units.value, row = active_count, col = 1) +650 else: +651 self.livefig.add_scatter(y=[],x=[], name=tempstr) +652 toplotx.append([]) +653 toploty.append([]) +654 lastupdatetime = time.time() +655 +656 pts = 0 +657 oldpts = 0 +658 #print('about to enter while loop',end='') +659 while (self.collectbtn.description == 'Stop Collecting'): +660 #print('.',end='') +661 while PLTconn.poll(): +662 pkg = PLTconn.recv() +663 self.lastpkgstr = str(pkg) +664 #print(self.lastpkgstr) +665 # convert voltage to requested units. +666 convert_pkg() +667 currenttime = time.time() +668 mindelay = 1.0 +669 if self.separate_traces_checkbox.value: +670 mindelay = nactive*1.0 +671 else: +672 mindelay = nactive*0.5 +673 if (currenttime - lastupdatetime)>(mindelay+len(toplotx[0])*len( +674 toplotx)/1000): +675 lastupdatetime = currenttime +676 for k in range(len(self.livefig.data)): +677 self.livefig.data[k].x=toplotx[k] +678 self.livefig.data[k].y=toploty[k] +679 #time.sleep(1) +680 PLTCTL.send('send') +681 time.sleep(self.delta) +682 # print ('btn.description='+str(btn.description)) +683 endtime = time.time() +684 PLTCTL.send('stop') +685 time.sleep(0.5) # wait 0.5 second to collect remaining data +686 PLTCTL.send('send') +687 time.sleep(0.5) +688 msg = '' +689 while (msg != 'done'): +690 while PLTconn.poll(): +691 pkg = PLTconn.recv() +692 # print(str(pkg)) +693 # convert voltage to requested units. +694 convert_pkg() +695 PLTCTL.send('send') +696 time.sleep(0.2) +697 if PLTCTL.poll(): +698 msg = PLTCTL.recv() +699 # print (str(msg)) +700 if (msg != 'done'): +701 print('Received unexpected message: ' + str(msg)) +702 for k in range(len(self.livefig.data)): +703 self.livefig.data[k].x = toplotx[k] +704 self.livefig.data[k].y = toploty[k] +705 return
127 def __init__(self, idno, title='None', ntraces=4, **kwargs): -128 """ -129 Data Aquistion Instance (a run). -130 -131 :param idno : id number you wish to use to keep track -132 :param title: optional name -133 :param ntraces: number of traces (default = 4) more than 4 easily -134 overwhelms a pi4. -135 :param kwargs: -136 :ignore_skew: bool (default: True) if True only a single average -137 collection time will be recorded for each time in a multichannel -138 data collection. If False a separate set of time will be -139 recorded for each channel. -140 """ -141 from plotly import graph_objects as go -142 self.ignore_skew = kwargs.pop('ignore_skew',True) -143 self.idno = idno -144 self.livefig = go.FigureWidget(layout_template='simple_white') -145 self.title = str(title) -146 self.svname = title + '.jpidaq.html' -147 self.averaging_time = 0.1 # seconds adjusted based on collection rate -148 self.gain = [1] * ntraces -149 self.data = [] -150 self.timestamp = [] -151 self.stdev = [] -152 self.pandadf = None -153 self.ntraces = ntraces -154 self.separate_plots = True -155 self.traces = [] -156 # index map from returned data to trace, -157 self.tracemap = [] -158 self.tracefrdatachn = [] -159 self.tracelbls = [] -160 self.units = [] -161 for i in range(self.ntraces): -162 self.traces.append(ChannelSettings(i, availboards)) -163 self.ratemax = 20.0 # Hz -164 self.rate = 1.0 # Hz -165 self.deltamin = 1 / self.ratemax -166 self.delta = 1.0 / self.rate -167 self.setupbtn = widgets.Button( -168 description='Set Parameters', -169 disabled=False, -170 button_style='info', -171 # 'success', 'info', 'warning', 'danger' or '' -172 tooltip='Click to set collection parameters to displayed values.', -173 icon='') -174 self.collectbtn = widgets.Button( -175 description='Start Collecting', -176 disabled=False, -177 button_style='success', -178 # 'success', 'info', 'warning', 'danger' or '' -179 tooltip='Start collecting data and plotting it. ' -180 'Will make new graph.', -181 icon='') -182 self.separate_traces_checkbox = widgets.Checkbox( -183 value = self.separate_plots, -184 description = 'Display multiple traces as stacked graphs. ' \ -185 'Uncheck to display all on the same graph.', -186 layout = widgets.Layout(width='80%'), -187 disabled = False) -188 self.rateinp = widgets.BoundedFloatText( -189 value=self.rate, -190 min=0, -191 max=self.ratemax, -192 step=self.ratemax / 1000.0, -193 description='Rate (Hz):', -194 disabled=False) -195 self.timelbl = widgets.Text( -196 value='Time(s)', -197 placeholder='Type something', -198 description='X-axis label (time):', +@@ -1730,24 +1739,24 @@128 def __init__(self, idno, title='None', ntraces=4, **kwargs): +129 """ +130 Data Aquistion Instance (a run). +131 +132 :param idno : id number you wish to use to keep track +133 :param title: optional name +134 :param ntraces: number of traces (default = 4) more than 4 easily +135 overwhelms a pi4. +136 :param kwargs: +137 :ignore_skew: bool (default: True) if True only a single average +138 collection time will be recorded for each time in a multichannel +139 data collection. If False a separate set of time will be +140 recorded for each channel. +141 """ +142 from plotly import graph_objects as go +143 self.ignore_skew = kwargs.pop('ignore_skew',True) +144 self.idno = idno +145 self.livefig = go.FigureWidget(layout_template='simple_white') +146 self.PLTconn, self.DAQconn = Pipe() +147 self.DAQCTL, self.PLTCTL = Pipe() +148 self.pltthread = threading.Thread(target=self.updatingplot, args=( +149 self.PLTconn, self.PLTCTL)) +150 self.title = str(title) +151 self.svname = title + '.jpidaq.html' +152 self.averaging_time = 0.1 # seconds adjusted based on collection rate +153 self.gain = [1] * ntraces +154 self.data = [] +155 self.timestamp = [] +156 self.stdev = [] +157 self.pandadf = None +158 self.ntraces = ntraces +159 self.separate_plots = True +160 self.traces = [] +161 # index map from returned data to trace, +162 self.tracemap = [] +163 self.tracefrdatachn = [] +164 self.tracelbls = [] +165 self.units = [] +166 for i in range(self.ntraces): +167 self.traces.append(ChannelSettings(i, availboards)) +168 self.ratemax = 20.0 # Hz +169 self.rate = 1.0 # Hz +170 self.deltamin = 1 / self.ratemax +171 self.delta = 1.0 / self.rate +172 self.setupbtn = widgets.Button( +173 description='Set Parameters', +174 disabled=False, +175 button_style='info', +176 # 'success', 'info', 'warning', 'danger' or '' +177 tooltip='Click to set collection parameters to displayed values.', +178 icon='') +179 self.collectbtn = widgets.Button( +180 description='Start Collecting', +181 disabled=False, +182 button_style='success', +183 # 'success', 'info', 'warning', 'danger' or '' +184 tooltip='Start collecting data and plotting it. ' +185 'Will make new graph.', +186 icon='') +187 self.separate_traces_checkbox = widgets.Checkbox( +188 value = self.separate_plots, +189 description = 'Display multiple traces as stacked graphs. ' \ +190 'Uncheck to display all on the same graph.', +191 layout = widgets.Layout(width='80%'), +192 disabled = False) +193 self.rateinp = widgets.BoundedFloatText( +194 value=self.rate, +195 min=0, +196 max=self.ratemax, +197 step=self.ratemax / 1000.0, +198 description='Rate (Hz):', 199 disabled=False) -200 self.runtitle = widgets.Text( -201 value=self.title, -202 placeholder='Type title/description', -203 description='Run title', +200 self.timelbl = widgets.Text( +201 value='Time(s)', +202 placeholder='Type something', +203 description='X-axis label (time):', 204 disabled=False) -205 self.defaultparamtxt = '' -206 self.defaultcollecttxt = '<span style="color:blue;"> To accurately ' -207 self.defaultcollecttxt += 'read point location on graph you can zoom ' -208 self.defaultcollecttxt += 'in. Drag to zoom. Additional controls show ' -209 self.defaultcollecttxt += 'above plot when you hover over it.</span>' -210 self.collecttxt = widgets.HTML( -211 value=self.defaultcollecttxt, -212 placeholder='', -213 description='') -214 self.setup_layout_bottom = widgets.HBox( -215 [self.rateinp, self.timelbl, self.setupbtn]) -216 self.setup_layout = widgets.VBox([self.separate_traces_checkbox, -217 self.setup_layout_bottom]) -218 self.collect_layout = widgets.HBox([self.collectbtn, self.collecttxt]) -219 self.output = widgets.Output() +205 self.runtitle = widgets.Text( +206 value=self.title, +207 placeholder='Type title/description', +208 description='Run title', +209 disabled=False) +210 self.defaultparamtxt = '' +211 self.defaultcollecttxt = '<span style="color:blue;"> To accurately ' +212 self.defaultcollecttxt += 'read point location on graph you can zoom ' +213 self.defaultcollecttxt += 'in. Drag to zoom. Additional controls show ' +214 self.defaultcollecttxt += 'above plot when you hover over it.</span>' +215 self.collecttxt = widgets.HTML( +216 value=self.defaultcollecttxt, +217 placeholder='', +218 description='') +219 self.setup_layout_bottom = widgets.HBox( +220 [self.rateinp, self.timelbl, self.setupbtn]) +221 self.setup_layout = widgets.VBox([self.separate_traces_checkbox, +222 self.setup_layout_bottom]) +223 self.collect_layout = widgets.HBox([self.collectbtn, self.collecttxt]) +224 self.output = widgets.Output()Parameters
409 def setupclick(self, btn): -410 # Could just use the values in widgets, but this forces intentional -411 # selection and locks them for the run. -412 from copy import copy -413 self.title = copy(self.runtitle.value) -414 self.rate = copy(self.rateinp.value) -415 self.delta = 1 / self.rate -416 self.separate_plots = copy(self.separate_traces_checkbox.value) -417 self.defaultparamtxt = self._make_defaultparamtxt() -418 self.runtitle.close() -419 del self.runtitle -420 self.setup_layout.close() -421 del self.setup_layout -422 self.output.clear_output() -423 doRun(runs[self.idno-1]) -424 with self.output: -425 display(runs[self.idno - 1].livefig) -426 pass +@@ -1765,17 +1774,17 @@414 def setupclick(self, btn): +415 # Could just use the values in widgets, but this forces intentional +416 # selection and locks them for the run. +417 from copy import copy +418 self.title = copy(self.runtitle.value) +419 self.rate = copy(self.rateinp.value) +420 self.delta = 1 / self.rate +421 self.separate_plots = copy(self.separate_traces_checkbox.value) +422 self.defaultparamtxt = self._make_defaultparamtxt() +423 self.runtitle.close() +424 del self.runtitle +425 self.setup_layout.close() +426 del self.setup_layout +427 self.output.clear_output() +428 doRun(runs[self.idno-1]) +429 with self.output: +430 display(runs[self.idno - 1].livefig) +431 passParameters
428 def setup(self): -429 with self.output: -430 display(HTML("<h3 id ='RunSetUp' " -431 "style='text-align:center;'>Set Run Parameters</h3>")) -432 self.setupbtn.on_click(self.setupclick) -433 display(self.runtitle) -434 for i in range(self.ntraces): -435 self.traces[i].setup() -436 display(self.setup_layout) -437 display(self.output) -438 pass +@@ -1793,83 +1802,80 @@433 def setup(self): +434 with self.output: +435 display(HTML("<h3 id ='RunSetUp' " +436 "style='text-align:center;'>Set Run Parameters</h3>")) +437 self.setupbtn.on_click(self.setupclick) +438 display(self.runtitle) +439 for i in range(self.ntraces): +440 self.traces[i].setup() +441 display(self.setup_layout) +442 display(self.output) +443 passParameters
440 def collectclick(self, btn): -441 if (btn.description == 'Start Collecting'): -442 btn.description = 'Stop Collecting' -443 btn.button_style = 'danger' -444 btn.tooltip = 'Stop the data collection' -445 # do not allow parameters to be reset after starting run. -446 self.setupbtn.disabled = True -447 self.setupbtn.tooltip = 'Parameters locked. The run has started.' -448 self.rateinp.disabled = True -449 self.timelbl.disabled = True -450 PLTconn, DAQconn = Pipe() -451 DAQCTL, PLTCTL = Pipe() -452 nactive = 0 -453 for k in self.traces: -454 if k.isactive: -455 nactive += 1 -456 whichchn = [] -457 gains =[] -458 for i in range(self.ntraces): -459 if (self.traces[i].isactive): -460 brd = self.traces[i].board -461 chn = self.traces[i].channel -462 newchn = True -463 if len(whichchn) > 0: -464 for k in range(len(whichchn)): -465 if whichchn[k]['board'] == brd \ -466 and whichchn[k]['chnl'] == chn: -467 self.tracefrdatachn.append(k) -468 newchn = False -469 if newchn: -470 whichchn.append({'board': brd, -471 'chnl': chn}) -472 gains.append(self.traces[i].toselectedgain) -473 self.tracefrdatachn.append(len(whichchn)-1) -474 # Use up to 30% of the time for averaging if channels were spaced -475 # evenly between data collection times (with DACQ2 they appear -476 # more synchronous than that). -477 self.averaging_time = self.delta / nactive / 3 -478 DAQ = Process(target=DAQProc, -479 args=( -480 whichchn, gains, self.averaging_time, self.delta, -481 DAQconn, DAQCTL)) -482 DAQ.start() -483 thread = threading.Thread(target=self.updatingplot, args=( -484 PLTconn, PLTCTL)) -485 thread.start() -486 # self.updatingplot() hangs up user interface -487 else: -488 btn.description = 'Done' -489 btn.button_style = '' -490 btn.tooltip = '' -491 time.sleep(3) # wait a few seconds for end of data collection -492 self.data = data -493 self.timestamp = timestamp -494 self.stdev = stdev -495 self.fillpandadf() -496 # save data to html file so it is human readable and can be loaded -497 # elsewhere. -498 #self.svname = self.title + '_' + time.strftime('%y-%m-%d_%H%M%S', -499 # time.localtime()) + '.html' -500 svhtml = '<!DOCTYPE html>' \ -501 '<html><body>'+ self.defaultparamtxt + \ -502 '<table id="file_info" border="1"><tr><th>Saved as ' \ -503 '</th></tr><tr><td>' + \ -504 self.svname+'</td></tr></table>' \ -505 '<h2>DATA</h2>'+ \ -506 self.pandadf.to_html() + '</body></html>' -507 f = open(self.svname,'w') -508 f.write(svhtml) -509 f.close() -510 self.collectbtn.close() -511 del self.collectbtn -512 with self.output: -513 display(HTML( -514 '<span style="color:blue;font-weight:bold;">DATA SAVED TO:' + -515 self.svname + '</span>')) -516 return +@@ -1887,43 +1893,43 @@445 def collectclick(self, btn): +446 if (btn.description == 'Start Collecting'): +447 btn.description = 'Stop Collecting' +448 btn.button_style = 'danger' +449 btn.tooltip = 'Stop the data collection' +450 # do not allow parameters to be reset after starting run. +451 self.setupbtn.disabled = True +452 self.setupbtn.tooltip = 'Parameters locked. The run has started.' +453 self.rateinp.disabled = True +454 self.timelbl.disabled = True +455 nactive = 0 +456 for k in self.traces: +457 if k.isactive: +458 nactive += 1 +459 whichchn = [] +460 gains =[] +461 for i in range(self.ntraces): +462 if (self.traces[i].isactive): +463 brd = self.traces[i].board +464 chn = self.traces[i].channel +465 newchn = True +466 if len(whichchn) > 0: +467 for k in range(len(whichchn)): +468 if whichchn[k]['board'] == brd \ +469 and whichchn[k]['chnl'] == chn: +470 self.tracefrdatachn.append(k) +471 newchn = False +472 if newchn: +473 whichchn.append({'board': brd, +474 'chnl': chn}) +475 gains.append(self.traces[i].toselectedgain) +476 self.tracefrdatachn.append(len(whichchn)-1) +477 # Use up to 30% of the time for averaging if channels were spaced +478 # evenly between data collection times (with DACQ2 they appear +479 # more synchronous than that). +480 self.averaging_time = self.delta / nactive / 3 +481 DAQ = Process(target=DAQProc, +482 args=( +483 whichchn, gains, self.averaging_time, self.delta, +484 self.DAQconn, self.DAQCTL)) +485 DAQ.start() +486 self.pltthread.start() +487 # self.updatingplot() hangs up user interface +488 else: +489 btn.description = 'Done' +490 btn.button_style = '' +491 btn.tooltip = '' +492 # wait a plotting thread to terminate +493 self.pltthread.join() +494 self.data = data +495 self.timestamp = timestamp +496 self.stdev = stdev +497 self.fillpandadf() +498 # save data to html file so it is human readable and can be loaded +499 # elsewhere. +500 #self.svname = self.title + '_' + time.strftime('%y-%m-%d_%H%M%S', +501 # time.localtime()) + '.html' +502 svhtml = '<!DOCTYPE html>' \ +503 '<html><body>'+ self.defaultparamtxt + \ +504 '<table id="file_info" border="1"><tr><th>Saved as ' \ +505 '</th></tr><tr><td>' + \ +506 self.svname+'</td></tr></table>' \ +507 '<h2>DATA</h2>'+ \ +508 self.pandadf.to_html() + '</body></html>' +509 f = open(self.svname,'w') +510 f.write(svhtml) +511 f.close() +512 self.collectbtn.close() +513 del self.collectbtn +514 with self.output: +515 display(HTML( +516 '<span style="color:blue;font-weight:bold;">DATA SAVED TO:' + +517 self.svname + '</span>')) +518 returnParameters
518 def fillpandadf(self): -519 datacolumns = [] -520 temptimes = np.transpose(self.timestamp) -521 tempdata = np.transpose(self.data) -522 tempstdev = np.transpose(self.stdev) -523 chncnt = 0 -524 for i in range(self.ntraces): -525 if (self.traces[i].isactive): -526 chncnt += 1 -527 for i in range(chncnt): -528 if self.ignore_skew and i > 0: -529 pass -530 else: -531 datacolumns.append(temptimes[i]) -532 datacolumns.append(tempdata[i]) -533 datacolumns.append(tempstdev[i]) -534 titles = [] -535 # Column labels. -536 chncnt = 0 -537 for i in range(self.ntraces): -538 if (self.traces[i].isactive): -539 chncnt += 1 -540 if self.ignore_skew: -541 if chncnt == 1: -542 titles.append(self.timelbl.value) -543 pass -544 else: -545 titles.append(self.traces[ -546 i].tracelbl.value + '_' + self.timelbl.value) -547 titles.append( -548 self.traces[i].tracelbl.value + '(' + self.traces[ -549 i].units.value + ')') -550 titles.append( -551 self.traces[i].tracelbl.value + '_' + 'stdev') -552 #print(str(titles)) -553 #print(str(datacolumns)) -554 self.pandadf = pd.DataFrame(np.transpose(datacolumns), columns=titles) +@@ -1941,153 +1947,154 @@520 def fillpandadf(self): +521 datacolumns = [] +522 temptimes = np.transpose(self.timestamp) +523 tempdata = np.transpose(self.data) +524 tempstdev = np.transpose(self.stdev) +525 chncnt = 0 +526 for i in range(self.ntraces): +527 if (self.traces[i].isactive): +528 chncnt += 1 +529 for i in range(chncnt): +530 if self.ignore_skew and i > 0: +531 pass +532 else: +533 datacolumns.append(temptimes[i]) +534 datacolumns.append(tempdata[i]) +535 datacolumns.append(tempstdev[i]) +536 titles = [] +537 # Column labels. +538 chncnt = 0 +539 for i in range(self.ntraces): +540 if (self.traces[i].isactive): +541 chncnt += 1 +542 if self.ignore_skew: +543 if chncnt == 1: +544 titles.append(self.timelbl.value) +545 pass +546 else: +547 titles.append(self.traces[ +548 i].tracelbl.value + '_' + self.timelbl.value) +549 titles.append( +550 self.traces[i].tracelbl.value + '(' + self.traces[ +551 i].units.value + ')') +552 titles.append( +553 self.traces[i].tracelbl.value + '_' + 'stdev') +554 #print(str(titles)) +555 #print(str(datacolumns)) +556 self.pandadf = pd.DataFrame(np.transpose(datacolumns), columns=titles)Parameters
556 def updatingplot(self, PLTconn, PLTCTL): -557 """ -558 Runs until a check of self.collectbtn.description does not return -559 'Stop Collecting'. This would probably be more efficient if set a -560 boolean. -561 Parameters -562 ---------- -563 PLTconn: Pipe -564 connection plotter end -565 DAQconn: Pipe -566 connection DAQ end -567 PLTCTL: Pipe -568 control pipe plotter end -569 DAQCTL: Pipe -570 control pipe DAQ end -571 """ -572 starttime = time.time() -573 global data -574 data = [] -575 global timestamp -576 timestamp = [] -577 global stdev -578 stdev = [] -579 datalegend = [] -580 timelegend = [] -581 stdevlegend = [] -582 whichchn = [] -583 gains = [] -584 toplotx = [] -585 toploty = [] -586 nactive = 0 -587 def convert_pkg(): -588 plttime = 0 -589 if self.ignore_skew: -590 plttime = sum(pkg[0]) / len(pkg[0]) -591 traceidx = 0 -592 tmptime = [] -593 tmpavg = [] -594 tmpstd = [] -595 tmpavg_std = [] -596 for i, k in zip(self.tracemap, self.tracefrdatachn): -597 -598 avg = pkg[1][k] -599 std = pkg[2][k] -600 avg_std = pkg[3][k] -601 avg_vdd = pkg[4][k] -602 avg, std, avg_std = self.traces[i].toselectedunits(avg, -603 std, avg_std, -604 avg_vdd) -605 avg, std, avg_std = sensors. \ -606 to_reasonable_significant_figures_fast(avg, std, avg_std) -607 tmptime.append(pkg[0][k]) -608 tmpavg.append(avg) -609 tmpstd.append(std) -610 tmpavg_std.append(avg_std) -611 if self.ignore_skew: -612 toplotx[traceidx].append(plttime) -613 else: -614 toplotx[traceidx].append(pkg[0][k]) -615 toploty[traceidx].append(avg) -616 traceidx += 1 -617 timestamp.append(tmptime) -618 data.append(tmpavg) -619 stdev.append(tmpavg_std) -620 return -621 -622 for k in self.traces: -623 if k.isactive: -624 nactive += 1 -625 if self.separate_plots: -626 self.livefig.set_subplots(rows = nactive, cols = 1, -627 shared_xaxes= True) -628 self.livefig.update_xaxes(title = self.timelbl.value, -629 row = nactive, col = 1) -630 else: -631 self.livefig.update_yaxes(title = "Values") -632 self.livefig.update_xaxes(title = self.timelbl.value) -633 active_count = 0 -634 for i in range(self.ntraces): -635 if (self.traces[i].isactive): -636 active_count += 1 -637 tempstr = self.traces[i].tracelbl.value + '(' + \ -638 self.traces[i].units.value + ')' -639 timelegend.append('time_' + tempstr) -640 datalegend.append(tempstr) -641 stdevlegend.append('stdev_' + tempstr) -642 if self.separate_plots: -643 scat = go.Scatter(y=[],x=[], name=tempstr) -644 self.livefig.add_trace(scat, row = active_count, -645 col = 1) -646 self.livefig.update_yaxes(title = self.traces[ -647 i].units.value, row = active_count, col = 1) -648 else: -649 self.livefig.add_scatter(y=[],x=[], name=tempstr) -650 toplotx.append([]) -651 toploty.append([]) -652 lastupdatetime = time.time() -653 -654 pts = 0 -655 oldpts = 0 -656 #print('about to enter while loop',end='') -657 while (self.collectbtn.description == 'Stop Collecting'): -658 #print('.',end='') -659 while PLTconn.poll(): -660 pkg = PLTconn.recv() -661 self.lastpkgstr = str(pkg) -662 #print(self.lastpkgstr) -663 # convert voltage to requested units. -664 convert_pkg() -665 currenttime = time.time() -666 mindelay = 1.0 -667 if self.separate_traces_checkbox.value: -668 mindelay = nactive*1.0 -669 else: -670 mindelay = nactive*0.5 -671 if (currenttime - lastupdatetime)>(mindelay+len(toplotx[0])*len( -672 toplotx)/1000): -673 lastupdatetime = currenttime -674 for k in range(len(self.livefig.data)): -675 self.livefig.data[k].x=toplotx[k] -676 self.livefig.data[k].y=toploty[k] -677 #time.sleep(1) -678 PLTCTL.send('send') -679 time.sleep(self.delta) -680 # print ('btn.description='+str(btn.description)) -681 endtime = time.time() -682 PLTCTL.send('stop') -683 time.sleep(0.5) # wait 0.5 second to collect remaining data -684 PLTCTL.send('send') -685 time.sleep(0.5) -686 msg = '' -687 while (msg != 'done'): -688 while PLTconn.poll(): -689 pkg = PLTconn.recv() -690 # print(str(pkg)) -691 # convert voltage to requested units. -692 convert_pkg() -693 PLTCTL.send('send') -694 time.sleep(0.2) -695 if PLTCTL.poll(): -696 msg = PLTCTL.recv() -697 # print (str(msg)) -698 if (msg != 'done'): -699 print('Received unexpected message: ' + str(msg)) -700 for k in range(len(self.livefig.data)): -701 self.livefig.data[k].x = toplotx[k] -702 self.livefig.data[k].y = toploty[k] +@@ -2121,40 +2128,40 @@558 def updatingplot(self, PLTconn, PLTCTL): +559 """ +560 Runs until a check of self.collectbtn.description does not return +561 'Stop Collecting'. This would probably be more efficient if set a +562 boolean. +563 Parameters +564 ---------- +565 PLTconn: Pipe +566 connection plotter end +567 DAQconn: Pipe +568 connection DAQ end +569 PLTCTL: Pipe +570 control pipe plotter end +571 DAQCTL: Pipe +572 control pipe DAQ end +573 """ +574 starttime = time.time() +575 global data +576 data = [] +577 global timestamp +578 timestamp = [] +579 global stdev +580 stdev = [] +581 datalegend = [] +582 timelegend = [] +583 stdevlegend = [] +584 whichchn = [] +585 gains = [] +586 toplotx = [] +587 toploty = [] +588 nactive = 0 +589 def convert_pkg(): +590 plttime = 0 +591 if self.ignore_skew: +592 plttime = sum(pkg[0]) / len(pkg[0]) +593 traceidx = 0 +594 tmptime = [] +595 tmpavg = [] +596 tmpstd = [] +597 tmpavg_std = [] +598 for i, k in zip(self.tracemap, self.tracefrdatachn): +599 +600 avg = pkg[1][k] +601 std = pkg[2][k] +602 avg_std = pkg[3][k] +603 avg_vdd = pkg[4][k] +604 avg, std, avg_std = self.traces[i].toselectedunits(avg, +605 std, avg_std, +606 avg_vdd) +607 avg, std, avg_std = sensors. \ +608 to_reasonable_significant_figures_fast(avg, std, avg_std) +609 tmptime.append(pkg[0][k]) +610 tmpavg.append(avg) +611 tmpstd.append(std) +612 tmpavg_std.append(avg_std) +613 if self.ignore_skew: +614 toplotx[traceidx].append(plttime) +615 else: +616 toplotx[traceidx].append(pkg[0][k]) +617 toploty[traceidx].append(avg) +618 traceidx += 1 +619 timestamp.append(tmptime) +620 data.append(tmpavg) +621 stdev.append(tmpavg_std) +622 return +623 +624 for k in self.traces: +625 if k.isactive: +626 nactive += 1 +627 if self.separate_plots: +628 self.livefig.set_subplots(rows = nactive, cols = 1, +629 shared_xaxes= True) +630 self.livefig.update_xaxes(title = self.timelbl.value, +631 row = nactive, col = 1) +632 else: +633 self.livefig.update_yaxes(title = "Values") +634 self.livefig.update_xaxes(title = self.timelbl.value) +635 active_count = 0 +636 for i in range(self.ntraces): +637 if (self.traces[i].isactive): +638 active_count += 1 +639 tempstr = self.traces[i].tracelbl.value + '(' + \ +640 self.traces[i].units.value + ')' +641 timelegend.append('time_' + tempstr) +642 datalegend.append(tempstr) +643 stdevlegend.append('stdev_' + tempstr) +644 if self.separate_plots: +645 scat = go.Scatter(y=[],x=[], name=tempstr) +646 self.livefig.add_trace(scat, row = active_count, +647 col = 1) +648 self.livefig.update_yaxes(title = self.traces[ +649 i].units.value, row = active_count, col = 1) +650 else: +651 self.livefig.add_scatter(y=[],x=[], name=tempstr) +652 toplotx.append([]) +653 toploty.append([]) +654 lastupdatetime = time.time() +655 +656 pts = 0 +657 oldpts = 0 +658 #print('about to enter while loop',end='') +659 while (self.collectbtn.description == 'Stop Collecting'): +660 #print('.',end='') +661 while PLTconn.poll(): +662 pkg = PLTconn.recv() +663 self.lastpkgstr = str(pkg) +664 #print(self.lastpkgstr) +665 # convert voltage to requested units. +666 convert_pkg() +667 currenttime = time.time() +668 mindelay = 1.0 +669 if self.separate_traces_checkbox.value: +670 mindelay = nactive*1.0 +671 else: +672 mindelay = nactive*0.5 +673 if (currenttime - lastupdatetime)>(mindelay+len(toplotx[0])*len( +674 toplotx)/1000): +675 lastupdatetime = currenttime +676 for k in range(len(self.livefig.data)): +677 self.livefig.data[k].x=toplotx[k] +678 self.livefig.data[k].y=toploty[k] +679 #time.sleep(1) +680 PLTCTL.send('send') +681 time.sleep(self.delta) +682 # print ('btn.description='+str(btn.description)) +683 endtime = time.time() +684 PLTCTL.send('stop') +685 time.sleep(0.5) # wait 0.5 second to collect remaining data +686 PLTCTL.send('send') +687 time.sleep(0.5) +688 msg = '' +689 while (msg != 'done'): +690 while PLTconn.poll(): +691 pkg = PLTconn.recv() +692 # print(str(pkg)) +693 # convert voltage to requested units. +694 convert_pkg() +695 PLTCTL.send('send') +696 time.sleep(0.2) +697 if PLTCTL.poll(): +698 msg = PLTCTL.recv() +699 # print (str(msg)) +700 if (msg != 'done'): +701 print('Received unexpected message: ' + str(msg)) +702 for k in range(len(self.livefig.data)): +703 self.livefig.data[k].x = toplotx[k] +704 self.livefig.data[k].y = toploty[k] +705 returnParameters
714def Run(name): -715 """Load a run from stored data or start a new run if the local file for -716 the run does not exist. -717 Parameters -718 ---------- -719 name: str -720 String name for the run. The data will be stored in a file of this -721 name with the extension of `.jpidaq.html`. -722 """ -723 from pathlib import Path -724 from IPython import get_ipython -725 from IPython.display import display -726 global_dict = get_ipython().user_ns -727 runs = None -728 if 'runs' in global_dict and 'DAQinstance' in global_dict: -729 runs = global_dict['runs'] -730 else: -731 return ('Initialization of JupyterPiDAQ required') -732 # Check if run completed, if so reload data, display and exit -733 datafilepath = Path.cwd() / Path(str(name) + '.jpidaq.html') -734 if datafilepath.exists(): -735 # display the data as a live plotly plot. -736 svname = name + '.jpidaq.html' -737 runs.append(DAQinstance(len(runs)+1, title = name)) -738 runs[-1]._load_from_html(svname) -739 display(HTML(runs[-1].defaultparamtxt)) -740 display(HTML('<h3>Saved as: '+runs[-1].svname+'</h3>')) -741 display(runs[-1].livefig) -742 display(HTML(runs[-1].defaultcollecttxt)) -743 return -744 nrun = len(runs) + 1 -745 runs.append(DAQinstance(nrun, title=name)) -746 runs[-1].setup() -747 return +@@ -2181,16 +2188,16 @@717def Run(name): +718 """Load a run from stored data or start a new run if the local file for +719 the run does not exist. +720 Parameters +721 ---------- +722 name: str +723 String name for the run. The data will be stored in a file of this +724 name with the extension of `.jpidaq.html`. +725 """ +726 from pathlib import Path +727 from IPython import get_ipython +728 from IPython.display import display +729 global_dict = get_ipython().user_ns +730 runs = None +731 if 'runs' in global_dict and 'DAQinstance' in global_dict: +732 runs = global_dict['runs'] +733 else: +734 return ('Initialization of JupyterPiDAQ required') +735 # Check if run completed, if so reload data, display and exit +736 datafilepath = Path.cwd() / Path(str(name) + '.jpidaq.html') +737 if datafilepath.exists(): +738 # display the data as a live plotly plot. +739 svname = name + '.jpidaq.html' +740 runs.append(DAQinstance(len(runs)+1, title = name)) +741 runs[-1]._load_from_html(svname) +742 display(HTML(runs[-1].defaultparamtxt)) +743 display(HTML('<h3>Saved as: '+runs[-1].svname+'</h3>')) +744 display(runs[-1].livefig) +745 display(HTML(runs[-1].defaultcollecttxt)) +746 return +747 nrun = len(runs) + 1 +748 runs.append(DAQinstance(nrun, title=name)) +749 runs[-1].setup() +750 returnParameters
749def doRun(whichrun): -750 with whichrun.output: -751 display(HTML('<span id="LiveRun_'+str(whichrun.idno)+'"></span>')) -752 display(HTML(whichrun.defaultparamtxt)) -753 if hasattr(whichrun, "collectbtn"): -754 # only show if hasn't already collected data -755 whichrun.collectbtn.on_click(whichrun.collectclick) -756 display(whichrun.collectbtn) -757 display(HTML(whichrun.defaultcollecttxt)) -758 pass +@@ -2208,20 +2215,20 @@752def doRun(whichrun): +753 with whichrun.output: +754 display(HTML('<span id="LiveRun_'+str(whichrun.idno)+'"></span>')) +755 display(HTML(whichrun.defaultparamtxt)) +756 if hasattr(whichrun, "collectbtn"): +757 # only show if hasn't already collected data +758 whichrun.collectbtn.on_click(whichrun.collectclick) +759 display(whichrun.collectbtn) +760 display(HTML(whichrun.defaultcollecttxt)) +761 passParameters
817def update_runsdrp(): -818 # get list of runs -819 runlst = [('Choose Run', -1)] -820 for i in range(len(runs)): -821 runlst.append((str(i + 1) + ': ' + runs[i].title, i)) -822 # buid selection menu -823 global runsdrp -824 runsdrp = widgets.Dropdown( -825 options=runlst, -826 value=-1, -827 description='Select Run #:', -828 disabled=False, -829 ) -830 pass +@@ -2239,17 +2246,17 @@820def update_runsdrp(): +821 # get list of runs +822 runlst = [('Choose Run', -1)] +823 for i in range(len(runs)): +824 runlst.append((str(i + 1) + ': ' + runs[i].title, i)) +825 # buid selection menu +826 global runsdrp +827 runsdrp = widgets.Dropdown( +828 options=runlst, +829 value=-1, +830 description='Select Run #:', +831 disabled=False, +832 ) +833 passParameters
832def showSelectedRunTable(change): -833 global runsdrp -834 global last_run_table_out -835 whichrun = runsdrp.value -836 runsdrp.close() -837 last_run_table_out.clear_output() -838 tbldiv = '<div style="height:10em;">' + str(runs[whichrun].title) -839 tbldiv += str(runs[whichrun].pandadf.to_html()) + '</div>' -840 with last_run_table_out: -841 display(HTML(tbldiv)) -842 return +@@ -2267,23 +2274,23 @@835def showSelectedRunTable(change): +836 global runsdrp +837 global last_run_table_out +838 whichrun = runsdrp.value +839 runsdrp.close() +840 last_run_table_out.clear_output() +841 tbldiv = '<div style="height:10em;">' + str(runs[whichrun].title) +842 tbldiv += str(runs[whichrun].pandadf.to_html()) + '</div>' +843 with last_run_table_out: +844 display(HTML(tbldiv)) +845 returnParameters
844def showDataTable(): -845 """ -846 Provides a menu to select which run. Then displays the run in a -847 10 em high scrolling table. Selection menu is removed after choice -848 is made. -849 """ -850 from ipywidgets import Output -851 global last_run_table_out -852 last_run_table_out = Output() -853 update_runsdrp() -854 global runsdrp -855 runsdrp.observe(showSelectedRunTable, names='value') -856 with last_run_table_out: -857 display(runsdrp) -858 display(last_run_table_out) -859 # will display selected run and delete menu upon selection. -860 return +@@ -2305,17 +2312,17 @@847def showDataTable(): +848 """ +849 Provides a menu to select which run. Then displays the run in a +850 10 em high scrolling table. Selection menu is removed after choice +851 is made. +852 """ +853 from ipywidgets import Output +854 global last_run_table_out +855 last_run_table_out = Output() +856 update_runsdrp() +857 global runsdrp +858 runsdrp.observe(showSelectedRunTable, names='value') +859 with last_run_table_out: +860 display(runsdrp) +861 display(last_run_table_out) +862 # will display selected run and delete menu upon selection. +863 returnParameters
861def newCalculatedColumn(): -862 """ -863 Uses jupyter-pandas-GUI.new_pandas_column_GUI to provide a GUI expression -864 composer. This method finds the datasets and launches the GUI. -865 """ -866 df_info = [] -867 for i in range(len(runs)): -868 df_info.append([runs[i].pandadf, 'runs['+str(i)+'].pandadf', -869 str(runs[i].title)]) -870 new_pandas_column_GUI(df_info) -871 pass +@@ -2336,18 +2343,18 @@864def newCalculatedColumn(): +865 """ +866 Uses jupyter-pandas-GUI.new_pandas_column_GUI to provide a GUI expression +867 composer. This method finds the datasets and launches the GUI. +868 """ +869 df_info = [] +870 for i in range(len(runs)): +871 df_info.append([runs[i].pandadf, 'runs['+str(i)+'].pandadf', +872 str(runs[i].title)]) +873 new_pandas_column_GUI(df_info) +874 passParameters
873def newPlot(): -874 """ -875 Uses jupyter-pandas-GUI.plot_pandas_GUI to provide a GUI expression -876 composer. This method finds the datasets and launches the GUI. -877 """ -878 df_info = [] -879 for i in range(len(runs)): -880 if isinstance(runs[i].pandadf,pd.DataFrame): -881 df_info.append([runs[i].pandadf, 'runs['+str(i)+'].pandadf', -882 str(runs[i].title)]) -883 plot_pandas_GUI(df_info) -884 pass +@@ -2368,18 +2375,18 @@876def newPlot(): +877 """ +878 Uses jupyter-pandas-GUI.plot_pandas_GUI to provide a GUI expression +879 composer. This method finds the datasets and launches the GUI. +880 """ +881 df_info = [] +882 for i in range(len(runs)): +883 if isinstance(runs[i].pandadf,pd.DataFrame): +884 df_info.append([runs[i].pandadf, 'runs['+str(i)+'].pandadf', +885 str(runs[i].title)]) +886 plot_pandas_GUI(df_info) +887 passParameters
886def newFit(): -887 """ -888 Uses jupyter-pandas-GUI.fit_pandas_GUI to provide a GUI expression -889 composer. This method finds the datasets and launches the GUI. -890 """ -891 df_info = [] -892 for i in range(len(runs)): -893 if isinstance(runs[i].pandadf,pd.DataFrame): -894 df_info.append([runs[i].pandadf, 'runs['+str(i)+'].pandadf', -895 str(runs[i].title)]) -896 fit_pandas_GUI(df_info) -897 pass +diff --git a/docs/jupyterpidaq/Sensors.html b/docs/jupyterpidaq/Sensors.html index 0eebef1..e81ee37 100644 --- a/docs/jupyterpidaq/Sensors.html +++ b/docs/jupyterpidaq/Sensors.html @@ -3,7 +3,7 @@ - +889def newFit(): +890 """ +891 Uses jupyter-pandas-GUI.fit_pandas_GUI to provide a GUI expression +892 composer. This method finds the datasets and launches the GUI. +893 """ +894 df_info = [] +895 for i in range(len(runs)): +896 if isinstance(runs[i].pandadf,pd.DataFrame): +897 df_info.append([runs[i].pandadf, 'runs['+str(i)+'].pandadf', +898 str(runs[i].title)]) +899 fit_pandas_GUI(df_info) +900 passjupyterpidaq.Sensors API documentation @@ -34,7 +34,7 @@Submodules
- + built with pdoc - +jupyterpidaq.Sensors.sensors API documentation @@ -181,7 +181,7 @@API Documentation
- + built with pdoco;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e 1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o User Guide\n\n Introduction | \nUsage
\n\nIntroduction
\n\nThis software allows GUI (Graphical User Interface) driven live collection, \nplotting and analysis of digitized data inside a Jupyter notebook using the \nfollowing A-to-D interfaces:
\n\non a Raspberry Pi:
\n\n\n
\n\n- Adafruit compliant ADS1115 boards \n(example,\nalso available from other vendors);
\n- The π-Plates DAQC2 plate.
\non MacOS and Windows:
\n\n\n
\n\n- Vernier LabQuest USB A-to-Ds.
\ndemo mode on anything Jupyter runs on
\n\n\n
\n\n- A demo mode will run on any computer with a Jupyter notebook install and\nPython 3.6+. Example notebooks can be found in the \"usage_examples\" folder.
\nUsage
\n\nLaunch the software | \nInitialize data acquisiton tools | \nCollect data |\nDisplaying a Data Table | \nPlotting data | \nAnalyzing data
\n\nStarting JupyterPiDAQ
\n\nA working Jupyter notebook or Jupyter lab installation with JupyterPiDAQ \ninstalled is required. If you need to install the software see the Installation \nInstructions. There are two common ways this may be set \nup, that lead to slightly different steps for starting the software:
\n\n\n
\n\n- A special kernel may be set up that can be used in any Jupyter notebook \ninstall for the current user (see the very end of the\nInstallation Instructions). \n
\n\n
- In this case launch\nJupyter, in whichever directory you want to work, using the \ncommand:
\njupyter notebook
orjupyter lab
.- Open a new notebook and choose the kernel \nfor
\nJupyterPiDAQ
. The kernel name will depend upon what was chosen \nduring installation.- Only for use within the directory structure of the virtual environment \nthat was set up for the software. \n
\n\n
- In this case you must navigate to the \ndirectory of the virtual environment using the
\ncd
command before \nstarting the software.- Then enter the virtual environment with the command
\npipenv shell
. \nThis assumes you set uppipenv
as described in the \nInstallation instructions.- Launch Jupyter using the command:
\njupyter notebook
orjupyter lab
.- Open a new python notebook.
\nInitialize the Data Acquisition Tools
\n\nInitialize the data acquisition tools by putting the statement
\n\nfrom \njupyterpidaq.DAQinstance import *
into the first cell and clicking on the \n'Run' button. The package loads supporting packages (numpy, pandas, plotly,\netc...) and searches for compatible hardware. On a Raspberry Pi this takes a\nnumber of seconds. If no compatible A-to-D boards are found, demo mode is used.\nIn demo mode the A-to-D board is simulated by a random number generator.When setup is done a new menu appears at the end of the menubar (figure 1).
\n\n\n\nFigure 1: The menu created once the data acquisition software is \ninitialized. Currently NOT available in Jupyter Lab.
\n\nThe menu options insert jupyter widget based GUIs for starting a run,\ndisplaying the data as tables or plots, composing an expression to calculate\na new column in a DataFrame, or fitting data.
\n\nCollecting data
\n\nUsing the Menu
\n\nFrom the \"DAQ Commands\" menu select \"Insert New Run After Selection...\" or \n\"Append New Run to End...\". The first will insert the code to set up \ndata collection for a run in the cell below the currently selected cell. \nThe second will append this to the end of the notebook. When the cell is \nrun it will generate \na GUI that looks like the figure 2, below. Fill in the information to define \nwhat you wish to do (see below figure 2 for more details).
\n\nUsing a Command
\n\nIn the cell you wish to collect the data enter the command \n
\n\n\n\nRun(\"desired_dataset_name\")
, where you replace desired_dataset_name with the \nstring you want for this run. Replacing spaces with _ will prevent issues, \nespecially on Windows. After entering the command, run the cell. This will \ngenerate the GUI shown in figure 2.Figure 2: Image of the GUI for setting up a data collection run.
\n\n\n
\n\n- Give the run a title/name using the first textbox.
\n- You can collect up to four (4) data traces at once. Two different data \ntraces can display the same analog-to-digital channel, but in different \nunits (e.g. you could record both the raw voltage and temperature from a \nthermistor). Each trace is activated by selecting its checkbox.
\n- Once a trace is activated you can give it a title and must select: the \ndata acquisition board, channel, sensor, units and gain from the \navailable drop-down menus.
\n- Once all your traces are set up decide whether they should be displayed in \nmultiple stacked graphs or all on the same graph. Uncheck the box to \ndisplay all on one graph.
\n- Select the data collection rate (20 Hz is currently the maximum rate, but \non a Raspberry Pi you may not be able to sustain more than 5 Hz).
\n- When everything is set the way you wish, click on the \"Set Parameters\" \nbutton. The collection parameters will be displayed and a button to \nstart the data collection will appear. You may have to scroll back up to \nthe display as Jupyter sometimes jumps too far down when a cell is updated.
\n- The \"start\" button will convert to a \"stop\" button once data collection \nis started. The data graph(s) will update at roughly 1 Hz, so you can \nmonitor the progress of the data collection.
\n- Click the \"stop\" button to end data collection. It can take \na while to stop if the data collection has got ahead of the graphic \ndisplay of the data.
\n- Once collection is stopped you will see a plot or plots of the completed \ndata collection and the name of the .html file the raw data has been \nbacked up to.
\n- Should you accidentally clear the output of a completed collection cell,\nrerunning it will regenerate the display as long as you have not moved \nthe raw data backup file.
\nDisplaying data
\n\nIn a table
\n\nSelecting the \"Show data in table...\" option in the \"DAQ Command\" menu will \ninsert a cell immediately below the currently selected cell displaying a \nwidget in which you can select which data set to display. The command \nequivalent is
\n\nshowDataTable()
.Plotting data
\n\nSelecting the \"Insert new plot after selection...\" option in the menu will\ninsert two cells immediately below the currently selected cell. The first cell\nwill be used to generate a GUI to lead you through creation of the code to\ngenerate the plot. The second cell is where the plot creation code is \ngenerated. The first tab of this GUI looks like figure 3. The command \nequivalent is
\n\n\n\nnewPlot()
.Figure 3: Image of the first tab in the four tab (4 step) Pandas Plot \nComposer. More information in the Pandas_GUI\ndocumentation.
\n\nIt is best to do the tabs in order. The notices in red will try to \nwarn you of errors or oversights. The \"Instructions\" accordian can be \nexpanded to get more specific information about how to use each tab.
\n\nYou can get more sophisticated control of \nyour plot by editing the code produced by this GUI. See the Plotly \nFigureWidget Instructions and the \nexample Jupyter notebooks referenced there for more information.
\n\nThe GUI destroys itself once you complete step 4.
\n\nAnalyzing data
\n\nCalculating a new column
\n\nSelecting \"Calculate new column...\" from the menu will add two cells\nimmediately below the selected cell. The first cell will create the GUI to\nlead you through creation of the code to calculate the new column. The second\ncell is where the code is built. The first tab of the GUI looks like \nfigure 4. The command equivalent is
\n\n\n\nnewCalculatedColumn()
.Figure 4: Image of the first tab in the four tab (4 step) Pandas New \nCalculated Column Composer. More information in the Pandas_GUI\ndocumentation.
\n\nDo the tabs in order. You can perform more complex manipulations than built \ninto the GUI by editing the code generated by this GUI.
\n\nThe GUI destroys itself once you complete step 4.
\n\nFitting data
\n\nA GUI for defining simple fits (linear, polynomial, exponential decay, sine \nand Gaussian) can be launched by selecting \"Insert new Fit after selection..\n.\" from the menu. This will create the GUI to lead you through selecting \nand fitting the data. The code is created in the cell immediately below the \nGUI. The command equivalent is
\n\n\n\nnewFit()
.Figure 5: Image of the first tab in the Pandas Fit Composer.\nMore information in the Pandas_GUI\ndocumentation.
\n\nInstallation
\n\nInitial setup: On Raspberry Pi | \nOn non-Pi Systems
\n\n\n\nRaspberry Pi Initial Setup
\n\nUnless you only want to run in Demo mode make sure you have one of the \ncompatible interface boards installed. The current options are:
\n\n\n
\n\n- Adafruit compliant ADS1115 boards \n(example,\nalso available from other vendors);
\n- The π-Plates DAQC2 plate.
\n- If you wish to use different interfaces see the Development\nNotes\n and the
\nBoards
subpackage ofjupyterpidaq
for examples and \n information on how to define the code interface for a board.OS specific: Ubuntu on Pi | \nRaspberrian on Pi |\nMacOS | Windows
\n\nUbuntu on Pi
\n\nBy default in Ubuntu 20.04 for Pis the gpio and spi groups do not exist.\nThe i2c group does (not always).
\n\n\n
\n\n- Make sure that the following packages are installed
\nrpi.gpio-common \npython3-pigpio python3-gpiozero python3-rpi.gpio
.- You can avoid having to create a gpio group, by assigning users who need\n gpio access to the dialout group. Check that /dev/gpiomem is part of that \ngroup and that the dialout group has rw access. If not you will need to set\n it.
\n- Users also need to be members of the i2c group. If it does not exist create \n it and then make that the group for /dev/i2c-1 with group rw permissions. \nTHIS MAY NOT BE NECESSARY.
\n- The spi group needs to be created (addgroup?).
\n- Additionally the spi group needs to be given rw access to the spi devices\nat each boot. To do this create a one line rule in a file named \n
\n/etc/udev/rules.d/50-spidev.rules
containingSUBSYSTEM==\"spidev\", \nGROUP=\"spi\", MODE=\"0660\"
. The file should have rw permission for root \nand read permission for everyone else.- Make sure you have pip installed for \npython 3:
\npython3 -m pip --version
orpip3 --version
. If you do not, \ninstall usingapt \ninstall python3-pip
.Raspberrian on Pi
\n\n(TBD)
\n\nNon-Pi based System Initial Setup
\n\nMake sure that Python >=3.6 is installed:
\n\npython3 -v
. If not follow \ninstructions at python.org. This software should run \non any computer capable of supporting the necessary version of Python. \nHowevever, it will only run in demo mode if the computer does not support \none of the compatible A-to-D boards.Generic Linux
\n\n\n
\n\n- If your system hardware \nhas GPIO pins and a GPIO interface board, you should try following the \ninstructions for a Pi based system above. If \nyou figure out how to make this work on other SBCs or systems with GPIO, \nplease submit a pull request updating these instructions.
\n- If your system hardware does not support GPIO and one of the compatible \ninterface boards, the software will run in demo mode.
\nNOTE: If a binary distribution (whl or wheel) is not available for your\nplatform, some of the required packages may need to be compiled. If you get\ncompilation errors when installing try getting the python header and \ndevelopment files for your platform. To get them on most *nix platforms use the\ncommand
\n\nsudo apt install python3-dev
.MacOS
\n\nCurrently, the LabQuest A-to-Ds are only working on intel based macs. When \nVernier recompiles their interface communication library for the M1 series \ncpus this will change.
\n\n\n
\n\n- Install the latest version of Python, by following the instructions on \nthe Python website.
\n- Make sure a virtual environment tool such as
\npipenv
is installed. In a \nterminal window trypython -m pip install --user pipenv
.Windows
\n\nNote: LoggerPro software may need to be \ninstalled because that provides the compiled
\n\n.dll
necessary to communicate \nwith the LabQuest interface. In theory will work without this.\n
\n\n- Install the latest version of Python, by following the instructions on \nthe Python website. WARNING: Do Not use \nWindows automatic installation. It may work on a plain vanilla system \nwith one user, but in multiuser systems it badly messes up the ability to \nuse virtual environments.
\n- Make sure a virtual environment tool such as
\npipenv
is installed. In a \nterminal window trypython -m pip install --user pipenv
.- You may have to set or add to your user
\nPATH
environment variable. See \nthe warnings generated during the installation. Then search for the \nlatest instructions on how to setPATH
.Final Set Up
\n\n\n
\n\n- If on Raspberry Pi type system, make sure the user you will be running the \nsoftware under is a member of the groups
\ndialout
,spi
and if it \nexistsi2c
.- It is recommended that you install JupyterPiDAQ in its own \nvirtual environment.\nThe instructions below do just that using the original author's favorite \nvirtual environment tool pipenv.
\nLog into your chosen user account:
\n\n\n
\n\n- Install pipenv:
\npip3 install \n--user pipenv
. You may\nneed to add~/.local/bin
to yourPATH
to makepipenv
\navailable in your command shell. More discussion: \nThe Hitchhiker's Guide to\nPython.- Create a directory for the virtual environment you will be installing\ninto (example:
\nmkdir JupyterPiDAQ
).- Navigate into the directory
\ncd JupyterPiDAQ
.- Create the virtual environment and enter it
\npipenv shell
. To get out of\nthe environment you can issue theexit
command on the command line.- While still in the shell install the latest JupyterPiDAQ and all its\nrequirements\n
\npip install -U JupyterPiDAQ
. This can take a long time, especially on a\n Raspberry Pi. On a Pi 3B+ (minimum requirement) it will probably not run\n without at least 1 GB of swap. See: Build Jupyter on a Pi\n for a discussion of adding swap space on a Pi.- Still within the environment shell test\nthis by starting jupyter
\njupyter notebook
orjupyter lab
. Jupyter should \nlaunch in your browser.\n\n
- Open a new notebook using the default (Python 3) kernel.
\n- In the first cell import all from DAQinstance.py: \n
\nfrom jupyterpidaq.DAQinstance import *
.\n When run in jupyter notebook this cell should load the DAQmenu at the \n end of the Jupyter notebook menu/icon bar. Currently, no convenience \n menu is available in Jupyter lab. If you do not have an appropriate\n A-to-D board installed you will get a message and the software\n will default to demo mode, substituting a random number\n generator for the A-to-D.- If you wish, you can make this environment available to an alternate Jupyter\ninstall as a special kernel when you are the user.\n
\n\n
- Make sure you are running in your virtual environment
\npipenv shell
\nin the directory for virtual environment will do that.- Issue the command to add this as a kernel to your personal space: \n
\npython -m ipykernel install --user --name=<name-you-want-for-kernel>
.- More information is available in the Jupyter/IPython documentation. \nA simple tutorial from Nikolai Jankiev (_Parametric Thoughts_) can be\nfound here.
\nDevelopment Notes
\n\nCode Repository
\n\nSetting up Development Environment
\n\nBasic requirements: Python 3.6+, associated\npip and a Jupyter notebook.\nSee: python.org and\nJupyter.org.
\n\n\n
\n\n- If not installed, install pipenv:
\n$ pip3 install --user pipenv
. You may\nneed to add~/.local/bin
to yourPATH
to makepipenv
\navailable in your command shell. More discussion: \nThe Hitchhiker's Guide to Python.- Navigate to the directory where this package will be\nor has been downloaded to. Use
\npipenv
to install an \n\"editable\" package \ninside the directory as described below:\n\n
- Start a shell in the environment
\n$ pipenv shell
.- Install using pip.\n
\n\n
- If you downloaded the git repository named \"JupyterPiDAQ\"\nand have used that directory to build your virtual\nenvironment:
\n$ pip install -e ../JupyterPiDAQ/
.- If you are downloading from PyPi\n
\n$ pip install -e JupyterPiDAQ
- Either should install all the additional packages this\npackage depends upon. On a Raspberry Pi this will take\na long time. It probably will not run without at least 1 GB of swap. See: \nBuild Jupyter on a Pi\n.
\n- Still within the environment shell test\nthis by starting jupyter
\n$ jupyter notebook
. Jupyter should launch in\nyour browser.\n\n
- Open a new notebook using the default (Python 3) kernel.
\n- In the first cell import all from DAQinstance.py: \n
\nfrom jupyterpidaq.DAQinstance import *
.\nWhen run this cell should load the DAQmenu at the end of the\nJupyter notebook menu/icon bar. If you do not have an appropriate A-to-D\nboard installed you will get a message and the software\nwill default to demo mode, substituting a random number\ngenerator for the A-to-D. Because of the demo mode it is\npossible to run this on any computer, not just a Pi.- If you wish, you can make this environment available to an alternate Jupyter\ninstall as a special kernel when you are the user.\n
\n\n
- Make sure you are running in your virtual environment
\n$ pipenv shell
\nin the directory for virtual environment will do that.- Issue the command to add this as a kernel to your personal space: \n
\n$ python -m ipykernel install --user --name=<name-you-want-for-kernel>
.- More information is available in the Jupyter/Ipython documentation. \nA simple tutorial from Nikolai Jankiev (_Parametric Thoughts_) can be\nfound here.
\nAdding New Sensor Code
\n\n\n
\n\n- Copy an existing sensor class paste it into the end of\nsensors.py and rename it.
\n- Update/delete functions for each valid unit within the new\nclass as necessary.
\n- Update the sensor name, vendor and available units in the\n
\n__init__
function.- Add the new sensor classname to the list of available sensors\nin
\nlistSensors
at about line 120 of sensors.py.- Add the new sensor classname to
\ngetsensors
of ADCsim.py,\nADCsim_line.py and any board (e.g. DAQC2.py) with which the sensor\ncan be used. Do not guess if a sensor works with a particular\nboard. Test it!Running Tests
\n\n\n
\n\n- Install updated pytest in the virtual environment:\n
\npipenv shell\npip install -U pytest\n
- Run tests ignoring the manual tests in the
\ndev_testing
directory:\npython -m pytest --ignore='dev_testing'
.Building Documentation
\n\n\n
\n\n- Install or update pdoc into the virtual environment
\npip install -U pdoc
.- Make edits to the
\n.md
files within the docs folder that are to be \nincluded in the first page (see__init__.py
of the jupyterpidaq package).- At the root level run
\npdoc \n--logo https://jupyterphysscilab.github.io/JupyterPiDAQ/JupyterPiDAQ-logo.svg --logo-link \nhttps://jupyterphysscilab.github.io/JupyterPiDAQ/ --footer-text \n\"JupyterPiDAQ vX.X.X\" -html -o docs jupyterpidaq
Unless you are on a \nRaspbery Pi this will throw an error aboutimport
. Just ignore.Building PyPi package
\n\n\n
\n\n- Make sure to update the version number in setup.py first.
\n- Install updated setuptools and twine in the virtual environment:\n
\npipenv shell\npip install -U setuptools wheel twine\n
- Build the distribution
\npython -m setup sdist bdist_wheel
.- Test it on
\ntest.pypi.org
.\n\n
- Upload it (you will need an account on test.pypi.org):\n
\npython -m twine upload --repository testpypi dist/*
.- Create a new virtual environment and test install into it:\n
\n\nThere are often install issues because sometimes only older versions of\nsome of the required packages are available on test.pypi.org. If this\nis the only problem change the version to end inexit # to get out of the current environment\ncd <somewhere>\nmkdir <new virtual environment>\ncd <new directory>\npipenv shell #creates the new environment and enters it.\npip install -i https://test.pypi.org/..... # copy actual link from the\n # repository on test.pypi.\n
rc0
for release\ncandidate and try it on the regular pypi.org as described below for\nreleasing on PyPi.- After install test by running a jupyter notebook in the virtual \nenvironment.
\nReleasing on PyPi
\n\nProceed only if testing of the build is successful.
\n\n\n
\n\n- Double check the version number in setup.py.
\n- Rebuild the release:
\npython -m setup sdist bdist_wheel
.- Upload it:
\npython -m twine upload dist/*
- Make sure it works by installing it in a clean virtual environment. This\nis the same as on test.pypi.org except without
\n-i https://test.pypy...
. If\nit does not work, pull the release.Change Log
\n\n\n
\n\n- 0.8.0 (Apr. 20, 2023)\n
\n\n
- Replaced
\nNewRun()
command withRun()
command. This version works in \nJupyter Lab and removes the need for theDisplayRun()
command because \nRun()
will load an already collected dataset or start a new one.- Now, when multiple traces are assigned to the same channel of a board the \nchannel is only read one time. If the units are different the two \ntraces will be displayed with different units.
\n- Can read data from Vernier LabQuest USB \nanalog-to-digital interfaces. Potential data rate is 10 kHz, currently \nlimited to 20 Hz.
\n- Runs in Jupyter Lab (no menus yet) and Notebook \n(menus still work).
\n- Updated requirements to include jupyterlab and labquest packages.
\n- 0.7.9 (Mar. 9 2023)\n
\n\n
- Added
\nspidev
package to requirements becausepi-plates
requires it.- More robust exception handling when searching for boards/A-to-Ds.
\n- 0.7.8\n
\n\n
- Updated text for insertion into cells to make better use of escaping \nupdates in JPSLUtils >=0.7.0.
\n- Removed some unnecessary print statements.
\n- 0.7.7\n
\n\n
- Updated requirements for upstream security fixes.
\n- Conversion to pandas dataframe now works when trace 0 is not collected.
\n- DAQ menu no longer created in trusted notebooks if the data acquisition \ntools have not been initialized since the notebook was opened.
\n- Reworked the data collection so that opening an old notebook without \nrunning anything will not have any leftover inoperable or undefined \nwidgets.
\n- Reordered the live trace display to match the order of the names at right.
\n- Runs now saved to a human readable html file that includes the run \nconditions.
\n- As long as this html file is in the same directory as the notebook, the \nrun display can be recreated by running its cell after accidentally \nclearing the cell output.
\n- The cell displaying the results of a run is now protected against \ndeletion and editing.
\n- 0.7.6\n
\n\n
- Converted to fancy menus (could make hierarchical).
\n- 0.7.5\n
\n\n
- Added fitting to DAQ command menu.
\n- Documentation Enhancements: github.io website; first pass as API docs; \nreorganized documentation; MyBinder link now forces launch in classic \nnotebook; added plans for adapter board to connect Vernier Sensors.
\n- 0.7.4.1\n
\n\n
- Improved layout of data collection.
\n- Better widget cleanup.
\n- Readme fixes.
\n- 0.7.3 Pip install reliability fixes.
\n- 0.7.2 Suppress Javascript error when not in JLab.
\n- 0.7.1\n
\n\n
- Include Heat Capacity Lab example.
\n- Make menu show up in JLab (still not functional).
\n- Remove matplotlib baggage.
\n- 0.7.0\n
\n\n
- Switched to plotly widget for plotting.
\n- Added Vernier pressure sensor calibrations (old and new).
\n- Jupyter widgets based new calculated column GUI.
\n- Jupyter widgets based new plot GUI.
\n- Default to providing only one time for channels collected nearly \nsimultaneously.
\n- As reported values are averages, switched to reporting the estimated \nstandard deviation of the average rather than the deviation of all the \nreadings used to create the average.
\n- 0.6.0 \n
\n\n
- Initial release.
\n- Live data collection.
\n- Recognized sensors: ADS1115 boards (voltage, built-in thermistor, \nVernier SS temperature probe), DAQC2 boards (voltage,Vernier SS \ntemperature probe, Vernier standard pH probe, Vernier flat pH probe).
\nThree Channel Adapter Board for Vernier Sensors
\n\nBoard plans
\n\n\n\nEtching the board
\n\nClean Cu cladding to be etched by wet sanding with 1500 grit or finer.\nDraw traces with a black sharpie \u201cindustrial super permanent ink\u201d version\nworks best. Allow to dry completely (no odor). Can be speeded up using a heat\ngun.
\n\nEtchant recipe:
\n\n3 M HCl
\n\nCuCl2 to make medium emerald green solution (can also be made by \ndissolving Cu after adding hydrogen peroxide)
\n\nUsing test piece add 30% H2O2 dropwise to get gentle \nbubbling and \ncomplete\nremoval in 3 \u2013 5 min (longer gives poorly defined edges).
\n"}, {"fullname": "jupyterpidaq.Boards", "modulename": "jupyterpidaq.Boards", "kind": "module", "doc": "This module wraps all the submodules related to communication and control of\ndata acquisition boards.
\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO", "modulename": "jupyterpidaq.Boards.PiGPIO", "kind": "module", "doc": "This module contains the modules for all PiGPIO based boards.
\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.find_boards", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "find_boards", "kind": "function", "doc": "A routine like this must be implemented by all board packages.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115", "kind": "class", "doc": "list of ADS1115 board objects (maximum of 4 boards)
\nClass defining the properties of Adafruit compatible ADS1115\nanalog-to-digital boards for Raspberry-Pi style GPIO. Key characteristics:
\n\n\n
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.__init__", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.__init__", "kind": "function", "doc": "- 4 channels (0 - 3) with 16 bit resolution and a range of +/- 3.3 V
\n- Programmable gain on each channel of 2/3, 1, 2, 4, 8, 16 making these\ngood for small signals.
\n- a differential mode is available but not implemented in this class.
\nShould be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(adc)"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.getsensors", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.V_oversampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nV_min -- float, the minimum voltage read during\nthe interval\n\nV_max -- float, the maximum voltage read during the\ninterval\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nself.Vdd -- float, the reference voltage.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3)
- \n
gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),\n4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
- \n
int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,\n128,250, 475 or 860 Hz). Set to 475 Hz by default.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, V_min, V_max, time_stamp, self.Vdd
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nstdev -- float, the standard deviation of the measured values\nduring the averaging interval\n\nstdev_avg -- float, the estimated standard deviation of the\nreturned average\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nself.Vdd -- float, the reference voltage.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3)
- \n
gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),\n4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
- \n
int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,\n128,250, 475 or 860 Hz). Set to 475 Hz by default.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: VV_avg, stdev, stdev_avg, time_stamp, self.Vdd
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.V_sampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.V_sampchan", "kind": "function", "doc": "This routine returns the voltage for the
\n\nReturns a tuple of the following 3 objects:\n V -- float, the measured voltage
\n\n\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nself.Vdd -- float, the reference voltage.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3)
- \n
gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),\n4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
- \n
int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,\n128,250, 475 or 860 Hz). Set to 475 Hz by default.
:returns: V, time_stamp, self.Vdd
\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.find_boards", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "find_boards", "kind": "function", "doc": "A rountine like this must be implemented by all board packages.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2", "kind": "class", "doc": "list of DAQC2 board objects (maximum of 8 boards)
\nClass defining the properties of the analog-to-digital block of the\npi-Plates DAQC2 board. Key characteristics:
\n\n\n
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.__init__", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.__init__", "kind": "function", "doc": "- 8 channels (0 - 7) with pseudo 16 bit resolution (oversampled 14 bit) and\na range of +/- 12 V.
\n- 1 channel (8) dedicated to monitoring Vdd.
\n- Programmable RGB LED to use as indicator.
\n- Other available facilities are Digital I/O, Digital-to-Analog and\n2-channel o-scope modes. These are not supported by this class.
\nShould be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(addr)"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.getsensors", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.V_oversampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at the default rate for the board and returns an\naverage and observed range.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nV_min -- float, the minimum voltage read during\nthe interval\n\nV_max -- float, the maximum voltage read during the\ninterval\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3, 4, 5, 6, 7,\n8). NOTE: channel 8 returns a measurement of Vdd.
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: ignored by board.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, V_min, V_max, time_stamp, Vdd_avg
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at the maximum rate for the board. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nstdev -- float, the standard deviation of the measured values\nduring the averaging interval\n\nstdev_avg -- float, the estimated standard deviation of the\nreturned average\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3, 4, 5, 6, 7,\n8). NOTE: channel 8 returns a measurement of Vdd.
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: ignored by board.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.V_sampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.V_sampchan", "kind": "function", "doc": "This routine returns a single reading of the voltage for the channel.
\n\nReturns a tuple of the following 5 objects:\n V -- float, the measured voltage
\n\n\n\ntime_stamp -- float, the time of the measurement in seconds since\nthe beginning of the epoch (OS dependent begin time)\n\nref -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3, 4, 5, 6, 7,\n8). NOTE: channel 8 returns a measurement of Vdd.
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: ignored by board.
:returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated", "modulename": "jupyterpidaq.Boards.Simulated", "kind": "module", "doc": "This module wraps modules for simulated boards.
\n"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.find_boards", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "find_boards", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random", "kind": "class", "doc": "Base class for all boards. Each board should be an extension of this class.
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.__init__", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.__init__", "kind": "function", "doc": "Should be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(adc)"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.getsensors", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.V_oversampchan_stats", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475 or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be as close\n as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in seconds\n since the beginning of the epoch (OS dependent begin time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.V_oversampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.V_oversampchan", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475 or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be as close\n as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in seconds\n since the beginning of the epoch (OS dependent begin time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.V_sampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.V_sampchan", "kind": "function", "doc": "This function returns a single measurement and the time it was\ncollected.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.find_boards", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "find_boards", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line", "kind": "class", "doc": "a tuple consisting of V, time_stamp, where V = the single\n voltage measurement and time_stamp the time it was collected.
\nThis class simulates an Analog-to-Digital board that returns a linearly\nincreasing signal with a small amount of noise on the signal. The\nintercept and slope depend upon which hour of the day the simulation is\nrun.
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.__init__", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.__init__", "kind": "function", "doc": "Should be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(adc)"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.getsensors", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.V_oversampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475\n or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be\n as close as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in\n seconds since the beginning of the epoch (OS dependent begin\n time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475\n or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be\n as close as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in\n seconds since the beginning of the epoch (OS dependent begin\n time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.V_sampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.V_sampchan", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475\n or 860 Hz) avg_sec seconds to average for, actual averaging\n interval will be as close as possible for an integer number of\n samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in\n seconds since the beginning of the epoch (OS dependent begin\n time).
\n", "signature": "(self, chan, gain, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards", "modulename": "jupyterpidaq.Boards.boards", "kind": "module", "doc": "This file handles loading adc board control software and sensor information.\nIt uses the list of known boards. It will skip boards that produce an error\neither because the pypi package is not installed or an error occurs when\ntrying to communicate with the board.
\n\nThe ADC simulator will be installed if no boards are available.
\n"}, {"fullname": "jupyterpidaq.Boards.boards.load_boards", "modulename": "jupyterpidaq.Boards.boards", "qualname": "load_boards", "kind": "function", "doc": "Uses the list of known board packages to search for available boards.\nThe file
\n\n.py should at minimum\nimplement a find_boards(): routine that overrides the function below and\ndefine a class for the particular board that extends the
Board` class\ndefined below.Returns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.find_boards", "modulename": "jupyterpidaq.Boards.boards", "qualname": "find_boards", "kind": "function", "doc": "list of adc board objects.
\nA function overriding this must be implemented by all board packages.\nSee examples in working packages. This is highly board dependent.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board", "kind": "class", "doc": "list of board objects
\nBase class for all boards. Each board should be an extension of this class.
\n"}, {"fullname": "jupyterpidaq.Boards.boards.Board.__init__", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.__init__", "kind": "function", "doc": "Should be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "()"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getname", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getname", "kind": "function", "doc": "Returns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getchannels", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getchannels", "kind": "function", "doc": "string value of the board name, a short label of board type.
\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getgains", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getgains", "kind": "function", "doc": "tuple of ids for available channels
\nIf not defined for a specific board the gain is fixed at 1.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getvendor", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getvendor", "kind": "function", "doc": "tuple of gains availabe for onboard preamp
\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getVdd", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getVdd", "kind": "function", "doc": "string value of the vendor name
\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getsensors", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getsensors", "kind": "function", "doc": "numerical value of the Vdd, voltage provided to sensors
\nThis returns a list of objects that allow the software to translate\nthe measured voltage into a sensor reading in appropriate units.\nMust be provided by the specific board implementation. See examples\nin working board packages.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.V_oversampchan", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.V_oversampchan", "kind": "function", "doc": "A list of valid sensor objects to use with this board. This\n should be a subset of all the sensors returned by the listSensors\n function in sensors.py.
\nThis function should return a tuple with average, minimum and maximum\nfor a channel averaged over the period of time avg_sec. How the\naveraging is performed will depend on the board.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\n- avg_sec: float period of time over which to average
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, avg_sec, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.V_oversampchan_stats", "kind": "function", "doc": "a tuple consisting of V_avg, V_min, V_max, time_stamp, avg_Vdd\n The time_stamp is the time the data was collected, usually the\n middle of the averaging period. avg_Vdd should be the measured\n average Vdd taken simultaneously, immediately before,\n or immediately after the voltage being measured. If the board or\n power supply is very stable self.Vdd can be returned instead.
\nThis function should return a tuple of statistical information for a\nchannel averaged over the period of time avg_sec.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\n- avg_sec: float period of time over which to average
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, avg_sec, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.V_sampchan", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.V_sampchan", "kind": "function", "doc": "tuple consisting of V_avg, stdev, stdev_avg, time_stamp,\n avg_Vdd where stdev_avg is the estimated standard deviation\n of the average not the standard deviation of the values\n sampled (stdev). avg_Vdd should be the measured\n average Vdd taken simultaneously, immediately before,\n or immediately after the voltage being measured. If the board or\n power supply is very stable self.Vdd can be returned instead.
\nThis function returns a single measurement and the time it was\ncollected.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier", "modulename": "jupyterpidaq.Boards.vernier", "kind": "module", "doc": "a tuple consisting of V, time_stamp, ref_Vdd, where V = the\n single voltage measurement and time_stamp the time it was\n collected. ref_Vdd should be the measured\n Vdd taken simultaneously, immediately before,\n or immediately after the voltage being measured. If the board or\n power supply is very stable self.Vdd can be returned instead.
\nThis module contains modules for the Vernier Interfaces.
\n"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest", "modulename": "jupyterpidaq.Boards.vernier.labquest", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.find_boards", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "find_boards", "kind": "function", "doc": "A rountine like this must be implemented by all board packages.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ", "kind": "class", "doc": "list of LabQuests (Types too?)
\nClass defining the properties of the analog-to-digital block of the\nLabQuests. Key characteristics:
\n\n\n
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.__init__", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.__init__", "kind": "function", "doc": "- 3 channels (1, 2, 3) a range of +/- 10 V.
\n- 12 bit resolution
\n- Other available but not implemented facilities are Digital I/O.
\nShould be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(addr, send, rcv)"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.getsensors", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.V_oversampchan", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at the default rate for the board and returns an\naverage and observed range.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nV_min -- float, the minimum voltage read during\nthe interval\n\nV_max -- float, the maximum voltage read during the\ninterval\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (1, 2, 3)
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: maximum
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, V_min, V_max, time_stamp, Vdd_avg
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=10000):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at the maximum rate for the board. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nstdev -- float, the standard deviation of the measured values\nduring the averaging interval\n\nstdev_avg -- float, the estimated standard deviation of the\nreturned average\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, returned as None.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (1, 2, 3)
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate:
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=10000):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.V_sampchan", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.V_sampchan", "kind": "function", "doc": "This routine returns a single reading of the voltage for the channel.
\n\nReturns a tuple of the following 5 objects:\n V -- float, the measured voltage
\n\n\n\ntime_stamp -- float, the time of the measurement in seconds since\nthe beginning of the epoch (OS dependent begin time)\n\nref -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (1, 2, 3).
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate:
:returns float value:
\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, data_rate=10000):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.LQProc", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "LQProc", "kind": "function", "doc": "Process to spawn that continuously collects from the LabQuests(s)
\n\nParameters
\n\ncmdrcv: Pipe\n Where commands are received.
\n\ndatasend: Pipe\n Where data is sent in response to a command.
\n", "signature": "(cmdrcv, datasend, starttime, samples):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings", "modulename": "jupyterpidaq.ChannelSettings", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings", "kind": "class", "doc": "This class takes care of interacting with the user to get settings for data\ncollection on each channel. Should be initialized with an idno, so that\nit knows what number has been assigned to it.
\n"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.__init__", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.__init__", "kind": "function", "doc": "Parameters
\n\n\n
\n", "signature": "(idno, availboards)"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.activate", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.activate", "kind": "function", "doc": "- idno: int number iding this instance of ChannelSettings
\nThis function makes this channel active. No return value unless an e\nrror is thrown by something called by this function.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.deactivate", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.deactivate", "kind": "function", "doc": "None
\nThis function makes the channel inactive. No return value unless an\nerror is thrown by something called by this function.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.checkchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.checkchanged", "kind": "function", "doc": "None
\nThis function is called when the checkbox changes.
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n\n\n\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.boardchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.boardchanged", "kind": "function", "doc": "None
\nThis function responds to a change in board choice.
\n\nParameters
\n\n\n
\n\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.channelchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.channelchanged", "kind": "function", "doc": "This function responds to a change in board choice.
\n\nParameters
\n\n\n
\n\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.sensorchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.sensorchanged", "kind": "function", "doc": "Called by the observe function of sensorchoice when the user changes\nthe sensor choice.
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n\n\n\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.unitschanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.unitschanged", "kind": "function", "doc": "None
\nCalled by the observe function for the units selector when units are\nchanged
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.gainschanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.gainschanged", "kind": "function", "doc": "Called by the observe function for the gains selector when the gain is\nchanged.
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.setup", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.setup", "kind": "function", "doc": "Sets up the GUI and the necessary monitoring.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.hideGUI", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.hideGUI", "kind": "function", "doc": "\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQProc", "modulename": "jupyterpidaq.DAQProc", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.DAQProc.DAQProc", "modulename": "jupyterpidaq.DAQProc", "qualname": "DAQProc", "kind": "function", "doc": "None
\nThis function is to be run in a separate thread to asynchronously\ncommunicate with the ADC board.
\n\nParameters
\n\n\n
\n\n- \n
list whichchn: a list of dictionaries. Each dictionary is of the\nform:{'board': board_object, 'chnl': chnlID}.
- \n
list gains: a list of the numerical gain for each channel.
- \n
float avgtime: the averaging time in seconds for a data point.
- \n
float timedelta: the target time between data points.
- \n
pipe DAQconn: the connection pipe
- \n
pipe DAQCTL: the control pipe
Returns
\n\n\n\n", "signature": "(whichchn, gains, avgtime, timedelta, DAQconn, DAQCTL):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance", "modulename": "jupyterpidaq.DAQinstance", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance", "kind": "class", "doc": "\n"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.__init__", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.__init__", "kind": "function", "doc": "Data is returned via the pipes.\n On the DAQCTL pipe this only returns 'done'\n On the DAQconn pipe a list of lists with data is returned.
\nData Aquistion Instance (a run).
\n\nParameters
\n\n\n
\n", "signature": "(idno, title='None', ntraces=4, **kwargs)"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.setupclick", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.setupclick", "kind": "function", "doc": "\n", "signature": "(self, btn):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.setup", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.setup", "kind": "function", "doc": "\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.collectclick", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.collectclick", "kind": "function", "doc": "\n", "signature": "(self, btn):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.fillpandadf", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.fillpandadf", "kind": "function", "doc": "\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.updatingplot", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.updatingplot", "kind": "function", "doc": "- idno: id number you wish to use to keep track
\n- title: optional name
\n- ntraces: number of traces (default = 4) more than 4 easily\noverwhelms a pi4.
\n- kwargs: \n:ignore_skew: bool (default: True) if True only a single average\ncollection time will be recorded for each time in a multichannel\ndata collection. If False a separate set of time will be\nrecorded for each channel.
\nRuns until a check of self.collectbtn.description does not return\n'Stop Collecting'. This would probably be more efficient if set a\nboolean.
\n\nParameters
\n\nPLTconn: Pipe\n connection plotter end\nDAQconn: Pipe\n connection DAQ end\nPLTCTL: Pipe\n control pipe plotter end\nDAQCTL: Pipe\n control pipe DAQ end
\n", "signature": "(self, PLTconn, PLTCTL):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.Run", "modulename": "jupyterpidaq.DAQinstance", "qualname": "Run", "kind": "function", "doc": "Load a run from stored data or start a new run if the local file for\nthe run does not exist.
\n\nParameters
\n\nname: str\n String name for the run. The data will be stored in a file of this\n name with the extension of
\n", "signature": "(name):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.doRun", "modulename": "jupyterpidaq.DAQinstance", "qualname": "doRun", "kind": "function", "doc": "\n", "signature": "(whichrun):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.update_runsdrp", "modulename": "jupyterpidaq.DAQinstance", "qualname": "update_runsdrp", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.showSelectedRunTable", "modulename": "jupyterpidaq.DAQinstance", "qualname": "showSelectedRunTable", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.showDataTable", "modulename": "jupyterpidaq.DAQinstance", "qualname": "showDataTable", "kind": "function", "doc": ".jpidaq.html
.Provides a menu to select which run. Then displays the run in a\n10 em high scrolling table. Selection menu is removed after choice\nis made.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.newCalculatedColumn", "modulename": "jupyterpidaq.DAQinstance", "qualname": "newCalculatedColumn", "kind": "function", "doc": "Uses jupyter-pandas-GUI.new_pandas_column_GUI to provide a GUI expression\ncomposer. This method finds the datasets and launches the GUI.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.newPlot", "modulename": "jupyterpidaq.DAQinstance", "qualname": "newPlot", "kind": "function", "doc": "Uses jupyter-pandas-GUI.plot_pandas_GUI to provide a GUI expression\ncomposer. This method finds the datasets and launches the GUI.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.newFit", "modulename": "jupyterpidaq.DAQinstance", "qualname": "newFit", "kind": "function", "doc": "Uses jupyter-pandas-GUI.fit_pandas_GUI to provide a GUI expression\ncomposer. This method finds the datasets and launches the GUI.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors", "modulename": "jupyterpidaq.Sensors", "kind": "module", "doc": "This module wraps all the modules related to interpretting data from known\nsensors.
\n"}, {"fullname": "jupyterpidaq.Sensors.sensors", "modulename": "jupyterpidaq.Sensors.sensors", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Sensors.sensors.to_reasonable_significant_figures", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "to_reasonable_significant_figures", "kind": "function", "doc": "This function will return value rounded to a reasonable number of\nsignificant figures based on the uncertainty. If you are doing this\nbased on the standard return from the raw voltage or the sensor\ndefinitions in this file it is recommend that this be the standard\ndeviation of the average, which will often provide about one more digit\nthan the standard deviation. This will provide a guard digit for further\ncomputations.
\n\nParameters
\n\n\n
\n\n- float value: the value to be rounded
\n- float uncertainty: the uncertainty.
\n:returns float:
\n\nReturns: rounded_value a floating point number.
\n", "signature": "(value, uncertainty):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.to_reasonable_significant_figures_fast", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "to_reasonable_significant_figures_fast", "kind": "function", "doc": "This function will return values rounded to a reasonable number of\nsignificant figures based on the avg_std. This function requires fewer\ncompares so is a little more efficient than calling\nto_reasonable_significant_figures(value, uncertainty) for avg, std,\navg_std separately.
\n\nParameters
\n\n\n
\n\n- float avg: the average value
\n- float std: the standard deviation
\n- float avg_std: the estimated standard deviation in avg\n:returns list:
\nReturns: list of rounded values for each [avg, std, avg_std]
\n", "signature": "(avg, std, avg_std):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.listSensors", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "listSensors", "kind": "function", "doc": "Provides a list of the sensor classes provided by this file. The list must\nbe manually updated with each new class.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD", "kind": "class", "doc": "list of classnames
\nThis is the base sensor class which all sensors should extend. See how to\ndo this properly using one of the examples below.\nThis class contains definitions for the raw AtoD return in volts. The\ndigital values are not used as the AtoD may have a builtin pre-amp,\nso a given digital value has different meanings depending upon the pre-amp\nsetting.
\n"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.getname", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.getname", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nProvides a string name for the sensor
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.getvendor", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.getvendor", "kind": "function", "doc": "string containing the sensor name
\nProvides a string name for the sensor vendor/manufacturer
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.getunits", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.getunits", "kind": "function", "doc": "string containing the vendor/manufacturer name
\nProvides the string names for the available units for this sensor.\nThese string names are also the functions within this class that\nreturn the measurement in those units.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.V", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.V", "kind": "function", "doc": "units a list of strings.
\nIt is not really necessary to call this function because it just\nreturns the same values that are passed to it.\nIt is provided for consistency with the way sensors units are defined.
\n\nParameters
\n\n\n
\n\n- v_avg: v_avg: average voltage from A-to-D
\n- v_std: standard deviation of the A-to-D measurements
\n- avg_std: estimate of the standard deviation of v_avg
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.mV", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.mV", "kind": "function", "doc": "[v_avg, v_std, avg_std]
\nConvert the raw AtoD voltage to mV.
\n\nParameters
\n\n\n
\n\n- v_avg: v_avg: average voltage from A-to-D
\n- v_std: standard deviation of the A-to-D measurements
\n- avg_std: estimate of the standard deviation of v_avg
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor", "kind": "class", "doc": "[v_avg, v_std, avg_std] converted to mV
\nThis class contains the definitions for builtin thermistor.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.K", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.K", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nThe returned values are in K. It is assumed that the distribution is\nsymmetric guassian even in K. This may not be true, but still gives\na reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- v_avg: average voltage from sensor.
\n- v_std: standard deviation of voltage from sensor.
\n- avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: list [K_avg, K_std, K_avg_std]\n [average temperature in K,\n standard deviation of temperature in K,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.C", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.C", "kind": "function", "doc": "The returned values are in deg C. It is assumed that the distribution\nis symmetric guassian even in deg C. This may not be true, but still\ngives a reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- v_avg: average voltage from sensor.
\n- v_std: standard deviation of voltage from sensor.
\n- avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: list [C_avg, C_std, C_avg_std]\n [average temperature in C, standard deviation of temperature in C,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.F", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.F", "kind": "function", "doc": "The returned values are in deg F. It is assumed that the distribution\nis symmetric guassian even in deg F. This may not be true, but still\ngives a reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.\n:returns list:
\nReturns: list [F_avg, F_std, F_avg_std]\n [average temperature in F, standard deviation of temperature in F,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp", "kind": "class", "doc": "This class contains the definitions for Vernier Stainless Steel Temperature\nProbe. A 20K thermistor.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.K", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.K", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nThe returned values are in K. It is assumed that the distribution is\nsymmetric guassian even in K. This may not be true, but still gives\na reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.\n:returns list:
\nReturns list [K_avg, K_std, K_avg_std]\n [average temperature in K, standard deviation of temperature in K,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.C", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.C", "kind": "function", "doc": "The returned values are in deg C. It is assumed that the distribution\nis symmetric guassian even in deg C. This may not be true, but still\ngives a reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: C_avg, C_std, C_avg_std\n average temperature in C, standard deviation of temperature in C,\n estimated standard deviation of the average temperature.
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.F", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.F", "kind": "function", "doc": "The returned values are in deg F. It is assumed that the\ndistribution is symmetric guassian even in deg F. This may not be\ntrue, but still gives a reasonable estimate of the standard\ndeviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: F_avg, F_std, F_avg_std\n average temperature in F, standard deviation of\n temperature in F, estimated standard deviation of the average\n temperature.
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP", "kind": "class", "doc": "This class contains the definitions for Vernier absolute gas pressure\nsensor, GPS-BTA (post 2011 manufacture).
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.Pa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.Pa", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Pascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.kPa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.kPa", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in kiloPascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.Bar", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.Bar", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Bars
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.Torr", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.Torr", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Torr
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.mmHg", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.mmHg", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in mmHg
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.atm", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.atm", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in atm
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD", "kind": "class", "doc": "This class contains the definitions for Vernier absolute gas pressure\nsensor, GPS-BTA (pre 2011 manufacture. Label does not depict a caliper\nwith the registered trademark symbol).
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.Pa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.Pa", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Pascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.kPa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.kPa", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in kiloPascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.Bar", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.Bar", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Bars
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.Torr", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.Torr", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Torr
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.mmHg", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.mmHg", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in mmHg
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.atm", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.atm", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in atm
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierpH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierpH", "kind": "class", "doc": "This class contains the definitions for Vernier standard pH\nsensor, PH-BTA.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierpH.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierpH.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierpH.pH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierpH.pH", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: pH_avg, pH_std, pH_avg_std all in pH units
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierFlatpH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierFlatpH", "kind": "class", "doc": "This class contains the definitions for Vernier flat tris-compatible pH\nsensor, FPH-BTA.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierFlatpH.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierFlatpH.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierFlatpH.pH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierFlatpH.pH", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: pH_avg, pH_std, pH_avg_std all in pH units
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}]; + /** pdoc search index */const docs = [{"fullname": "jupyterpidaq", "modulename": "jupyterpidaq", "kind": "module", "doc": "User Guide
\n\nIntroduction | \nUsage
\n\nIntroduction
\n\nThis software allows GUI (Graphical User Interface) driven live collection, \nplotting and analysis of digitized data inside a Jupyter notebook using the \nfollowing A-to-D interfaces:
\n\non a Raspberry Pi:
\n\n\n
\n\n- Adafruit compliant ADS1115 boards \n(example,\nalso available from other vendors);
\n- The π-Plates DAQC2 plate.
\non MacOS and Windows:
\n\n\n
\n\n- Vernier LabQuest USB A-to-Ds.
\ndemo mode on anything Jupyter runs on
\n\n\n
\n\n- A demo mode will run on any computer with a Jupyter notebook install and\nPython 3.6+. Example notebooks can be found in the \"usage_examples\" folder.
\nUsage
\n\nLaunch the software | \nInitialize data acquisiton tools | \nCollect data |\nDisplaying a Data Table | \nPlotting data | \nAnalyzing data
\n\nStarting JupyterPiDAQ
\n\nA working Jupyter notebook or Jupyter lab installation with JupyterPiDAQ \ninstalled is required. If you need to install the software see the Installation \nInstructions. There are two common ways this may be set \nup, that lead to slightly different steps for starting the software:
\n\n\n
\n\n- A special kernel may be set up that can be used in any Jupyter notebook \ninstall for the current user (see the very end of the\nInstallation Instructions). \n
\n\n
- In this case launch\nJupyter, in whichever directory you want to work, using the \ncommand:
\njupyter nbclassic
(for the old notebook interface) orjupyter \nlab
(for the newer lab interface).- Open a new notebook and choose the kernel \nfor
\nJupyterPiDAQ
. The kernel name will depend upon what was chosen \nduring installation.- Only for use within the directory structure of the virtual environment \nthat was set up for the software. \n
\n\n
- In this case you must navigate to the \ndirectory of the virtual environment using the
\ncd
command before \nstarting the software.- Then enter the virtual environment with the command
\npipenv shell
. \nThis assumes you set uppipenv
as described in the \nInstallation instructions.- Launch Jupyter using the command:
\njupyter nbclassic
(for the old \nnotebook interface) orjupyter lab
(for the newer lab interface).- Open a new python notebook.
\nInitialize the Data Acquisition Tools
\n\nInitialize the data acquisition tools by putting the statement
\n\nfrom \njupyterpidaq.DAQinstance import *
into the first cell and clicking on the \n'Run' button. The package loads supporting packages (numpy, pandas, plotly,\netc...) and searches for compatible hardware. On a Raspberry Pi this takes a\nnumber of seconds. If no compatible A-to-D boards are found, demo mode is used.\nIn demo mode the A-to-D board is simulated by a random number generator.When setup is done a new menu appears at the end of the menubar (figure 1).
\n\n\n\nFigure 1: The menu created once the data acquisition software is \ninitialized. Currently NOT available in Jupyter Lab.
\n\nThe menu options insert jupyter widget based GUIs for starting a run,\ndisplaying the data as tables or plots, composing an expression to calculate\na new column in a DataFrame, or fitting data.
\n\nCollecting data
\n\nUsing the Menu
\n\nFrom the \"DAQ Commands\" menu select \"Insert New Run After Selection...\" or \n\"Append New Run to End...\". The first will insert the code to set up \ndata collection for a run in the cell below the currently selected cell. \nThe second will append this to the end of the notebook. When the cell is \nrun it will generate \na GUI that looks like the figure 2, below. Fill in the information to define \nwhat you wish to do (see below figure 2 for more details).
\n\nUsing a Command
\n\nIn the cell you wish to collect the data enter the command \n
\n\n\n\nRun(\"desired_dataset_name\")
, where you replace desired_dataset_name with the \nstring you want for this run. Replacing spaces with _ will prevent issues, \nespecially on Windows. After entering the command, run the cell. This will \ngenerate the GUI shown in figure 2.Figure 2: Image of the GUI for setting up a data collection run.
\n\n\n
\n\n- Give the run a title/name using the first textbox.
\n- You can collect up to four (4) data traces at once. Two different data \ntraces can display the same analog-to-digital channel, but in different \nunits (e.g. you could record both the raw voltage and temperature from a \nthermistor). Each trace is activated by selecting its checkbox.
\n- Once a trace is activated you can give it a title and must select: the \ndata acquisition board, channel, sensor, units and gain from the \navailable drop-down menus.
\n- Once all your traces are set up decide whether they should be displayed in \nmultiple stacked graphs or all on the same graph. Uncheck the box to \ndisplay all on one graph.
\n- Select the data collection rate (20 Hz is currently the maximum rate, but \non a Raspberry Pi you may not be able to sustain more than 5 Hz).
\n- When everything is set the way you wish, click on the \"Set Parameters\" \nbutton. The collection parameters will be displayed and a button to \nstart the data collection will appear. You may have to scroll back up to \nthe display as Jupyter sometimes jumps too far down when a cell is updated.
\n- The \"start\" button will convert to a \"stop\" button once data collection \nis started. The data graph(s) will update at roughly 1 Hz, so you can \nmonitor the progress of the data collection.
\n- Click the \"stop\" button to end data collection. It can take \na while to stop if the data collection has got ahead of the graphic \ndisplay of the data.
\n- Once collection is stopped you will see a plot or plots of the completed \ndata collection and the name of the .html file the raw data has been \nbacked up to.
\n- Should you accidentally clear the output of a completed collection cell,\nrerunning it will regenerate the display as long as you have not moved \nthe raw data backup file.
\nDisplaying data
\n\nIn a table
\n\nSelecting the \"Show data in table...\" option in the \"DAQ Command\" menu will \ninsert a cell immediately below the currently selected cell displaying a \nwidget in which you can select which data set to display. The command \nequivalent is
\n\nshowDataTable()
.Plotting data
\n\nSelecting the \"Insert new plot after selection...\" option in the menu will\ninsert two cells immediately below the currently selected cell. The first cell\nwill be used to generate a GUI to lead you through creation of the code to\ngenerate the plot. The second cell is where the plot creation code is \ngenerated. The first tab of this GUI looks like figure 3. The command \nequivalent is
\n\n\n\nnewPlot()
.Figure 3: Image of the first tab in the four tab (4 step) Pandas Plot \nComposer. More information in the Pandas_GUI\ndocumentation.
\n\nIt is best to do the tabs in order. The notices in red will try to \nwarn you of errors or oversights. The \"Instructions\" accordian can be \nexpanded to get more specific information about how to use each tab.
\n\nYou can get more sophisticated control of \nyour plot by editing the code produced by this GUI. See the Plotly \nFigureWidget Instructions and the \nexample Jupyter notebooks referenced there for more information.
\n\nThe GUI destroys itself once you complete step 4.
\n\nAnalyzing data
\n\nCalculating a new column
\n\nSelecting \"Calculate new column...\" from the menu will add two cells\nimmediately below the selected cell. The first cell will create the GUI to\nlead you through creation of the code to calculate the new column. The second\ncell is where the code is built. The first tab of the GUI looks like \nfigure 4. The command equivalent is
\n\n\n\nnewCalculatedColumn()
.Figure 4: Image of the first tab in the four tab (4 step) Pandas New \nCalculated Column Composer. More information in the Pandas_GUI\ndocumentation.
\n\nDo the tabs in order. You can perform more complex manipulations than built \ninto the GUI by editing the code generated by this GUI.
\n\nThe GUI destroys itself once you complete step 4.
\n\nFitting data
\n\nA GUI for defining simple fits (linear, polynomial, exponential decay, sine \nand Gaussian) can be launched by selecting \"Insert new Fit after selection..\n.\" from the menu. This will create the GUI to lead you through selecting \nand fitting the data. The code is created in the cell immediately below the \nGUI. The command equivalent is
\n\n\n\nnewFit()
.Figure 5: Image of the first tab in the Pandas Fit Composer.\nMore information in the Pandas_GUI\ndocumentation.
\n\nInstallation
\n\nInitial setup: On Raspberry Pi | \nOn non-Pi Systems
\n\n\n\nRaspberry Pi Initial Setup
\n\nUnless you only want to run in Demo mode make sure you have one of the \ncompatible interface boards installed. The current options are:
\n\n\n
\n\n- Adafruit compliant ADS1115 boards \n(example,\nalso available from other vendors);
\n- The π-Plates DAQC2 plate.
\n- If you wish to use different interfaces see the Development\nNotes\n and the
\nBoards
subpackage ofjupyterpidaq
for examples and \n information on how to define the code interface for a board.OS specific: Ubuntu on Pi | \nRaspberrian on Pi |\nMacOS | Windows
\n\nUbuntu on Pi
\n\nBy default in Ubuntu 20.04 for Pis the gpio and spi groups do not exist.\nThe i2c group does (not always).
\n\n\n
\n\n- Make sure that the following packages are installed
\nrpi.gpio-common \npython3-pigpio python3-gpiozero python3-rpi.gpio
.- You can avoid having to create a gpio group, by assigning users who need\n gpio access to the dialout group. Check that /dev/gpiomem is part of that \ngroup and that the dialout group has rw access. If not you will need to set\n it.
\n- Users also need to be members of the i2c group. If it does not exist create \n it and then make that the group for /dev/i2c-1 with group rw permissions. \nTHIS MAY NOT BE NECESSARY.
\n- The spi group needs to be created (addgroup?).
\n- Additionally the spi group needs to be given rw access to the spi devices\nat each boot. To do this create a one line rule in a file named \n
\n/etc/udev/rules.d/50-spidev.rules
containingSUBSYSTEM==\"spidev\", \nGROUP=\"spi\", MODE=\"0660\"
. The file should have rw permission for root \nand read permission for everyone else.- Make sure you have pip installed for \npython 3:
\npython3 -m pip --version
orpip3 --version
. If you do not, \ninstall usingapt \ninstall python3-pip
.Raspberrian on Pi
\n\n(TBD)
\n\nNon-Pi based System Initial Setup
\n\nMake sure that Python >=3.6 is installed:
\n\npython3 -v
. If not follow \ninstructions at python.org. This software should run \non any computer capable of supporting the necessary version of Python. \nHowevever, it will only run in demo mode if the computer does not support \none of the compatible A-to-D boards.Generic Linux
\n\n\n
\n\n- If your system hardware \nhas GPIO pins and a GPIO interface board, you should try following the \ninstructions for a Pi based system above. If \nyou figure out how to make this work on other SBCs or systems with GPIO, \nplease submit a pull request updating these instructions.
\n- If your system hardware does not support GPIO and one of the compatible \ninterface boards, the software will run in demo mode.
\nNOTE: If a binary distribution (whl or wheel) is not available for your\nplatform, some of the required packages may need to be compiled. If you get\ncompilation errors when installing try getting the python header and \ndevelopment files for your platform. To get them on most *nix platforms use the\ncommand
\n\nsudo apt install python3-dev
.MacOS
\n\nCurrently, the LabQuest A-to-Ds are only working on intel based macs. When \nVernier recompiles their interface communication library for the M1 series \ncpus this will change.
\n\n\n
\n\n- Install the latest version of Python, by following the instructions on \nthe Python website.
\n- Make sure a virtual environment tool such as
\npipenv
is installed. In a \nterminal window trypython -m pip install --user pipenv
.Windows
\n\nNote: LoggerPro software may need to be \ninstalled because that provides the compiled
\n\n.dll
necessary to communicate \nwith the LabQuest interface. In theory will work without this.\n
\n\n- Install the latest version of Python, by following the instructions on \nthe Python website. WARNING: Do Not use \nWindows automatic installation. It may work on a plain vanilla system \nwith one user, but in multiuser systems it badly messes up the ability to \nuse virtual environments.
\n- Make sure a virtual environment tool such as
\npipenv
is installed. In a \nterminal window trypython -m pip install --user pipenv
.- You may have to set or add to your user
\nPATH
environment variable. See \nthe warnings generated during the installation. Then search for the \nlatest instructions on how to setPATH
.Final Set Up
\n\n\n
\n\n- If on Raspberry Pi type system, make sure the user you will be running the \nsoftware under is a member of the groups
\ndialout
,spi
and if it \nexistsi2c
.- It is recommended that you install JupyterPiDAQ in its own \nvirtual environment.\nThe instructions below do just that using the original author's favorite \nvirtual environment tool pipenv.
\nLog into your chosen user account:
\n\n\n
\n\n- Install pipenv:
\npip3 install \n--user pipenv
. You may\nneed to add~/.local/bin
to yourPATH
to makepipenv
\navailable in your command shell. More discussion: \nThe Hitchhiker's Guide to\nPython.- Create a directory for the virtual environment you will be installing\ninto (example:
\nmkdir JupyterPiDAQ
).- Navigate into the directory
\ncd JupyterPiDAQ
.- Create the virtual environment and enter it
\npipenv shell
. To get out of\nthe environment you can issue theexit
command on the command line.- While still in the shell install the latest JupyterPiDAQ and all its\nrequirements\n
\npip install -U JupyterPiDAQ
. This can take a long time, especially on a\n Raspberry Pi. On a Pi 3B+ (minimum requirement) it will probably not run\n without at least 1 GB of swap. See: Build Jupyter on a Pi\n for a discussion of adding swap space on a Pi.- Still within the environment shell test\nthis by starting jupyter
\njupyter notebook
orjupyter lab
. Jupyter should \nlaunch in your browser.\n\n
- Open a new notebook using the default (Python 3) kernel.
\n- In the first cell import all from DAQinstance.py: \n
\nfrom jupyterpidaq.DAQinstance import *
.\n When run in jupyter notebook this cell should load the DAQmenu at the \n end of the Jupyter notebook menu/icon bar. Currently, no convenience \n menu is available in Jupyter lab. If you do not have an appropriate\n A-to-D board installed you will get a message and the software\n will default to demo mode, substituting a random number\n generator for the A-to-D.- If you wish, you can make this environment available to an alternate Jupyter\ninstall as a special kernel when you are the user.\n
\n\n
- Make sure you are running in your virtual environment
\npipenv shell
\nin the directory for virtual environment will do that.- Issue the command to add this as a kernel to your personal space: \n
\npython -m ipykernel install --user --name=<name-you-want-for-kernel>
.- More information is available in the Jupyter/IPython documentation. \nA simple tutorial from Nikolai Jankiev (_Parametric Thoughts_) can be\nfound here.
\nDevelopment Notes
\n\nCode Repository
\n\nSetting up Development Environment
\n\nBasic requirements: Python 3.6+, associated\npip and a Jupyter notebook.\nSee: python.org and\nJupyter.org.
\n\n\n
\n\n- If not installed, install pipenv:
\npip3 install --user pipenv
. You may\nneed to add~/.local/bin
to yourPATH
to makepipenv
\navailable in your command shell. More discussion: \nThe Hitchhiker's Guide to Python.- Navigate to the directory where this package will be\nor has been downloaded to. Use
\npipenv
to install an \n\"editable\" package \ninside the directory as described below:\n\n
- Start a shell in the environment
\npipenv shell
.- Install using pip.\n
\n\n
- If you downloaded the git repository named \"JupyterPiDAQ\"\nand have used that directory to build your virtual\nenvironment:
\npip install -e ../JupyterPiDAQ/
.- If you are downloading from PyPi\n
\npip install -e JupyterPiDAQ
- Either should install all the additional packages this\npackage depends upon. On a Raspberry Pi this will take\na long time. It probably will not run without at least 1 GB of swap. See: \nBuild Jupyter on a Pi\n.
\n- Still within the environment shell test this by starting jupyter \n
\njupyter nbclassic
orjupyter lab
. Jupyter should launch in your \nbrowser.\n\n
- Open a new notebook using the default (Python 3) kernel.
\n- In the first cell import all from DAQinstance.py: \n
\nfrom jupyterpidaq.DAQinstance import *
.\nWhen run this cell should load the DAQmenu at the end of the\nJupyter notebook menu/icon bar. If you do not have an appropriate A-to-D\nboard installed you will get a message and the software\nwill default to demo mode, substituting a random number\ngenerator for the A-to-D. Because of the demo mode it is\npossible to run this on any computer, not just a Pi.- If you wish, you can make this environment available to an alternate Jupyter\ninstall as a special kernel when you are the user.\n
\n\n
- Make sure you are running in your virtual environment
\npipenv shell
\nin the directory for virtual environment will do that.- Issue the command to add this as a kernel to your personal space: \n
\npython -m ipykernel install --user --name=<name-you-want-for-kernel>
.- More information is available in the Jupyter/Ipython documentation. \nA simple tutorial from Nikolai Jankiev (_Parametric Thoughts_) can be\nfound here.
\nAdding New Sensor Code
\n\n\n
\n\n- Copy an existing sensor class paste it into the end of\nsensors.py and rename it.
\n- Update/delete functions for each valid unit within the new\nclass as necessary.
\n- Update the sensor name, vendor and available units in the\n
\n__init__
function.- Add the new sensor classname to the list of available sensors\nin
\nlistSensors
at about line 120 of sensors.py.- Add the new sensor classname to
\ngetsensors
of ADCsim.py,\nADCsim_line.py and any board (e.g. DAQC2.py) with which the sensor\ncan be used. Do not guess if a sensor works with a particular\nboard. Test it!Running Tests
\n\n\n
\n\n- Install updated pytest in the virtual environment:\n
\npipenv shell\npip install -U pytest\n
- Run tests ignoring the manual tests in the
\ndev_testing
directory:\npython -m pytest --ignore='dev_testing'
.Building Documentation
\n\n\n
\n\n- Install or update pdoc into the virtual environment
\npip install -U pdoc
.- Make edits to the
\n.md
files within the docs folder that are to be \nincluded in the first page (see__init__.py
of the jupyterpidaq package).- At the root level run
\npdoc \n--logo https://jupyterphysscilab.github.io/JupyterPiDAQ/JupyterPiDAQ-logo.svg --logo-link \nhttps://jupyterphysscilab.github.io/JupyterPiDAQ/ --footer-text \n\"JupyterPiDAQ vX.X.X\" -html -o docs jupyterpidaq
Unless you are on a \nRaspbery Pi this will throw an error aboutimport
. Just ignore.Building PyPi package
\n\n\n
\n\n- Make sure to update the version number in setup.py first.
\n- Install updated setuptools and twine in the virtual environment:\n
\npipenv shell\npip install -U setuptools wheel twine\n
- Build the distribution
\npython -m setup sdist bdist_wheel
.- Test it on
\ntest.pypi.org
.\n\n
- Upload it (you will need an account on test.pypi.org):\n
\npython -m twine upload --repository testpypi dist/*
.- Create a new virtual environment and test install into it:\n
\n\nThere are often install issues because sometimes only older versions of\nsome of the required packages are available on test.pypi.org. If this\nis the only problem change the version to end inexit # to get out of the current environment\ncd <somewhere>\nmkdir <new virtual environment>\ncd <new directory>\npipenv shell #creates the new environment and enters it.\npip install -i https://test.pypi.org/..... # copy actual link from the\n # repository on test.pypi.\n
rc0
for release\ncandidate and try it on the regular pypi.org as described below for\nreleasing on PyPi.- After install test by running a jupyter notebook in the virtual \nenvironment.
\nReleasing on PyPi
\n\nProceed only if testing of the build is successful.
\n\n\n
\n\n- Double check the version number in setup.py.
\n- Rebuild the release:
\npython -m setup sdist bdist_wheel
.- Upload it:
\npython -m twine upload dist/*
- Make sure it works by installing it in a clean virtual environment. This\nis the same as on test.pypi.org except without
\n-i https://test.pypy...
. If\nit does not work, pull the release.Change Log
\n\n\n
\n\n- 0.8.1 (May 2, 2023)\n
\n\n
- BUG FIX: Now always waits for all data to be transferred to plot before \nwriting backup to a file.
\n- More rapid update of display when using LabQuests.
\n- Docs now recommend launching
\njupyter nbclassic
for old notebook interface.- 0.8.0 (Apr. 20, 2023)\n
\n\n
- Replaced
\nNewRun()
command withRun()
command. This version works in \nJupyter Lab and removes the need for theDisplayRun()
command because \nRun()
will load an already collected dataset or start a new one.- Now, when multiple traces are assigned to the same channel of a board the \nchannel is only read one time. If the units are different the two \ntraces will be displayed with different units.
\n- Can read data from Vernier LabQuest USB \nanalog-to-digital interfaces. Potential data rate is 10 kHz, currently \nlimited to 20 Hz.
\n- Runs in Jupyter Lab (no menus yet) and Notebook \n(menus still work).
\n- Updated requirements to include jupyterlab and labquest packages.
\n- 0.7.9 (Mar. 9 2023)\n
\n\n
- Added
\nspidev
package to requirements becausepi-plates
requires it.- More robust exception handling when searching for boards/A-to-Ds.
\n- 0.7.8\n
\n\n
- Updated text for insertion into cells to make better use of escaping \nupdates in JPSLUtils >=0.7.0.
\n- Removed some unnecessary print statements.
\n- 0.7.7\n
\n\n
- Updated requirements for upstream security fixes.
\n- Conversion to pandas dataframe now works when trace 0 is not collected.
\n- DAQ menu no longer created in trusted notebooks if the data acquisition \ntools have not been initialized since the notebook was opened.
\n- Reworked the data collection so that opening an old notebook without \nrunning anything will not have any leftover inoperable or undefined \nwidgets.
\n- Reordered the live trace display to match the order of the names at right.
\n- Runs now saved to a human readable html file that includes the run \nconditions.
\n- As long as this html file is in the same directory as the notebook, the \nrun display can be recreated by running its cell after accidentally \nclearing the cell output.
\n- The cell displaying the results of a run is now protected against \ndeletion and editing.
\n- 0.7.6\n
\n\n
- Converted to fancy menus (could make hierarchical).
\n- 0.7.5\n
\n\n
- Added fitting to DAQ command menu.
\n- Documentation Enhancements: github.io website; first pass as API docs; \nreorganized documentation; MyBinder link now forces launch in classic \nnotebook; added plans for adapter board to connect Vernier Sensors.
\n- 0.7.4.1\n
\n\n
- Improved layout of data collection.
\n- Better widget cleanup.
\n- Readme fixes.
\n- 0.7.3 Pip install reliability fixes.
\n- 0.7.2 Suppress Javascript error when not in JLab.
\n- 0.7.1\n
\n\n
- Include Heat Capacity Lab example.
\n- Make menu show up in JLab (still not functional).
\n- Remove matplotlib baggage.
\n- 0.7.0\n
\n\n
- Switched to plotly widget for plotting.
\n- Added Vernier pressure sensor calibrations (old and new).
\n- Jupyter widgets based new calculated column GUI.
\n- Jupyter widgets based new plot GUI.
\n- Default to providing only one time for channels collected nearly \nsimultaneously.
\n- As reported values are averages, switched to reporting the estimated \nstandard deviation of the average rather than the deviation of all the \nreadings used to create the average.
\n- 0.6.0 \n
\n\n
- Initial release.
\n- Live data collection.
\n- Recognized sensors: ADS1115 boards (voltage, built-in thermistor, \nVernier SS temperature probe), DAQC2 boards (voltage,Vernier SS \ntemperature probe, Vernier standard pH probe, Vernier flat pH probe).
\nThree Channel Adapter Board for Vernier Sensors
\n\nBoard plans
\n\n\n\nEtching the board
\n\nClean Cu cladding to be etched by wet sanding with 1500 grit or finer.\nDraw traces with a black sharpie \u201cindustrial super permanent ink\u201d version\nworks best. Allow to dry completely (no odor). Can be speeded up using a heat\ngun.
\n\nEtchant recipe:
\n\n3 M HCl
\n\nCuCl2 to make medium emerald green solution (can also be made by \ndissolving Cu after adding hydrogen peroxide)
\n\nUsing test piece add 30% H2O2 dropwise to get gentle \nbubbling and \ncomplete\nremoval in 3 \u2013 5 min (longer gives poorly defined edges).
\n"}, {"fullname": "jupyterpidaq.Boards", "modulename": "jupyterpidaq.Boards", "kind": "module", "doc": "This module wraps all the submodules related to communication and control of\ndata acquisition boards.
\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO", "modulename": "jupyterpidaq.Boards.PiGPIO", "kind": "module", "doc": "This module contains the modules for all PiGPIO based boards.
\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.find_boards", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "find_boards", "kind": "function", "doc": "A routine like this must be implemented by all board packages.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115", "kind": "class", "doc": "list of ADS1115 board objects (maximum of 4 boards)
\nClass defining the properties of Adafruit compatible ADS1115\nanalog-to-digital boards for Raspberry-Pi style GPIO. Key characteristics:
\n\n\n
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.__init__", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.__init__", "kind": "function", "doc": "- 4 channels (0 - 3) with 16 bit resolution and a range of +/- 3.3 V
\n- Programmable gain on each channel of 2/3, 1, 2, 4, 8, 16 making these\ngood for small signals.
\n- a differential mode is available but not implemented in this class.
\nShould be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(adc)"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.getsensors", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.V_oversampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nV_min -- float, the minimum voltage read during\nthe interval\n\nV_max -- float, the maximum voltage read during the\ninterval\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nself.Vdd -- float, the reference voltage.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3)
- \n
gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),\n4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
- \n
int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,\n128,250, 475 or 860 Hz). Set to 475 Hz by default.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, V_min, V_max, time_stamp, self.Vdd
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nstdev -- float, the standard deviation of the measured values\nduring the averaging interval\n\nstdev_avg -- float, the estimated standard deviation of the\nreturned average\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nself.Vdd -- float, the reference voltage.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3)
- \n
gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),\n4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
- \n
int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,\n128,250, 475 or 860 Hz). Set to 475 Hz by default.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: VV_avg, stdev, stdev_avg, time_stamp, self.Vdd
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.ADS1115.Board_ADS1115.V_sampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.ADS1115", "qualname": "Board_ADS1115.V_sampchan", "kind": "function", "doc": "This routine returns the voltage for the
\n\nReturns a tuple of the following 3 objects:\n V -- float, the measured voltage
\n\n\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nself.Vdd -- float, the reference voltage.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3)
- \n
gain: 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V),\n4(+/-1.024V), 8 (+/-0.512V), 16 (+/-0.256V))
- \n
int data_rate: the ADC sample rate in Hz (8, 16, 32, 64,\n128,250, 475 or 860 Hz). Set to 475 Hz by default.
:returns: V, time_stamp, self.Vdd
\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.find_boards", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "find_boards", "kind": "function", "doc": "A rountine like this must be implemented by all board packages.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2", "kind": "class", "doc": "list of DAQC2 board objects (maximum of 8 boards)
\nClass defining the properties of the analog-to-digital block of the\npi-Plates DAQC2 board. Key characteristics:
\n\n\n
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.__init__", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.__init__", "kind": "function", "doc": "- 8 channels (0 - 7) with pseudo 16 bit resolution (oversampled 14 bit) and\na range of +/- 12 V.
\n- 1 channel (8) dedicated to monitoring Vdd.
\n- Programmable RGB LED to use as indicator.
\n- Other available facilities are Digital I/O, Digital-to-Analog and\n2-channel o-scope modes. These are not supported by this class.
\nShould be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(addr)"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.getsensors", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.V_oversampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at the default rate for the board and returns an\naverage and observed range.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nV_min -- float, the minimum voltage read during\nthe interval\n\nV_max -- float, the maximum voltage read during the\ninterval\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3, 4, 5, 6, 7,\n8). NOTE: channel 8 returns a measurement of Vdd.
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: ignored by board.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, V_min, V_max, time_stamp, Vdd_avg
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at the maximum rate for the board. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nstdev -- float, the standard deviation of the measured values\nduring the averaging interval\n\nstdev_avg -- float, the estimated standard deviation of the\nreturned average\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3, 4, 5, 6, 7,\n8). NOTE: channel 8 returns a measurement of Vdd.
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: ignored by board.
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.PiGPIO.DAQC2.Board_DAQC2.V_sampchan", "modulename": "jupyterpidaq.Boards.PiGPIO.DAQC2", "qualname": "Board_DAQC2.V_sampchan", "kind": "function", "doc": "This routine returns a single reading of the voltage for the channel.
\n\nReturns a tuple of the following 5 objects:\n V -- float, the measured voltage
\n\n\n\ntime_stamp -- float, the time of the measurement in seconds since\nthe beginning of the epoch (OS dependent begin time)\n\nref -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (0, 1, 2, 3, 4, 5, 6, 7,\n8). NOTE: channel 8 returns a measurement of Vdd.
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: ignored by board.
:returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated", "modulename": "jupyterpidaq.Boards.Simulated", "kind": "module", "doc": "This module wraps modules for simulated boards.
\n"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.find_boards", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "find_boards", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random", "kind": "class", "doc": "Base class for all boards. Each board should be an extension of this class.
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.__init__", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.__init__", "kind": "function", "doc": "Should be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(adc)"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.getsensors", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.V_oversampchan_stats", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475 or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be as close\n as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in seconds\n since the beginning of the epoch (OS dependent begin time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.V_oversampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.V_oversampchan", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475 or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be as close\n as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in seconds\n since the beginning of the epoch (OS dependent begin time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim.Board_ADCsim_random.V_sampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim", "qualname": "Board_ADCsim_random.V_sampchan", "kind": "function", "doc": "This function returns a single measurement and the time it was\ncollected.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.find_boards", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "find_boards", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line", "kind": "class", "doc": "a tuple consisting of V, time_stamp, where V = the single\n voltage measurement and time_stamp the time it was collected.
\nThis class simulates an Analog-to-Digital board that returns a linearly\nincreasing signal with a small amount of noise on the signal. The\nintercept and slope depend upon which hour of the day the simulation is\nrun.
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.__init__", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.__init__", "kind": "function", "doc": "Should be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(adc)"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.getsensors", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.V_oversampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475\n or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be\n as close as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in\n seconds since the beginning of the epoch (OS dependent begin\n time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475\n or 860 Hz)\n avg_sec seconds to average for, actual averaging interval will be\n as close as possible for an integer number of samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in\n seconds since the beginning of the epoch (OS dependent begin\n time).
\n", "signature": "(self, chan, gain, avg_sec, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.Simulated.ADCsim_line.Board_ADCsim_line.V_sampchan", "modulename": "jupyterpidaq.Boards.Simulated.ADCsim_line", "qualname": "Board_ADCsim_line.V_sampchan", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at (0.0012 + 1/data_rate)^-1 Hz for avg_sec\nnumber of seconds. The 0.0012 is the required loop time\non a RPI 3B+ in python3. The voltage is rounded to the number\nof decimals indicated by the standard deviation. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.\nParameters\n chan the channel number 0, 1, 2, 3\n gain 2/3 (+/-6.144V), 1(+/-4.096V), 2(+/-2.048V), 4(+/-1.024V),\n 8 (+/-0.512V), 16 (+/-0.256V)\n data_rate the ADC sample rate in Hz (8, 16, 32, 64, 128, 250, 475\n or 860 Hz) avg_sec seconds to average for, actual averaging\n interval will be as close as possible for an integer number of\n samples.\nReturns a tuple (V_avg, V_min, V_max, time_stamp)\n V_avg the averaged voltage\n stdev estimated standard deviation of the measurements\n stdev_avg estimated standard deviation of the mean\n time_stamp the time at halfway through the averaging interval in\n seconds since the beginning of the epoch (OS dependent begin\n time).
\n", "signature": "(self, chan, gain, data_rate=475):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards", "modulename": "jupyterpidaq.Boards.boards", "kind": "module", "doc": "This file handles loading adc board control software and sensor information.\nIt uses the list of known boards. It will skip boards that produce an error\neither because the pypi package is not installed or an error occurs when\ntrying to communicate with the board.
\n\nThe ADC simulator will be installed if no boards are available.
\n"}, {"fullname": "jupyterpidaq.Boards.boards.load_boards", "modulename": "jupyterpidaq.Boards.boards", "qualname": "load_boards", "kind": "function", "doc": "Uses the list of known board packages to search for available boards.\nThe file
\n\n.py should at minimum\nimplement a find_boards(): routine that overrides the function below and\ndefine a class for the particular board that extends the
Board` class\ndefined below.Returns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.find_boards", "modulename": "jupyterpidaq.Boards.boards", "qualname": "find_boards", "kind": "function", "doc": "list of adc board objects.
\nA function overriding this must be implemented by all board packages.\nSee examples in working packages. This is highly board dependent.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board", "kind": "class", "doc": "list of board objects
\nBase class for all boards. Each board should be an extension of this class.
\n"}, {"fullname": "jupyterpidaq.Boards.boards.Board.__init__", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.__init__", "kind": "function", "doc": "Should be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "()"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getname", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getname", "kind": "function", "doc": "Returns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getchannels", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getchannels", "kind": "function", "doc": "string value of the board name, a short label of board type.
\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getgains", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getgains", "kind": "function", "doc": "tuple of ids for available channels
\nIf not defined for a specific board the gain is fixed at 1.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getvendor", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getvendor", "kind": "function", "doc": "tuple of gains availabe for onboard preamp
\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getVdd", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getVdd", "kind": "function", "doc": "string value of the vendor name
\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.getsensors", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.getsensors", "kind": "function", "doc": "numerical value of the Vdd, voltage provided to sensors
\nThis returns a list of objects that allow the software to translate\nthe measured voltage into a sensor reading in appropriate units.\nMust be provided by the specific board implementation. See examples\nin working board packages.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.V_oversampchan", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.V_oversampchan", "kind": "function", "doc": "A list of valid sensor objects to use with this board. This\n should be a subset of all the sensors returned by the listSensors\n function in sensors.py.
\nThis function should return a tuple with average, minimum and maximum\nfor a channel averaged over the period of time avg_sec. How the\naveraging is performed will depend on the board.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\n- avg_sec: float period of time over which to average
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, avg_sec, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.V_oversampchan_stats", "kind": "function", "doc": "a tuple consisting of V_avg, V_min, V_max, time_stamp, avg_Vdd\n The time_stamp is the time the data was collected, usually the\n middle of the averaging period. avg_Vdd should be the measured\n average Vdd taken simultaneously, immediately before,\n or immediately after the voltage being measured. If the board or\n power supply is very stable self.Vdd can be returned instead.
\nThis function should return a tuple of statistical information for a\nchannel averaged over the period of time avg_sec.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\n- avg_sec: float period of time over which to average
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, avg_sec, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.boards.Board.V_sampchan", "modulename": "jupyterpidaq.Boards.boards", "qualname": "Board.V_sampchan", "kind": "function", "doc": "tuple consisting of V_avg, stdev, stdev_avg, time_stamp,\n avg_Vdd where stdev_avg is the estimated standard deviation\n of the average not the standard deviation of the values\n sampled (stdev). avg_Vdd should be the measured\n average Vdd taken simultaneously, immediately before,\n or immediately after the voltage being measured. If the board or\n power supply is very stable self.Vdd can be returned instead.
\nThis function returns a single measurement and the time it was\ncollected.
\n\nParameters
\n\n\n
\n\n- chan: id of the channel to be measured
\n- gain: gain of the channel if adjustable
\nReturns
\n\n\n\n", "signature": "(self, chan, gain, **kwargs):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier", "modulename": "jupyterpidaq.Boards.vernier", "kind": "module", "doc": "a tuple consisting of V, time_stamp, ref_Vdd, where V = the\n single voltage measurement and time_stamp the time it was\n collected. ref_Vdd should be the measured\n Vdd taken simultaneously, immediately before,\n or immediately after the voltage being measured. If the board or\n power supply is very stable self.Vdd can be returned instead.
\nThis module contains modules for the Vernier Interfaces.
\n"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest", "modulename": "jupyterpidaq.Boards.vernier.labquest", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.find_boards", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "find_boards", "kind": "function", "doc": "A rountine like this must be implemented by all board packages.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ", "kind": "class", "doc": "list of LabQuests (Types too?)
\nClass defining the properties of the analog-to-digital block of the\nLabQuests. Key characteristics:
\n\n\n
\n", "bases": "jupyterpidaq.Boards.boards.Board"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.__init__", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.__init__", "kind": "function", "doc": "- 3 channels (1, 2, 3) a range of +/- 10 V.
\n- 12 bit resolution
\n- Other available but not implemented facilities are Digital I/O.
\nShould be overridden by each board and define at minimum:\nself.name = 'board name/adc name/type' Short an useful to end user\nself.vendor = 'Vendor/Manufacturer name`\nself.channels = tuple of available channel IDs\nself.gains = list of gains\nself.Vdd = voltage provided by board to sensors
\n", "signature": "(addr, send, rcv)"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.getsensors", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.getsensors", "kind": "function", "doc": "Return a list of valid sensor object names for this board.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.V_oversampchan", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.V_oversampchan", "kind": "function", "doc": "list of classnames
\nThis routine returns the average voltage for the channel\naveraged at the default rate for the board and returns an\naverage and observed range.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nV_min -- float, the minimum voltage read during\nthe interval\n\nV_max -- float, the maximum voltage read during the\ninterval\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (1, 2, 3)
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate: maximum
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, V_min, V_max, time_stamp, Vdd_avg
\n\nReturns
\n\n\n\n\ndescription
\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=500):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.V_oversampchan_stats", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.V_oversampchan_stats", "kind": "function", "doc": "This routine returns the average voltage for the channel\naveraged at the maximum rate for the board. The standard\ndeviation and the estimated deviation of the mean are also\nreturned.
\n\nReturns a tuple of the following 5 objects:\n V_avg -- float, the averaged voltage
\n\n\n\nstdev -- float, the standard deviation of the measured values\nduring the averaging interval\n\nstdev_avg -- float, the estimated standard deviation of the\nreturned average\n\ntime_stamp -- float, the time at halfway through the averaging\ninterval in seconds since the beginning of the epoch (OS\ndependent begin time)\n\nVdd_avg -- float, returned as None.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (1, 2, 3)
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate:
- \n
float avg_sec: seconds to average for, actual\naveraging interval will be as close as possible for an integer\nnumber of samples
:returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, avg_sec, data_rate=500):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.Board_LQ.V_sampchan", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "Board_LQ.V_sampchan", "kind": "function", "doc": "This routine returns a single reading of the voltage for the channel.
\n\nReturns a tuple of the following 5 objects:\n V -- float, the measured voltage
\n\n\n\ntime_stamp -- float, the time of the measurement in seconds since\nthe beginning of the epoch (OS dependent begin time)\n\nref -- float, the reference voltage (Vdd) collected\nsimultaneously.\n
Parameters
\n\n\n
\n\n- \n
int chan: the channel number (1, 2, 3).
- \n
gain: ignored by board. Defaults to 1.
- \n
int data_rate:
:returns float value:
\n\nReturns
\n\n\n \n\n\nReturns
\n", "signature": "(self, chan, gain, data_rate=500):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Boards.vernier.labquest.LQProc", "modulename": "jupyterpidaq.Boards.vernier.labquest", "qualname": "LQProc", "kind": "function", "doc": "Process to spawn that continuously collects from the LabQuests(s)
\n\nParameters
\n\ncmdrcv: Pipe\n Where commands are received.
\n\ndatasend: Pipe\n Where data is sent in response to a command.
\n", "signature": "(cmdrcv, datasend, starttime, samples):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings", "modulename": "jupyterpidaq.ChannelSettings", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings", "kind": "class", "doc": "This class takes care of interacting with the user to get settings for data\ncollection on each channel. Should be initialized with an idno, so that\nit knows what number has been assigned to it.
\n"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.__init__", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.__init__", "kind": "function", "doc": "Parameters
\n\n\n
\n", "signature": "(idno, availboards)"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.activate", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.activate", "kind": "function", "doc": "- idno: int number iding this instance of ChannelSettings
\nThis function makes this channel active. No return value unless an e\nrror is thrown by something called by this function.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.deactivate", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.deactivate", "kind": "function", "doc": "None
\nThis function makes the channel inactive. No return value unless an\nerror is thrown by something called by this function.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.checkchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.checkchanged", "kind": "function", "doc": "None
\nThis function is called when the checkbox changes.
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n\n\n\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.boardchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.boardchanged", "kind": "function", "doc": "None
\nThis function responds to a change in board choice.
\n\nParameters
\n\n\n
\n\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.channelchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.channelchanged", "kind": "function", "doc": "This function responds to a change in board choice.
\n\nParameters
\n\n\n
\n\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.sensorchanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.sensorchanged", "kind": "function", "doc": "Called by the observe function of sensorchoice when the user changes\nthe sensor choice.
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n\n\n\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.unitschanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.unitschanged", "kind": "function", "doc": "None
\nCalled by the observe function for the units selector when units are\nchanged
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.gainschanged", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.gainschanged", "kind": "function", "doc": "Called by the observe function for the gains selector when the gain is\nchanged.
\n\nParameters
\n\n\n
\n\n- self:
\n- change: change object passed by the observe tool
\nReturns
\n", "signature": "(self, change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.setup", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.setup", "kind": "function", "doc": "Sets up the GUI and the necessary monitoring.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.ChannelSettings.ChannelSettings.hideGUI", "modulename": "jupyterpidaq.ChannelSettings", "qualname": "ChannelSettings.hideGUI", "kind": "function", "doc": "\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQProc", "modulename": "jupyterpidaq.DAQProc", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.DAQProc.DAQProc", "modulename": "jupyterpidaq.DAQProc", "qualname": "DAQProc", "kind": "function", "doc": "None
\nThis function is to be run in a separate thread to asynchronously\ncommunicate with the ADC board.
\n\nParameters
\n\n\n
\n\n- \n
list whichchn: a list of dictionaries. Each dictionary is of the\nform:{'board': board_object, 'chnl': chnlID}.
- \n
list gains: a list of the numerical gain for each channel.
- \n
float avgtime: the averaging time in seconds for a data point.
- \n
float timedelta: the target time between data points.
- \n
pipe DAQconn: the connection pipe
- \n
pipe DAQCTL: the control pipe
Returns
\n\n\n\n", "signature": "(whichchn, gains, avgtime, timedelta, DAQconn, DAQCTL):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance", "modulename": "jupyterpidaq.DAQinstance", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance", "kind": "class", "doc": "\n"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.__init__", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.__init__", "kind": "function", "doc": "Data is returned via the pipes.\n On the DAQCTL pipe this only returns 'done'\n On the DAQconn pipe a list of lists with data is returned.
\nData Aquistion Instance (a run).
\n\nParameters
\n\n\n
\n", "signature": "(idno, title='None', ntraces=4, **kwargs)"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.setupclick", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.setupclick", "kind": "function", "doc": "\n", "signature": "(self, btn):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.setup", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.setup", "kind": "function", "doc": "\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.collectclick", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.collectclick", "kind": "function", "doc": "\n", "signature": "(self, btn):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.fillpandadf", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.fillpandadf", "kind": "function", "doc": "\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.DAQinstance.updatingplot", "modulename": "jupyterpidaq.DAQinstance", "qualname": "DAQinstance.updatingplot", "kind": "function", "doc": "- idno: id number you wish to use to keep track
\n- title: optional name
\n- ntraces: number of traces (default = 4) more than 4 easily\noverwhelms a pi4.
\n- kwargs: \n:ignore_skew: bool (default: True) if True only a single average\ncollection time will be recorded for each time in a multichannel\ndata collection. If False a separate set of time will be\nrecorded for each channel.
\nRuns until a check of self.collectbtn.description does not return\n'Stop Collecting'. This would probably be more efficient if set a\nboolean.
\n\nParameters
\n\nPLTconn: Pipe\n connection plotter end\nDAQconn: Pipe\n connection DAQ end\nPLTCTL: Pipe\n control pipe plotter end\nDAQCTL: Pipe\n control pipe DAQ end
\n", "signature": "(self, PLTconn, PLTCTL):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.Run", "modulename": "jupyterpidaq.DAQinstance", "qualname": "Run", "kind": "function", "doc": "Load a run from stored data or start a new run if the local file for\nthe run does not exist.
\n\nParameters
\n\nname: str\n String name for the run. The data will be stored in a file of this\n name with the extension of
\n", "signature": "(name):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.doRun", "modulename": "jupyterpidaq.DAQinstance", "qualname": "doRun", "kind": "function", "doc": "\n", "signature": "(whichrun):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.update_runsdrp", "modulename": "jupyterpidaq.DAQinstance", "qualname": "update_runsdrp", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.showSelectedRunTable", "modulename": "jupyterpidaq.DAQinstance", "qualname": "showSelectedRunTable", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.showDataTable", "modulename": "jupyterpidaq.DAQinstance", "qualname": "showDataTable", "kind": "function", "doc": ".jpidaq.html
.Provides a menu to select which run. Then displays the run in a\n10 em high scrolling table. Selection menu is removed after choice\nis made.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.newCalculatedColumn", "modulename": "jupyterpidaq.DAQinstance", "qualname": "newCalculatedColumn", "kind": "function", "doc": "Uses jupyter-pandas-GUI.new_pandas_column_GUI to provide a GUI expression\ncomposer. This method finds the datasets and launches the GUI.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.newPlot", "modulename": "jupyterpidaq.DAQinstance", "qualname": "newPlot", "kind": "function", "doc": "Uses jupyter-pandas-GUI.plot_pandas_GUI to provide a GUI expression\ncomposer. This method finds the datasets and launches the GUI.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.DAQinstance.newFit", "modulename": "jupyterpidaq.DAQinstance", "qualname": "newFit", "kind": "function", "doc": "Uses jupyter-pandas-GUI.fit_pandas_GUI to provide a GUI expression\ncomposer. This method finds the datasets and launches the GUI.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors", "modulename": "jupyterpidaq.Sensors", "kind": "module", "doc": "This module wraps all the modules related to interpretting data from known\nsensors.
\n"}, {"fullname": "jupyterpidaq.Sensors.sensors", "modulename": "jupyterpidaq.Sensors.sensors", "kind": "module", "doc": "\n"}, {"fullname": "jupyterpidaq.Sensors.sensors.to_reasonable_significant_figures", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "to_reasonable_significant_figures", "kind": "function", "doc": "This function will return value rounded to a reasonable number of\nsignificant figures based on the uncertainty. If you are doing this\nbased on the standard return from the raw voltage or the sensor\ndefinitions in this file it is recommend that this be the standard\ndeviation of the average, which will often provide about one more digit\nthan the standard deviation. This will provide a guard digit for further\ncomputations.
\n\nParameters
\n\n\n
\n\n- float value: the value to be rounded
\n- float uncertainty: the uncertainty.
\n:returns float:
\n\nReturns: rounded_value a floating point number.
\n", "signature": "(value, uncertainty):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.to_reasonable_significant_figures_fast", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "to_reasonable_significant_figures_fast", "kind": "function", "doc": "This function will return values rounded to a reasonable number of\nsignificant figures based on the avg_std. This function requires fewer\ncompares so is a little more efficient than calling\nto_reasonable_significant_figures(value, uncertainty) for avg, std,\navg_std separately.
\n\nParameters
\n\n\n
\n\n- float avg: the average value
\n- float std: the standard deviation
\n- float avg_std: the estimated standard deviation in avg\n:returns list:
\nReturns: list of rounded values for each [avg, std, avg_std]
\n", "signature": "(avg, std, avg_std):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.listSensors", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "listSensors", "kind": "function", "doc": "Provides a list of the sensor classes provided by this file. The list must\nbe manually updated with each new class.
\n\nReturns
\n\n\n\n", "signature": "():", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD", "kind": "class", "doc": "list of classnames
\nThis is the base sensor class which all sensors should extend. See how to\ndo this properly using one of the examples below.\nThis class contains definitions for the raw AtoD return in volts. The\ndigital values are not used as the AtoD may have a builtin pre-amp,\nso a given digital value has different meanings depending upon the pre-amp\nsetting.
\n"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.getname", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.getname", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nProvides a string name for the sensor
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.getvendor", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.getvendor", "kind": "function", "doc": "string containing the sensor name
\nProvides a string name for the sensor vendor/manufacturer
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.getunits", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.getunits", "kind": "function", "doc": "string containing the vendor/manufacturer name
\nProvides the string names for the available units for this sensor.\nThese string names are also the functions within this class that\nreturn the measurement in those units.
\n\nReturns
\n\n\n\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.V", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.V", "kind": "function", "doc": "units a list of strings.
\nIt is not really necessary to call this function because it just\nreturns the same values that are passed to it.\nIt is provided for consistency with the way sensors units are defined.
\n\nParameters
\n\n\n
\n\n- v_avg: v_avg: average voltage from A-to-D
\n- v_std: standard deviation of the A-to-D measurements
\n- avg_std: estimate of the standard deviation of v_avg
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.RawAtoD.mV", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "RawAtoD.mV", "kind": "function", "doc": "[v_avg, v_std, avg_std]
\nConvert the raw AtoD voltage to mV.
\n\nParameters
\n\n\n
\n\n- v_avg: v_avg: average voltage from A-to-D
\n- v_std: standard deviation of the A-to-D measurements
\n- avg_std: estimate of the standard deviation of v_avg
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor", "kind": "class", "doc": "[v_avg, v_std, avg_std] converted to mV
\nThis class contains the definitions for builtin thermistor.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.K", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.K", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nThe returned values are in K. It is assumed that the distribution is\nsymmetric guassian even in K. This may not be true, but still gives\na reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- v_avg: average voltage from sensor.
\n- v_std: standard deviation of voltage from sensor.
\n- avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: list [K_avg, K_std, K_avg_std]\n [average temperature in K,\n standard deviation of temperature in K,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.C", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.C", "kind": "function", "doc": "The returned values are in deg C. It is assumed that the distribution\nis symmetric guassian even in deg C. This may not be true, but still\ngives a reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- v_avg: average voltage from sensor.
\n- v_std: standard deviation of voltage from sensor.
\n- avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: list [C_avg, C_std, C_avg_std]\n [average temperature in C, standard deviation of temperature in C,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.BuiltInThermistor.F", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "BuiltInThermistor.F", "kind": "function", "doc": "The returned values are in deg F. It is assumed that the distribution\nis symmetric guassian even in deg F. This may not be true, but still\ngives a reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.\n:returns list:
\nReturns: list [F_avg, F_std, F_avg_std]\n [average temperature in F, standard deviation of temperature in F,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp", "kind": "class", "doc": "This class contains the definitions for Vernier Stainless Steel Temperature\nProbe. A 20K thermistor.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.K", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.K", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nThe returned values are in K. It is assumed that the distribution is\nsymmetric guassian even in K. This may not be true, but still gives\na reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.\n:returns list:
\nReturns list [K_avg, K_std, K_avg_std]\n [average temperature in K, standard deviation of temperature in K,\n estimated standard deviation of the average temperature].
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.C", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.C", "kind": "function", "doc": "The returned values are in deg C. It is assumed that the distribution\nis symmetric guassian even in deg C. This may not be true, but still\ngives a reasonable estimate of the standard deviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: C_avg, C_std, C_avg_std\n average temperature in C, standard deviation of temperature in C,\n estimated standard deviation of the average temperature.
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierSSTemp.F", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierSSTemp.F", "kind": "function", "doc": "The returned values are in deg F. It is assumed that the\ndistribution is symmetric guassian even in deg F. This may not be\ntrue, but still gives a reasonable estimate of the standard\ndeviation.
\n\nParameters
\n\n\n
\n\n- float v_avg: average voltage from sensor.
\n- float v_std: standard deviation of voltage from sensor.
\n- float avg_std: estimated standard deviation of the avg.
\n- float avg_vdd: simultaneously measured average Vdd.
\nReturns
\n\n\n \n\n\nReturns: F_avg, F_std, F_avg_std\n average temperature in F, standard deviation of\n temperature in F, estimated standard deviation of the average\n temperature.
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP", "kind": "class", "doc": "This class contains the definitions for Vernier absolute gas pressure\nsensor, GPS-BTA (post 2011 manufacture).
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.Pa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.Pa", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Pascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.kPa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.kPa", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in kiloPascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.Bar", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.Bar", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Bars
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.Torr", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.Torr", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Torr
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.mmHg", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.mmHg", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in mmHg
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP.atm", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP.atm", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in atm
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD", "kind": "class", "doc": "This class contains the definitions for Vernier absolute gas pressure\nsensor, GPS-BTA (pre 2011 manufacture. Label does not depict a caliper\nwith the registered trademark symbol).
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.Pa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.Pa", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Pascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.kPa", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.kPa", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in kiloPascals
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.Bar", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.Bar", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Bars
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.Torr", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.Torr", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in Torr
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.mmHg", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.mmHg", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in mmHg
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierGasP_OLD.atm", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierGasP_OLD.atm", "kind": "function", "doc": "Parameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the voltage measurements
\n- float avg_std: estimate of the standard deviation of the average
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (\nnot used)
\nReturns
\n\n\n \n\n\nReturns: P_avg, P_std, P_avg_std all in atm
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierpH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierpH", "kind": "class", "doc": "This class contains the definitions for Vernier standard pH\nsensor, PH-BTA.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierpH.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierpH.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierpH.pH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierpH.pH", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: pH_avg, pH_std, pH_avg_std all in pH units
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierFlatpH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierFlatpH", "kind": "class", "doc": "This class contains the definitions for Vernier flat tris-compatible pH\nsensor, FPH-BTA.
\n", "bases": "RawAtoD"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierFlatpH.__init__", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierFlatpH.__init__", "kind": "function", "doc": "This init should be called first in the init section of any class\nextending this class (e.g.
\n\nsuper().__init__(Vdd)
). Then set\nself.name
andself.vendor
to the proper values. Append units\nspecific to the sensor toself.units
. The parameter Vdd must be\nsupplied upon initialization because the output voltage of some\nsensors depends on Vdd.Parameters
\n\n\n
\n", "signature": "(Vdd)"}, {"fullname": "jupyterpidaq.Sensors.sensors.VernierFlatpH.pH", "modulename": "jupyterpidaq.Sensors.sensors", "qualname": "VernierFlatpH.pH", "kind": "function", "doc": "- float Vdd: the voltage supplied to the sensor by the A-to-D\nboard in case the sensor output depends on this.
\nParameters
\n\n\n
\n\n- float v_avg: average raw voltage
\n- float v_std: standard deviation of the raw voltage
\n- float avg_std: estimated standard deviation of v_avg
\n- float avg_vdd: the Vdd measured simultaneously with v_avg (not\nused)
\nReturns
\n\n\n \n\n\nReturns: pH_avg, pH_std, pH_avg_std all in pH units
\n", "signature": "(self, v_avg, v_std, avg_std, avg_vdd):", "funcdef": "def"}]; // mirrored in build-search-index.js (part 1) // Also split on html tags. this is a cheap heuristic, but good enough. diff --git a/setup.py b/setup.py index a6ea72b..6ab74a3 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setuptools.setup( name="JupyterPiDAQ", url = "https://github.com/JupyterPhysSciLab/JupyterPiDAQ", - version="0.8.0", + version="0.8.1", description="Live Data Acquisition in Jupyter notebooks", long_description=long_description, long_description_content_type="text/markdown",