class EVTxx(item.item): """ This class (the class with the same name as the module) handles the basic functionality of the item. It does not deal with GUI stuff. """ description = u"Allows setting or pulsing values of pins on the " \ "output port of various EventExchanger devices" def reset(self): self.var._value = 0 self.var._duration = 500 self.var._productName = u'DUMMY' self.var._outputMode = u'Pulse Output Lines' def prepare(self): item.item.prepare(self) self.EE = EvtExchanger() Device = self.EE.Select(self.var._productName) try: if Device is None: raise except: self.var._productName = u'DUMMY' oslogger.info("Cannot find eventexchanger: code to debugwindow") def run(self): self.set_item_onset() #self.EE.Select(self.PATH) if self.var._productName == u'DUMMY': oslogger.info('dummy code: {} for {} ms'.format( self.var._value, self.var._duration)) else: if self.var._outputMode == u'Set Output Lines': self.EE.SetLines(self.var._value) elif self.var._outputMode == u'Pulse Output Lines': # make sure that the code starts at, and returns to zero. self.EE.SetLines(0) self.EE.PulseLines(self.var._value, self.var._duration) return True
class RGB_Led_Control(item.item): """ This class (the class with the same name as the module) handles the basic functionality of the item. It does not deal with GUI stuff. """ description = u"Sets and/or sends RGB led data from\r\n" \ "EventExchanger-based digital input/output device." def reset(self): # Set the default values of the plug-in items in the GUI. self.var._productName = u'DUMMY' self.var._correctButton = u'1' self.var._allowedButtons = u'1;2;3' self.var._responseTimeout = u'infinite' self.var._button1_Led_Color = "#000000" self.var._button2_Led_Color = "#000000" self.var._button3_Led_Color = "#000000" self.var._button4_Led_Color = "#000000" self.var._resetAfter = 500; self.var._feedback = u'yes' self.var._correctColor = "#00FF00" self.var._inCorrectColor = "#FF0000" def prepare(self): item.item.prepare(self) self.EE = EvtExchanger() Device = self.EE.Select(self.var._productName) try: if Device is None: raise except: self.var._productName = u'DUMMY' self.Keyboard = Keyboard(self.experiment); if not type(self.var._responseTimeout) == int: self.var._responseTimeout = None oslogger.info("Cannot find ResponseBox: Using Keyboard instead") if not type(self.var._responseTimeout) == int and not type(self.var._responseTimeout) == float: self.var._responseTimeout = -1 # Recode Allowed buttons to AllowedEventLines self.var.AllowedEventLines = 0 try: AllowedList = self.var._allowedButtons.split(";") for x in AllowedList: self.var.AllowedEventLines += (1 << (int(x,10) -1)) except: x = self.var._allowedButtons self.var.AllowedEventLines = (1 << (x-1)) def run(self): # Save the current time ... t0 = self.set_item_onset() hexprepend = "0x" self.colors = [hexprepend + self.var._button1_Led_Color[1:], \ hexprepend + self.var._button2_Led_Color[1:], \ hexprepend + self.var._button3_Led_Color[1:], \ hexprepend + self.var._button4_Led_Color[1:]] self.CorrectColor = hexprepend + self.var._correctColor[1:] self.InCorrectColor = hexprepend + self.var._inCorrectColor[1:] CC=int(self.CorrectColor,16) IC=int(self.InCorrectColor,16) BLC = [0,0,0,0] for b in range(4): BLC[b] = int(self.colors[b] , 16) if self.var._productName != u'DUMMY': for b in range(4): self.EE.SetLedColor( \ ((BLC[b] >> 16) & 0xFF), \ ((BLC[b] >> 8) & 0xFF), \ (BLC[b] & 0xFF), \ b+1, 1) if self.var._feedback == u'yes': for b in range(4): self.EE.SetLedColor( \ ((IC >> 16) & 0xFF), \ ((IC >> 8) & 0xFF), \ (IC & 0xFF), \ b+1, b+11) self.EE.SetLedColor( \ ((CC >> 16) & 0xFF), \ ((CC >> 8) & 0xFF), \ (CC & 0xFF), \ int(self.var._correctButton), int(self.var._correctButton)+10) # Call the 'wait for event' function in the EventExchanger C# object. (self.var.Response,self.var.RT) = \ (self.EE.WaitForDigEvents(self.var.AllowedEventLines, self.var._responseTimeout)) if (self.var.Response != -1): self.var.Response = math.log2(self.var.Response) + 1; #FEEDBACK: if self.var._feedback == u'yes': time.sleep(self.var._resetAfter/1000.0) for b in range(4): self.EE.SetLedColor(0,0,0,b+1,1) else: # demo mode: keyboard response..... if self.var._responseTimeout==-1: self.var._responseTimeout = None self.var.Response, self.var.RT= self.Keyboard.get_key(timeout=self.var._responseTimeout) #HOUSEHOLD: self.var.correct = \ bool(self.var.Response == self.var._correctButton) self.var.correct = distutils.util.strtobool(str(self.var.correct)) print(self.var.correct) # Add all response related data to the Opensesame responses instance. self.experiment.responses.add(response_time=self.var.RT, \ correct=self.var.correct, \ response=self.var.Response, \ item=self.name) #Report success return True
class ResponseBox(item.item): """ This class (the class with the same name as the module) handles the basic functionality of the item. It does not deal with GUI stuff. """ description = u"Aquires buttonpress-responses and/or digital events\r\n" \ " from EventExchanger-based digital input device. " def reset(self): # Set the default values of the plug-in items in the GUI self.var._productName = u'DUMMY' self.var._correctButton = u'' self.var._allowedButtons = u'1;2;3;4' self.var._responseTimeout = u'infinite' def prepare(self): item.item.prepare(self) self.EE = EvtExchanger() Device = self.EE.Select(self.var._productName) try: if Device is None: raise except: self.var._productName = u'DUMMY' self.Keyboard = Keyboard(self.experiment) if not type(self.var._responseTimeout) == int: self.var._responseTimeout = None oslogger.info("Cannot find ResponseBox: Using Keyboard instead") if not type(self.var._responseTimeout) == int: self.var._responseTimeout = -1 # Recode Allowed buttons to AllowedEventLines self.var.AllowedEventLines = 0 try: AllowedList = self.var._allowedButtons.split(";") for x in AllowedList: self.var.AllowedEventLines += (1 << (int(x, 10) - 1)) except: x = self.var._allowedButtons self.var.AllowedEventLines = (1 << (x - 1)) def run(self): # Save the current time ... t0 = self.set_item_onset() # Call the 'wait for event' function in the EventExchanger C# object. if self.var._productName != u'DUMMY': (self.var.Response,self.var.RT) = \ (self.EE.WaitForDigEvents(self.var.AllowedEventLines, self.var._responseTimeout)) self.var.Response = math.log2(self.var.Response) + 1 else: # demo mode: keyboard response..... self.var.Response, self.var.RT = self.Keyboard.get_key( timeout=self.var._responseTimeout) self.CorrectResponse = \ (self.var.Response == self.var._correctButton) # Add all response related data to the Opensesame responses instance. self.experiment.responses.add(response_time=self.var.RT, \ correct=self.CorrectResponse, \ response=self.var.Response, \ item=self.name) #Report success return True
class VAS(item): """ This class (the class with the same name as the module) handles the basic functionality of the item. It does not deal with GUI stuff. """ # Provide an informative description for your plug-in. description = u'A VAS modifier for a canvas' def reset(self): """ desc: Resets plug-in to initial values. """ # Here we provide default values for the variables that are specified # in info.json. If you do not provide default values, the plug-in will # work, but the variables will be undefined when they are not explicitly # set in the GUI. self.var.VAS_ENCODER_ID = u"MOUSE" self.var.VAS_EXIT_METHOD = u'MOUSE' self.var.VAS_EXIT_KEY = u' ' self.var.VAS_DURATION = 10000 self.var.VAS_CANVAS_NAME = u'VASSCREEN' self.var.VAS_BODY_NAME = u'VASBODY' self.var.VAS_CURSOR_NAME = u'VASCURSOR' self.var.VAS_TIMER_NAME = u'VASTIMER' self.var.VAS_CURSOR_STARTPOSITION = 0 def prepare(self): """The preparation phase of the plug-in goes here.""" item.prepare(self) self.EE = EvtExchanger() Devices = self.EE.Select(self.var.VAS_ENCODER_ID) try: self.EE.RENC_SetUp(1024, 0, int(1024*(self.var.VAS_CURSOR_STARTPOSITION/100.0)), 1, 1) if Devices[0] is None: raise except: self.var.VAS_ENCODER_ID = u"MOUSE" oslogger.info("Cannot find encoder input device: Using mouse") # Checking the excistence of the VAS elements is only possible in the runphase # as only then the full canvas is availeable self.c = Canvas(self.experiment) self._Keyboard = Keyboard(self.experiment, timeout = 0); self._Mouse = Mouse(self.experiment) my_canvas = self.experiment.items[self.var.VAS_CANVAS_NAME].canvas try: if my_canvas[self.var.VAS_CURSOR_NAME] == None or my_canvas[self.var.VAS_BODY_NAME] == None: oslogger.info("Should not occur") except Exception as e: raise osexception(u"Prepare: READ the VAS manual:\n\rNo VAS elements found on the named canvas") self.c = self.experiment.items[self.var.VAS_CANVAS_NAME].canvas self.c[self.var.VAS_CURSOR_NAME].sx = (self.c[self.var.VAS_BODY_NAME].sx+self.c[self.var.VAS_BODY_NAME].ex) / 2.0 self.c[self.var.VAS_CURSOR_NAME].ex = self.c[self.var.VAS_CURSOR_NAME].sx self.VASLENGTH = self.c[self.var.VAS_BODY_NAME].ex - self.c[self.var.VAS_BODY_NAME].sx self.SHOWTIMER = False if self.var.VAS_EXIT_METHOD == 'TIME': if my_canvas[self.var.VAS_CURSOR_NAME] != None: self.SHOWTIMER = True self.w = self.c[self.var.VAS_TIMER_NAME].ex - self.c[self.var.VAS_TIMER_NAME].sx self.h = self.c[self.var.VAS_TIMER_NAME].ey - self.c[self.var.VAS_TIMER_NAME].sy self.TIMER_DIR = 'vert' self.TIMERSIZE = self.h if (abs(self.w) > abs(self.h)): self.TIMER_DIR = 'horiz' self.TIMERSIZE = self.w def run(self): self.set_item_onset(self.c.show()) st = self.experiment.time() val = int(1024*(self.var.VAS_CURSOR_STARTPOSITION/100.0)) while(True): if self.var.VAS_EXIT_METHOD == 'TIME': if self.SHOWTIMER: tperc = (self.experiment.time()-st)/self.var.VAS_DURATION if self.TIMER_DIR == 'horiz': self.c[self.var.VAS_TIMER_NAME].ex = self.c[self.var.VAS_TIMER_NAME].sx + ((1-tperc) * self.w) else: self.c[self.var.VAS_TIMER_NAME].ey = self.c[self.var.VAS_TIMER_NAME].sy + ((1-tperc) * self.h) if ((self.experiment.time()-st) > self.var.VAS_DURATION): break if self.var.VAS_EXIT_METHOD == 'MOUSE': button, position, timestamp = self._Mouse.get_click(timeout=2) if button is not None: break if self.var.VAS_EXIT_METHOD == 'KEY': key, time = self._Keyboard.get_key(timeout=5) if key is not None: if key == self.var.VAS_EXITKEY: break self._Keyboard.flush() if self.var.VAS_ENCODER_ID != u"MOUSE": val = self.EE.GetAxis() else: (val,y), time = self._Mouse.get_pos() val = (val + 512) if val is not None: val = (val)/1024.0 val = np.clip(val, 0, 1) try: self.c["VASVALUE"].text = str(round(val,2)) except Exception as e: e.Message = "" for i in self.c[self.var.VAS_CURSOR_NAME]: i.sx = self.c[self.var.VAS_BODY_NAME].sx + (val*self.VASLENGTH) i.ex = i.sx self.c.show() # Add all response related data to the Opensesame responses instance. self.experiment.responses.add(response_time=self.experiment.time()-st, \ correct=None, \ response=str(round(val,2)), \ item=self.name)
class Shocker(item.item): description = u"Allows the calibration *and* the use of the tactile stimulator." def reset(self): self.var._value = 0 self.var._calibrationvalue = 100 self.var._duration = 150 self.var._productName = u"DUMMY" self.var._calibrate = u"Calibrate" # time in seconds. def prepare(self): self.experiment.set("ShockDuration", self.var._duration) self.var._min_intershock_interval = 1 item.item.prepare(self) self.EE = EvtExchanger() Device = self.EE.Select(self.var._productName) try: if Device is None: raise except: self.var._productName = u"DUMMY" oslogger.warning("Did not find a shocker: code to debugwindow") if self.var._calibrate == u"Calibrate": self.Calibrate_Prepare() elif self.var._calibrate == u"Shock": self.Do_Shock_Prepare() def run(self): self.set_item_onset() if self.var._productName == u"DUMMY": if self.var._calibrate == u"Shock": oslogger.info('dummy shock: {} for {} ms'.format(self.var._value, self.var._duration) ) else: self.Calibrate_Run() else: #self.EE.Select(self.PATH) if self.var._calibrate == u"Calibrate": self.Calibrate_Run() elif self.var._calibrate == u"Shock": self.Do_Shock_Run() return True def Do_Shock_Prepare(self): pass def Do_Shock_Run(self): try: self.experiment.get("ShockerCalibration") except: oslogger.error("No calibration step taken: First run a Shocker in calibration mode!") return if (self.var._productName == u"DUMMY"): oslogger.info("In (Dummy) Shock: shocking with value: " + str(self.var._value)) else: try: lst = self.experiment.get("lastShockTime") except: lst = 0; td = time.time() - lst # This line is to prevent the possibility to shock if the previous shock was less then the minimum time ago if (td > self.var._min_intershock_interval): oslogger.info("In (Hardware) Shock: shocking with value: " + str(math.floor((self.var._value/100.0) * self.experiment.get("ShockerCalibration")))) self.EE.SetLines(0) self.EE.PulseLines(math.floor((self.var._value/100.0) * self.experiment.get("ShockerCalibration")), self.var._duration) # TODO: mAh = round((self.var._value/100.0) * self.experiment.get("ShockermAhCalibration"),2) self.experiment.set("lastShockTime", time.time()) self.experiment.set("BinaryShockValue", math.floor((self.var._value/100.0) * self.experiment.get("ShockerCalibration"))) self.experiment.set("ShockPercValue", self.var._value) self.experiment.set("ShockMahValue", mAh) else: oslogger.warning("In Shock: the shock came too early: please don't give shocks in rapid succession!") def Calibrate_Run(self): slmouse = mouse(self.experiment, timeout=20, visible=True) slmouse.show_cursor(True) slmouse.set_pos(pos=(0,0)) xperc = 0; self.canvas['Slider'].w = (xperc / 100) * ((2 * self.canvas.width / 2.2) - 12) self.canvas.show() while True: # Poll the mouse for buttonclicks button = None while button == None: button, position, timestamp = slmouse.get_click() button = None pos, mtime = slmouse.get_pos() x, y = pos if (x, y) in self.canvas['SliderBox']: xperc = min((x + self.canvas.width / 2.2) / (2 * ((self.canvas.width / 2.2) - 6)) * 100.0,100) self.canvas['Slider'].w = (xperc / 100) * ((2 * self.canvas.width / 2.2) - 12) self.canvas['ValuePerc'].text = "("+str(round(xperc,1)) + "%)" self.canvas['ValuemAh'].text = str(round(5*(xperc/100.0),1)) + "mAh" self.canvas.show() if (x, y) in self.canvas['TestBox']: #self.EE.SetLines(0) self.EE.PulseLines(math.floor((xperc/100.0) * 255), self.var._duration) self.canvas['TestBox'].color = "blue" self.canvas.show() time.sleep(8) self.canvas['TestBox'].color = "red" self.canvas.show() if (x, y) in self.canvas['OKBox']: self.var.ShockerCalibrationBinvalue = math.floor((xperc/100.0) * 255) self.var.ShockerCalibrationmAhvalue = round(5*(xperc/100.0),1) print((self.var.ShockerCalibrationBinvalue,self.var.ShockerCalibrationmAhvalue)) self.experiment.set("ShockerCalibration", self.var.ShockerCalibrationBinvalue) self.experiment.set("ShockermAhCalibration", self.var.ShockerCalibrationmAhvalue) break def Calibrate_Prepare(self): self.canvas = Canvas(self.experiment) self.canvas.set_bgcolor("black") self.canvas.clear() self.canvas['Title'] = RichText("Tactile Stimulator Calibration", center = True , x = 0 , y = -int(self.canvas.height/3) , color = "white" , font_family = "mono", font_size = 28) self.canvas['Instruction'] = RichText("Point at the desired value position"\ " on the axis and click ... "\ "Then click TEST",\ center = True, x = 0, y = -int(self.canvas.height / 8), color = "white") # Draw the slider axis self.canvas.set_fgcolor("white") self.canvas['SliderBox'] = Rect(-self.canvas.width / 2.2, 0, 2 * self.canvas.width / 2.2, 28, fill=False) self.canvas.set_fgcolor("white") self.canvas['Slider'] = Rect((-self.canvas.width / 2.2) + 6, 6, (2 * self.canvas.width / 2.2) - 12, 16, fill=True) self.canvas['TestBox'] = Rect((-self.canvas.width / 3), self.canvas.height / 4, self.canvas.width / 10, self.canvas.height / 10, fill=True, color = "Red") self.canvas['TestText'] = RichText("Test", x=(-self.canvas.width / 3)+(self.canvas.width / 20), y=(self.canvas.height / 4)+(self.canvas.height / 20), color = "black") self.canvas['OKBox'] = Rect((self.canvas.width / 3), self.canvas.height / 4, -self.canvas.width / 10, self.canvas.height / 10, fill=True, color = "Green") self.canvas['OKText'] = RichText("OK", x=(self.canvas.width / 3)-(self.canvas.width / 20), y=(self.canvas.height / 4)+(self.canvas.height / 20), color = "black") self.canvas['ValuemAh'] = RichText(str(round(0,3)) + "mAh", x=0, y=-(self.canvas.height / 4)+(self.canvas.height / 20), color = "green") self.canvas['ValuePerc'] = RichText("("+str(round(0)) + "%)", x=0, y=-(self.canvas.height / 4)+(self.canvas.height / 12), color = "green")