jupyterpidaq.ChannelSettings
1# Class that manages getting settings for a channel to use in JupyterPiDAQ 2# By Jonathan Gutow <gutow@uwosh.edu> 3# July 2021 4# license GPL3+ 5 6from ipywidgets import widgets, Layout 7 8from jupyterpidaq.Sensors import sensors 9 10 11class ChannelSettings: 12 """ 13 This class takes care of interacting with the user to get settings for data 14 collection on each channel. Should be initialized with an idno, so that 15 it knows what number has been assigned to it. 16 """ 17 18 def __init__(self, idno, availboards): 19 """ 20 21 :param idno: int number iding this instance of ChannelSettings 22 """ 23 if idno == None: 24 idno = 0 25 self.idno = idno 26 self.boardchannel = None 27 self.boards = availboards 28 self.boardnames = [] 29 for k in range(len(self.boards)): 30 self.boardnames.append( 31 (str(k) + ' ' + self.boards[k].getname(), k)) 32 self.board = self.boards[0] 33 self.channel = self.board.channels[0] 34 self.toselectedunits = None 35 self.isactive = False 36 self.availablegains = self.board.getgains() 37 self.toselectedgain = self.availablegains[0] 38 self.sensornames = [] 39 for name in self.board.getsensors(): 40 # TODO: change this to display the sensor name, not the sensor 41 # class name. Probably need to replace each element with a tuple 42 # and rejigger some of the update calls. 43 self.sensornames.append(name) 44 self.sensor = getattr(sensors, self.board.getsensors()[0])( 45 self.board.getVdd()) 46 self.defaultunits = self.sensor.getunits() 47 self.defaultsensorname = self.sensornames[0] 48 self.sensor = None # Set to nothing unless the channel is active. 49 ### 50 # Jupyter Interactive elements for setting channel parameters 51 ### 52 self.checkbox = widgets.Checkbox( 53 value=self.isactive, 54 description='Trace ' + str(self.idno), 55 disabled=False) 56 self.checkbox.observe(self.checkchanged, names='value') 57 self.tracelbl = widgets.Text( 58 value='Trace_' + str(self.idno), 59 # TODO: update to meaningful title on sensor change if left at 60 # default. 61 placeholder='Type something', 62 description='Title:', 63 disabled=True) 64 self.boardchoice = widgets.Dropdown( 65 options=self.boardnames, 66 description='Board:', 67 disabled=True) 68 self.boardchoice.observe(self.boardchanged, names='value') 69 self.channelchoice = widgets.Dropdown( 70 options=self.board.channels, 71 description='Channel:', 72 disabled=True) 73 self.channelchoice.observe(self.channelchanged, names='value') 74 self.sensorchoice = widgets.Dropdown( 75 options=self.sensornames, 76 # value=self.defaultsensorname, # not needed defaults to the first 77 # choice in list 78 description='Sensor:', 79 disabled=True) 80 self.sensorchoice.observe(self.sensorchanged, names='value') 81 self.units = widgets.Dropdown( 82 options=self.defaultunits, 83 # value=self.defaultunits[0], # not needed defaults to the first 84 # choice in list 85 description='Units:', 86 disabled=True) 87 self.units.observe(self.unitschanged, names='value') 88 # TODO: select gain 89 self.gains = widgets.Dropdown( 90 options=self.availablegains, 91 description='gains:', 92 disabled=True) 93 self.toselectedgain = self.gains.value 94 self.gains.observe(self.gainschanged, names='value') 95 96 def activate(self): 97 """ 98 This function makes this channel active. No return value unless an e 99 rror is thrown by something called by this function. 100 :return: None 101 """ 102 self.sensor = getattr(sensors, self.board.getsensors()[0])( 103 self.board.getVdd()) 104 self.toselectedunits = getattr(self.sensor, self.units.value) 105 self.checkbox.value = True # in case the selection is not done by the 106 # user. 107 self.tracelbl.disabled = False 108 self.boardchoice.disabled = False 109 self.channelchoice.disabled = False 110 self.sensorchoice.disabled = False 111 self.units.disabled = False 112 self.gains.disabled = False 113 self.isactive = True 114 pass 115 116 def deactivate(self): 117 """ 118 This function makes the channel inactive. No return value unless an 119 error is thrown by something called by this function. 120 :return: None 121 """ 122 self.sensor = None 123 self.toselectedunits = None 124 self.checkbox.value = False # in case the deactivation is not done by 125 # the user. 126 self.tracelbl.disabled = True 127 self.boardchoice.disabled = True 128 self.channelchoice.disabled = True 129 self.sensorchoice.disabled = True 130 self.units.disabled = True 131 self.gains.disabled = True 132 self.isactive = False 133 pass 134 135 def checkchanged(self, change): 136 """ 137 This function is called when the checkbox changes. 138 :param self: 139 :param change: change object passed by the observe tool 140 :return: None 141 """ 142 if change.new: # if True 143 self.activate() 144 else: 145 self.deactivate() 146 pass 147 148 def boardchanged(self, change): 149 """ 150 This function responds to a change in board choice. 151 :param change: change object passed by the observe tool 152 :return: 153 """ 154 # Get the new board 155 self.board = self.boards[change['owner'].value] 156 # Update available channels 157 self.channelchoice.options = self.board.getchannels() 158 # Trigger update to allowed gains 159 self.availablegains = self.board.getgains() 160 self.gains.options = self.board.getgains() 161 self.toselectedgain = self.availablegains[0] 162 # Trigger an update to the sensor list 163 self.sensornames = [] 164 for name in self.board.getsensors(): 165 self.sensornames.append(name) 166 self.sensorchoice.options = self.sensornames 167 self.sensor = getattr(sensors, self.board.getsensors()[0])( 168 self.board.getVdd()) 169 self.defaultunits = self.sensor.getunits() 170 self.units.options = self.defaultunits 171 self.defaultsensorname = self.sensornames[0] 172 self.toselectedunits = getattr(self.sensor, self.defaultunits[0]) 173 pass 174 175 def channelchanged(self, change): 176 """ 177 This function responds to a change in board choice. 178 :param change: change object passed by the observe tool 179 :return: 180 """ 181 # set new channel 182 self.channel = change['owner'].value 183 pass 184 185 def sensorchanged(self, change): 186 """ 187 Called by the observe function of sensorchoice when the user changes 188 the sensor choice. 189 :param self: 190 :param change: change object passed by the observe tool 191 :return: None 192 """ 193 # print(str(change['new'])+',' + str(self.sensorchoice.value)) 194 # Get the new sensor choice and define the sensor object 195 self.sensor = getattr(sensors, change['owner'].value)( 196 self.board.getVdd()) 197 # Update the unit choices to match the sensor chosen 198 self.units.options = self.sensor.getunits() 199 # set the unit conversion function 200 self.toselectedunits = getattr(self.sensor, self.units.value) 201 pass 202 203 def unitschanged(self, change): 204 """ 205 Called by the observe function for the units selector when units are 206 changed 207 :param self: 208 :param change: change object passed by the observe tool 209 :return: 210 """ 211 self.toselectedunits = getattr(self.sensor, self.units.value) 212 pass 213 214 def gainschanged(self, change): 215 """ 216 Called by the observe function for the gains selector when the gain is 217 changed. 218 :param self: 219 :param change: change object passed by the observe tool 220 :return: 221 """ 222 self.toselectedgain = self.gains.value 223 pass 224 225 def setup(self): 226 """ 227 Sets up the GUI and the necessary monitoring. 228 :return: None 229 """ 230 self.headbox = widgets.HBox([self.checkbox, self.tracelbl]) 231 self.parambox1 = widgets.HBox( 232 [self.boardchoice, self.channelchoice, self.sensorchoice]) 233 self.parambox2 = widgets.HBox([self.units, self.gains]) 234 self.settings = widgets.VBox( 235 [self.headbox, self.parambox1, self.parambox2], 236 layout=Layout(border='solid')) 237 from IPython.core.display import display 238 display(self.settings) 239 pass 240 241 def hideGUI(self): 242 self.settings.close() 243 # Not sure any of the below is necessary. The DOM could use some 244 # cleanup. This may require supporting JS. 245 self.headbox.close() 246 self.parambox1.close() 247 self.parambox2.close() 248 self.sensorchoice.close() 249 self.units.close() 250 self.checkbox.close() 251 self.tracelbl.close()
12class ChannelSettings: 13 """ 14 This class takes care of interacting with the user to get settings for data 15 collection on each channel. Should be initialized with an idno, so that 16 it knows what number has been assigned to it. 17 """ 18 19 def __init__(self, idno, availboards): 20 """ 21 22 :param idno: int number iding this instance of ChannelSettings 23 """ 24 if idno == None: 25 idno = 0 26 self.idno = idno 27 self.boardchannel = None 28 self.boards = availboards 29 self.boardnames = [] 30 for k in range(len(self.boards)): 31 self.boardnames.append( 32 (str(k) + ' ' + self.boards[k].getname(), k)) 33 self.board = self.boards[0] 34 self.channel = self.board.channels[0] 35 self.toselectedunits = None 36 self.isactive = False 37 self.availablegains = self.board.getgains() 38 self.toselectedgain = self.availablegains[0] 39 self.sensornames = [] 40 for name in self.board.getsensors(): 41 # TODO: change this to display the sensor name, not the sensor 42 # class name. Probably need to replace each element with a tuple 43 # and rejigger some of the update calls. 44 self.sensornames.append(name) 45 self.sensor = getattr(sensors, self.board.getsensors()[0])( 46 self.board.getVdd()) 47 self.defaultunits = self.sensor.getunits() 48 self.defaultsensorname = self.sensornames[0] 49 self.sensor = None # Set to nothing unless the channel is active. 50 ### 51 # Jupyter Interactive elements for setting channel parameters 52 ### 53 self.checkbox = widgets.Checkbox( 54 value=self.isactive, 55 description='Trace ' + str(self.idno), 56 disabled=False) 57 self.checkbox.observe(self.checkchanged, names='value') 58 self.tracelbl = widgets.Text( 59 value='Trace_' + str(self.idno), 60 # TODO: update to meaningful title on sensor change if left at 61 # default. 62 placeholder='Type something', 63 description='Title:', 64 disabled=True) 65 self.boardchoice = widgets.Dropdown( 66 options=self.boardnames, 67 description='Board:', 68 disabled=True) 69 self.boardchoice.observe(self.boardchanged, names='value') 70 self.channelchoice = widgets.Dropdown( 71 options=self.board.channels, 72 description='Channel:', 73 disabled=True) 74 self.channelchoice.observe(self.channelchanged, names='value') 75 self.sensorchoice = widgets.Dropdown( 76 options=self.sensornames, 77 # value=self.defaultsensorname, # not needed defaults to the first 78 # choice in list 79 description='Sensor:', 80 disabled=True) 81 self.sensorchoice.observe(self.sensorchanged, names='value') 82 self.units = widgets.Dropdown( 83 options=self.defaultunits, 84 # value=self.defaultunits[0], # not needed defaults to the first 85 # choice in list 86 description='Units:', 87 disabled=True) 88 self.units.observe(self.unitschanged, names='value') 89 # TODO: select gain 90 self.gains = widgets.Dropdown( 91 options=self.availablegains, 92 description='gains:', 93 disabled=True) 94 self.toselectedgain = self.gains.value 95 self.gains.observe(self.gainschanged, names='value') 96 97 def activate(self): 98 """ 99 This function makes this channel active. No return value unless an e 100 rror is thrown by something called by this function. 101 :return: None 102 """ 103 self.sensor = getattr(sensors, self.board.getsensors()[0])( 104 self.board.getVdd()) 105 self.toselectedunits = getattr(self.sensor, self.units.value) 106 self.checkbox.value = True # in case the selection is not done by the 107 # user. 108 self.tracelbl.disabled = False 109 self.boardchoice.disabled = False 110 self.channelchoice.disabled = False 111 self.sensorchoice.disabled = False 112 self.units.disabled = False 113 self.gains.disabled = False 114 self.isactive = True 115 pass 116 117 def deactivate(self): 118 """ 119 This function makes the channel inactive. No return value unless an 120 error is thrown by something called by this function. 121 :return: None 122 """ 123 self.sensor = None 124 self.toselectedunits = None 125 self.checkbox.value = False # in case the deactivation is not done by 126 # the user. 127 self.tracelbl.disabled = True 128 self.boardchoice.disabled = True 129 self.channelchoice.disabled = True 130 self.sensorchoice.disabled = True 131 self.units.disabled = True 132 self.gains.disabled = True 133 self.isactive = False 134 pass 135 136 def checkchanged(self, change): 137 """ 138 This function is called when the checkbox changes. 139 :param self: 140 :param change: change object passed by the observe tool 141 :return: None 142 """ 143 if change.new: # if True 144 self.activate() 145 else: 146 self.deactivate() 147 pass 148 149 def boardchanged(self, change): 150 """ 151 This function responds to a change in board choice. 152 :param change: change object passed by the observe tool 153 :return: 154 """ 155 # Get the new board 156 self.board = self.boards[change['owner'].value] 157 # Update available channels 158 self.channelchoice.options = self.board.getchannels() 159 # Trigger update to allowed gains 160 self.availablegains = self.board.getgains() 161 self.gains.options = self.board.getgains() 162 self.toselectedgain = self.availablegains[0] 163 # Trigger an update to the sensor list 164 self.sensornames = [] 165 for name in self.board.getsensors(): 166 self.sensornames.append(name) 167 self.sensorchoice.options = self.sensornames 168 self.sensor = getattr(sensors, self.board.getsensors()[0])( 169 self.board.getVdd()) 170 self.defaultunits = self.sensor.getunits() 171 self.units.options = self.defaultunits 172 self.defaultsensorname = self.sensornames[0] 173 self.toselectedunits = getattr(self.sensor, self.defaultunits[0]) 174 pass 175 176 def channelchanged(self, change): 177 """ 178 This function responds to a change in board choice. 179 :param change: change object passed by the observe tool 180 :return: 181 """ 182 # set new channel 183 self.channel = change['owner'].value 184 pass 185 186 def sensorchanged(self, change): 187 """ 188 Called by the observe function of sensorchoice when the user changes 189 the sensor choice. 190 :param self: 191 :param change: change object passed by the observe tool 192 :return: None 193 """ 194 # print(str(change['new'])+',' + str(self.sensorchoice.value)) 195 # Get the new sensor choice and define the sensor object 196 self.sensor = getattr(sensors, change['owner'].value)( 197 self.board.getVdd()) 198 # Update the unit choices to match the sensor chosen 199 self.units.options = self.sensor.getunits() 200 # set the unit conversion function 201 self.toselectedunits = getattr(self.sensor, self.units.value) 202 pass 203 204 def unitschanged(self, change): 205 """ 206 Called by the observe function for the units selector when units are 207 changed 208 :param self: 209 :param change: change object passed by the observe tool 210 :return: 211 """ 212 self.toselectedunits = getattr(self.sensor, self.units.value) 213 pass 214 215 def gainschanged(self, change): 216 """ 217 Called by the observe function for the gains selector when the gain is 218 changed. 219 :param self: 220 :param change: change object passed by the observe tool 221 :return: 222 """ 223 self.toselectedgain = self.gains.value 224 pass 225 226 def setup(self): 227 """ 228 Sets up the GUI and the necessary monitoring. 229 :return: None 230 """ 231 self.headbox = widgets.HBox([self.checkbox, self.tracelbl]) 232 self.parambox1 = widgets.HBox( 233 [self.boardchoice, self.channelchoice, self.sensorchoice]) 234 self.parambox2 = widgets.HBox([self.units, self.gains]) 235 self.settings = widgets.VBox( 236 [self.headbox, self.parambox1, self.parambox2], 237 layout=Layout(border='solid')) 238 from IPython.core.display import display 239 display(self.settings) 240 pass 241 242 def hideGUI(self): 243 self.settings.close() 244 # Not sure any of the below is necessary. The DOM could use some 245 # cleanup. This may require supporting JS. 246 self.headbox.close() 247 self.parambox1.close() 248 self.parambox2.close() 249 self.sensorchoice.close() 250 self.units.close() 251 self.checkbox.close() 252 self.tracelbl.close()
This class takes care of interacting with the user to get settings for data collection on each channel. Should be initialized with an idno, so that it knows what number has been assigned to it.
19 def __init__(self, idno, availboards): 20 """ 21 22 :param idno: int number iding this instance of ChannelSettings 23 """ 24 if idno == None: 25 idno = 0 26 self.idno = idno 27 self.boardchannel = None 28 self.boards = availboards 29 self.boardnames = [] 30 for k in range(len(self.boards)): 31 self.boardnames.append( 32 (str(k) + ' ' + self.boards[k].getname(), k)) 33 self.board = self.boards[0] 34 self.channel = self.board.channels[0] 35 self.toselectedunits = None 36 self.isactive = False 37 self.availablegains = self.board.getgains() 38 self.toselectedgain = self.availablegains[0] 39 self.sensornames = [] 40 for name in self.board.getsensors(): 41 # TODO: change this to display the sensor name, not the sensor 42 # class name. Probably need to replace each element with a tuple 43 # and rejigger some of the update calls. 44 self.sensornames.append(name) 45 self.sensor = getattr(sensors, self.board.getsensors()[0])( 46 self.board.getVdd()) 47 self.defaultunits = self.sensor.getunits() 48 self.defaultsensorname = self.sensornames[0] 49 self.sensor = None # Set to nothing unless the channel is active. 50 ### 51 # Jupyter Interactive elements for setting channel parameters 52 ### 53 self.checkbox = widgets.Checkbox( 54 value=self.isactive, 55 description='Trace ' + str(self.idno), 56 disabled=False) 57 self.checkbox.observe(self.checkchanged, names='value') 58 self.tracelbl = widgets.Text( 59 value='Trace_' + str(self.idno), 60 # TODO: update to meaningful title on sensor change if left at 61 # default. 62 placeholder='Type something', 63 description='Title:', 64 disabled=True) 65 self.boardchoice = widgets.Dropdown( 66 options=self.boardnames, 67 description='Board:', 68 disabled=True) 69 self.boardchoice.observe(self.boardchanged, names='value') 70 self.channelchoice = widgets.Dropdown( 71 options=self.board.channels, 72 description='Channel:', 73 disabled=True) 74 self.channelchoice.observe(self.channelchanged, names='value') 75 self.sensorchoice = widgets.Dropdown( 76 options=self.sensornames, 77 # value=self.defaultsensorname, # not needed defaults to the first 78 # choice in list 79 description='Sensor:', 80 disabled=True) 81 self.sensorchoice.observe(self.sensorchanged, names='value') 82 self.units = widgets.Dropdown( 83 options=self.defaultunits, 84 # value=self.defaultunits[0], # not needed defaults to the first 85 # choice in list 86 description='Units:', 87 disabled=True) 88 self.units.observe(self.unitschanged, names='value') 89 # TODO: select gain 90 self.gains = widgets.Dropdown( 91 options=self.availablegains, 92 description='gains:', 93 disabled=True) 94 self.toselectedgain = self.gains.value 95 self.gains.observe(self.gainschanged, names='value')
Parameters
- idno: int number iding this instance of ChannelSettings
97 def activate(self): 98 """ 99 This function makes this channel active. No return value unless an e 100 rror is thrown by something called by this function. 101 :return: None 102 """ 103 self.sensor = getattr(sensors, self.board.getsensors()[0])( 104 self.board.getVdd()) 105 self.toselectedunits = getattr(self.sensor, self.units.value) 106 self.checkbox.value = True # in case the selection is not done by the 107 # user. 108 self.tracelbl.disabled = False 109 self.boardchoice.disabled = False 110 self.channelchoice.disabled = False 111 self.sensorchoice.disabled = False 112 self.units.disabled = False 113 self.gains.disabled = False 114 self.isactive = True 115 pass
This function makes this channel active. No return value unless an e rror is thrown by something called by this function.
Returns
None
117 def deactivate(self): 118 """ 119 This function makes the channel inactive. No return value unless an 120 error is thrown by something called by this function. 121 :return: None 122 """ 123 self.sensor = None 124 self.toselectedunits = None 125 self.checkbox.value = False # in case the deactivation is not done by 126 # the user. 127 self.tracelbl.disabled = True 128 self.boardchoice.disabled = True 129 self.channelchoice.disabled = True 130 self.sensorchoice.disabled = True 131 self.units.disabled = True 132 self.gains.disabled = True 133 self.isactive = False 134 pass
This function makes the channel inactive. No return value unless an error is thrown by something called by this function.
Returns
None
136 def checkchanged(self, change): 137 """ 138 This function is called when the checkbox changes. 139 :param self: 140 :param change: change object passed by the observe tool 141 :return: None 142 """ 143 if change.new: # if True 144 self.activate() 145 else: 146 self.deactivate() 147 pass
This function is called when the checkbox changes.
Parameters
- self:
- change: change object passed by the observe tool
Returns
None
149 def boardchanged(self, change): 150 """ 151 This function responds to a change in board choice. 152 :param change: change object passed by the observe tool 153 :return: 154 """ 155 # Get the new board 156 self.board = self.boards[change['owner'].value] 157 # Update available channels 158 self.channelchoice.options = self.board.getchannels() 159 # Trigger update to allowed gains 160 self.availablegains = self.board.getgains() 161 self.gains.options = self.board.getgains() 162 self.toselectedgain = self.availablegains[0] 163 # Trigger an update to the sensor list 164 self.sensornames = [] 165 for name in self.board.getsensors(): 166 self.sensornames.append(name) 167 self.sensorchoice.options = self.sensornames 168 self.sensor = getattr(sensors, self.board.getsensors()[0])( 169 self.board.getVdd()) 170 self.defaultunits = self.sensor.getunits() 171 self.units.options = self.defaultunits 172 self.defaultsensorname = self.sensornames[0] 173 self.toselectedunits = getattr(self.sensor, self.defaultunits[0]) 174 pass
This function responds to a change in board choice.
Parameters
- change: change object passed by the observe tool
Returns
176 def channelchanged(self, change): 177 """ 178 This function responds to a change in board choice. 179 :param change: change object passed by the observe tool 180 :return: 181 """ 182 # set new channel 183 self.channel = change['owner'].value 184 pass
This function responds to a change in board choice.
Parameters
- change: change object passed by the observe tool
Returns
186 def sensorchanged(self, change): 187 """ 188 Called by the observe function of sensorchoice when the user changes 189 the sensor choice. 190 :param self: 191 :param change: change object passed by the observe tool 192 :return: None 193 """ 194 # print(str(change['new'])+',' + str(self.sensorchoice.value)) 195 # Get the new sensor choice and define the sensor object 196 self.sensor = getattr(sensors, change['owner'].value)( 197 self.board.getVdd()) 198 # Update the unit choices to match the sensor chosen 199 self.units.options = self.sensor.getunits() 200 # set the unit conversion function 201 self.toselectedunits = getattr(self.sensor, self.units.value) 202 pass
Called by the observe function of sensorchoice when the user changes the sensor choice.
Parameters
- self:
- change: change object passed by the observe tool
Returns
None
204 def unitschanged(self, change): 205 """ 206 Called by the observe function for the units selector when units are 207 changed 208 :param self: 209 :param change: change object passed by the observe tool 210 :return: 211 """ 212 self.toselectedunits = getattr(self.sensor, self.units.value) 213 pass
Called by the observe function for the units selector when units are changed
Parameters
- self:
- change: change object passed by the observe tool
Returns
215 def gainschanged(self, change): 216 """ 217 Called by the observe function for the gains selector when the gain is 218 changed. 219 :param self: 220 :param change: change object passed by the observe tool 221 :return: 222 """ 223 self.toselectedgain = self.gains.value 224 pass
Called by the observe function for the gains selector when the gain is changed.
Parameters
- self:
- change: change object passed by the observe tool
Returns
226 def setup(self): 227 """ 228 Sets up the GUI and the necessary monitoring. 229 :return: None 230 """ 231 self.headbox = widgets.HBox([self.checkbox, self.tracelbl]) 232 self.parambox1 = widgets.HBox( 233 [self.boardchoice, self.channelchoice, self.sensorchoice]) 234 self.parambox2 = widgets.HBox([self.units, self.gains]) 235 self.settings = widgets.VBox( 236 [self.headbox, self.parambox1, self.parambox2], 237 layout=Layout(border='solid')) 238 from IPython.core.display import display 239 display(self.settings) 240 pass
Sets up the GUI and the necessary monitoring.
Returns
None
242 def hideGUI(self): 243 self.settings.close() 244 # Not sure any of the below is necessary. The DOM could use some 245 # cleanup. This may require supporting JS. 246 self.headbox.close() 247 self.parambox1.close() 248 self.parambox2.close() 249 self.sensorchoice.close() 250 self.units.close() 251 self.checkbox.close() 252 self.tracelbl.close()