def prepare(self): """The preparation phase of the plug-in.""" item.item.prepare(self) try: if self.get(u"jitter_mode") == u"Uniform": self._duration = int(self.get(u"duration") + \ random.uniform(0, self.get(u"jitter")) - \ self.get(u"jitter")*0.5) elif self.get(u"jitter_mode") == u"Std. Dev.": self._duration = int(self.get(u"duration") + \ random.gauss(0, self.get(u"jitter"))) else: raise exceptions.runtime_error( \ u'Unknown jitter mode in advanced_delay %s' % self.name) except: raise exceptions.runtime_error( \ u"Invalid duration and/ or jitter in advanced_delay '%s'" % \ self.name) if self._duration < 0: self._duration = 0 self.experiment.set(u"delay_%s" % self.name, self._duration) debug.msg(u"delay for %s ms" % self._duration)
def get_file(self, path): """<DOC> Returns the path to a file. First checks if the file is in the file pool # and then the folder of the current experiment (if any). Otherwise, # simply returns the path. Arguments: path -- The filename. Returns: The full path to the file. Example: >>> image_path = exp.get_file('my_image.png') >>> my_canvas = exp.offline_canvas() >>> my_canvas.image(image_path) </DOC>""" if not isinstance(path, basestring): raise exceptions.runtime_error( \ u"A string should be passed to experiment.get_file(), not '%s'" \ % path) if isinstance(path, str): path = path.decode(self.encoding, errors=u'ignore') if path.strip() == u'': raise exceptions.runtime_error( \ u"An empty string was passed to experiment.get_file(). Please specify a valid filename.") if os.path.exists(os.path.join(self.pool_folder, path)): return os.path.join(self.pool_folder, path) elif self.experiment_path != None and os.path.exists(os.path.join( \ self.experiment_path, path)): return os.path.join(self.experiment_path, path) else: return path
def prepare(self): """Prepare for the run phase""" item.item.prepare(self) # Prepare the form try: cols = [float(i) for i in unicode(self.cols).split(';')] rows = [float(i) for i in unicode(self.rows).split(';')] margins = [float(i) for i in unicode(self.margins).split(';')] except: raise exceptions.runtime_error( \ _('cols, rows, and margins should be numeric values separated by a semi-colon')) self._form = widgets.form(self.experiment, cols=cols, rows=rows, \ margins=margins, spacing=self.spacing, theme=self.theme, item=self) # Prepare the widgets for _w in self._widgets: # Evaluate all keyword arguments w = {} for var, val in _w.iteritems(): w[var] = self.eval_text(val) _type = w['type'] col = w['col'] row = w['row'] colspan = w['colspan'] rowspan = w['rowspan'] del w['type'] del w['col'] del w['row'] del w['colspan'] del w['rowspan'] # Translate paths into full file names if 'path' in w: w['path'] = self.experiment.get_file(w['path']) # Process focus keyword if 'focus' in w: focus = True del w['focus'] else: focus = False # Create the widget and add it to the form try: _w = eval('widgets.%s(self._form, **w)' % _type) except Exception as e: raise exceptions.runtime_error( \ 'Failed to create widget "%s": %s' % (_type, e)) self._form.set_widget(_w, (col, row), colspan=colspan, \ rowspan=rowspan) # Add as focus widget if focus: self.focus_widget = _w return True
def start_recording(self): """<DOC> Starts recording of gaze samples. Exceptions: Raises an exceptions.runtime_error on failure. </DOC>""" self.recording = True i = 0 while True: # Params: write samples, write event, send samples, send events error = pylink.getEYELINK().startRecording(1, 1, 1, 1) if not error: break if i > self.MAX_TRY: raise exceptions.runtime_error( \ u'Failed to start recording (startRecording error)') i += 1 print u'libeyelink.start_recording(): failed to start recording (attempt %d of %d)' \ % (i, self.MAX_TRY) pylink.msecDelay(100) # Don't know what this is pylink.pylink.beginRealTimeMode(100) # Wait for a bit until samples start coming in (I think?) if not pylink.getEYELINK().waitForBlockStart(100, 1, 0): raise exceptions.runtime_error( \ u'Failed to start recording (waitForBlockStart error)')
def get(self, var): """<DOC> Return the value of a variable. Checks first if the variable exists 'locally' in the item and, if not, checks if the vaiable exists 'globally' in the experiment. Raises a runtime_error if the variable is not found. Arguments: var -- the name of the variable Returns: The value </DOC>""" if hasattr(self, var): val = eval("self.%s" % var) else: try: val = eval("self.experiment.%s" % var) except: raise exceptions.runtime_error( \ "Variable '%s' is not set in item '%s'.<br /><br />You are trying to use a variable that does not exist. Make sure that you have spelled and capitalized the variable name correctly. You may wish to use the variable inspector (Control + I) to find the intended variable." \ % (var, self.name)) # Process variables, indicated like [varname] if self.experiment.running and type(val) == str and len(val) > 3 and \ val[0] == "[" and val[-1] == "]": if val[1:-1] == var: raise exceptions.runtime_error( \ "Variable '%s' is defined in terms of itself (e.g., 'var = [var]') in item '%s'" \ % (var, self.name)) val = self.get(val[1:-1]) return val
def get(self, var): """ Retrieve a variable. First check the item, and fall back to the experiment. """ if hasattr(self, var): val = eval("self.%s" % var) else: try: val = eval("self.experiment.%s" % var) except: raise exceptions.runtime_error( "Variable '%s' is not set in item '%s'.<br /><br />You are trying to use a variable that does not exist. Make sure that you have spelled and capitalized the variable name correctly. You may wish to use the variable inspector (Control + I) to find the intended variable." % (var, self.name)) # Process variables, indicated like [varname] if self.experiment.running and type(val) == str and len( val) > 3 and val[0] == "[" and val[-1] == "]": if val[1:-1] == var: raise exceptions.runtime_error( "Variable '%s' is defined in terms of itself (e.g., 'var = [var]') in item '%s'" % (var, self.name)) val = self.get(val[1:-1]) return val
def __init__(self, experiment, dev=None): """<DOC> Constructor. Connects to the SR Box. Arguments: experiment -- Opensesame experiment. Keywords arguments: dev -- The srbox device port or None for auto-detect (default=None). </DOC>""" self.experiment = experiment self._srbox = None # If a device has been specified, use it if dev not in (None, "", "autodetect"): try: self._srbox = serial.Serial(dev, timeout=0, baudrate=19200) except Exception as e: raise exceptions.runtime_error( \ "Failed to open device port '%s' in libsrbox: '%s'" \ % (dev, e)) else: # Else determine the common name of the serial devices on the # platform and find the first accessible device. On Windows, # devices are labeled COM[X], on Linux there are labeled /dev/tty[X] if os.name == "nt": for i in range(255): try: dev = "COM%d" % i self._srbox = serial.Serial(dev, timeout=0, \ baudrate=19200) break except Exception as e: self._srbox = None pass elif os.name == "posix": for path in os.listdir("/dev"): if path[:3] == "tty": try: dev = "/dev/%s" % path self._srbox = serial.Serial(dev, timeout=0, \ baudrate=19200) break except Exception as e: self._srbox = None pass else: raise exceptions.runtime_error( \ "libsrbox does not know how to auto-detect the SR Box on your platform. Please specify a device.") if self._srbox == None: raise exceptions.runtime_error( \ "libsrbox failed to auto-detect an SR Box. Please specify a device.") debug.msg("using device %s" % dev) # Turn off all lights if self._srbox != None: self._srbox.write('\x64')
def prepare(self): """ Prepare the sequence Returns: True on success, False on failure """ item.item.prepare(self) if self.get("flush_keyboard") == "yes": # Create a keyboard to flush responses at the start of the run phase self._keyboard = openexp.keyboard.keyboard(self.experiment) else: self._keyboard = None self._items = [] for _item, cond in self.items: if _item not in self.experiment.items: raise exceptions.runtime_error( \ "Could not find item '%s', which is called by sequence item '%s'" \ % (_item, self.name)) if not self.experiment.items[_item].prepare(): raise exceptions.runtime_error( \ "Failed to prepare item '%s', which is called by sequence item '%s'" \ % (_item, self.name)) self._items.append((_item, self.compile_cond(cond))) return True
def set_backdrop(self, canvas, prepped_backdrop_image=None): """<DOC> Set backdrop image of Eyelink computer. For performance, it can be useful sometimes to already prepare the image to send to the eyelink in the prepare phase. This prepared image can be optionally supplied in prepped_backdrop_image (a 3 dimensional list with hor-lines x ver-lines x pixels) Otherwise, supplying the canvas is enough and this function will take care of the conversion Arguments: canvas -- an openexp canvas Keyword arguments: prepped_backdrop_image -- an image in the (list x list x tuple) format required by pylink </DOC>""" if self.experiment.canvas_backend != 'legacy': raise exceptions.runtime_error( \ 'prepare_backdrop requires the legacy back-end') if not prepped_backdrop_image is None: if type(prepped_backdrop_image) == list: width = len(prepped_backdrop_image[0]) height = len(prepped_backdrop_image) pylink.getEYELINK().bitmapBackdrop(width,height,prepped_backdrop_image,0,0,width,height,0,0,pylink.BX_MAXCONTRAST) else: raise exceptions.runtime_error("Backdrop image has invalid format") else: backdrop = prepare_backdrop(canvas) width = canvas.surface.get_width() height = canvas.surface.get_height() pylink.getEYELINK().bitmapBackdrop(width,height,backdrop,0,0,width,height,0,0,pylink.BX_MAXCONTRAST)
def prepare(self): """Prepares for playback.""" item.item.prepare(self) if self.sample.strip() == u'': raise exceptions.runtime_error( \ u'No sample has been specified in sampler "%s"' % self.name) sample = self.experiment.get_file(self.eval_text(self.sample)) if debug.enabled: self.sampler = openexp.sampler.sampler(self.experiment, sample) else: try: self.sampler = openexp.sampler.sampler(self.experiment, sample) except Exception as e: raise exceptions.runtime_error( \ u'Failed to load sample in sampler "%s": %s' % (self.name, \ e)) pan = self.get(u'pan') if pan == -20: pan = u'left' elif pan == 20: pan = u'right' self.sampler.pan(pan) self.sampler.volume(self.get(u'volume')) self.sampler.pitch(self.get(u'pitch')) self.sampler.fade_in(self.get(u'fade_in')) self.sampler.stop_after(self.get(u'stop_after')) generic_response.generic_response.prepare(self)
def float_list(l, desc, min_len=None, max_len=None): """ Converts a variable to a list of floats if possible. Arguments: a -- The variable to convert. desc -- A description to clarify the runtime_error. Keyword arguments: min_len -- The minimum length of the list. (default=None) max_len -- The maximum length of the list. (default=None) Raises: A runtime_error if the variable could not be converted. Returns: A list of floats. """ try: l = list(l) except: raise runtime_error( \ u'Expecting a list or compatible type not "%s" for "%s"' % (l, \ desc)) if min_len != None and len(l) < min_len: raise runtime_error( \ u'Expecting a list of at least %d items for "%s"' % (min_len, desc)) if max_len != None and len(l) > max_len: raise runtime_error( \ u'Expecting a list of at most %d items for "%s"' % (max_len, desc)) return l
def prepare(self): """ Prepare the item. In this case this means drawing a fixation dot to an offline canvas. """ # Pass the word on to the parent item.item.prepare(self) # Create an eyelink instance if it doesn't exist yet. Libeyelink is # dynamically loaded if not hasattr(self.experiment, "eyelink"): raise exceptions.runtime_error( "Please connect to the eyelink using the the eyelink_calibrate plugin before using any other eyelink plugins" ) # Use static numbers to avoid importing pylink if self.event == self._ssacc: self._event = 5 # pylink.STARTSACC elif self.event == self._esacc: self._event = 6 # pylink.ENDSACC elif self.event == self._sfix: self._event = 7 # pylink.STARTFIX elif self.event == self._efix: self._event = 8 # pylink.ENDFIX elif self.event == self._sblink: self._event = 3 # pylink.STARTBLINK elif self.event == self._eblink: self._event = 4 # pylink.ENDBLINK else: raise exceptions.runtime_error("An unknown event was specified in eyelink_wait item '%s'" % self.name) # Report success return True
def prepare(self): """ Prepare the sequence Returns: True on success, False on failure """ item.item.prepare(self) if self.get("flush_keyboard") == "yes": # Create a keyboard to flush responses at the start of the run phase self._keyboard = openexp.keyboard.keyboard(self.experiment) else: self._keyboard = None self._items = [] for _item, cond in self.items: if _item not in self.experiment.items: raise exceptions.runtime_error( \ "Could not find item '%s', which is called by sequence item '%s'" \ % (_item, self.name)) if not self.experiment.items[_item].prepare(): raise exceptions.runtime_error( \ "Failed to prepare item '%s', which is called by sequence item '%s'" \ % (_item, self.name)) self._items.append( (_item, self.compile_cond(cond)) ) return True
def get(self, var, _eval=True): """<DOC> Return the value of an OpenSesame variable. Checks first if the variable exists 'locally' in the item and, if not, checks if the variable exists 'globally' in the experiment. The type of the value that is returned can be int, float, or unicode (string). The appropriate type is automatically selected, e.g. '10' is returned as int, '10.1' as float, and 'some text' as unicode. The _eval parameter is used to specify whether the value of the variable should be evaluated, in case it contains references to other variables. This is best illustrated by example: >>> exp.set('var1', 'I like [var2]') >>> exp.set('var2', 'OpenSesame') >>> print self.get('var1') # prints 'I like OpenSesame' >>> print self.get('var1', _eval=False) # prints 'I like [var2]' Example: >>> if self.get('cue') == 'valid': >>> print 'This is a validly cued trial' Arguments: var -- the name of an OpenSesame variable _eval -- indicates whether the variable should be evaluated, i.e. whether containing variables should be processed (default=True) Exceptions: a runtime_error is raised if the variable is not found Returns: The value </DOC>""" var = self.unistr(var) # Avoid recursion if var == self._get_lock: raise exceptions.runtime_error( \ u"Recursion detected! Is variable '%s' defined in terms of itself (e.g., 'var = [var]') in item '%s'" \ % (var, self.name)) # Get the variable if hasattr(self, var): val = getattr(self, var) else: try: val = getattr(self.experiment, var) except: raise exceptions.runtime_error( \ u"Variable '%s' is not set in item '%s'.<br /><br />You are trying to use a variable that does not exist. Make sure that you have spelled and capitalized the variable name correctly. You may wish to use the variable inspector (Control + I) to find the intended variable." \ % (var, self.name)) if _eval: # Lock to avoid recursion and start evaluating possible variables self._get_lock = var val = self.eval_text(val) self._get_lock = None # Done! return val
def __init__(self, experiment, dev=None): """<DOC> Constructor. Connects to the SR Box. Arguments: experiment -- opensesame experiment Keywords arguments: dev -- the srbox device port or None for auto-detect (default=None) </DOC>""" self.experiment = experiment self._srbox = None # If a device has been specified, use it if dev not in (None, "", "autodetect"): try: self._srbox = serial.Serial(dev, timeout=0, baudrate=19200) except Exception as e: raise exceptions.runtime_error( \ "Failed to open device port '%s' in libsrbox: '%s'" \ % (dev, e)) else: # Else determine the common name of the serial devices on the # platform and find the first accessible device. On Windows, # devices are labeled COM[X], on Linux there are labeled /dev/tty[X] if os.name == "nt": for i in range(255): try: dev = "COM%d" % i self._srbox = serial.Serial(dev, timeout=0, \ baudrate=19200) break except Exception as e: self._srbox = None pass elif os.name == "posix": for path in os.listdir("/dev"): if path[:3] == "tty": try: dev = "/dev/%s" % path self._srbox = serial.Serial(dev, timeout=0, \ baudrate=19200) break except Exception as e: self._srbox = None pass else: raise exceptions.runtime_error("libsrbox does not know how to auto-detect the SR Box on your platform. Please specify a device.") if self._srbox == None: raise exceptions.runtime_error("libsrbox failed to auto-detect an SR Box. Please specify a device.") debug.msg("using device %s" % dev) # Turn off all lights if self._srbox != None: self._srbox.write('\x64')
def run(self): """ Run the item. """ # Set the onset time self.set_item_onset() # Flush the keyboard so we can use the escape key openexp.response.flush() # If no start response interval has been set, set it to the onset of # the current response item if self.experiment.start_response_interval == None: self.experiment.start_response_interval = self.get("time_%s" % self.name) if self.has("dummy") and self.get("dummy") == "yes": # In dummy mode, we simply take the numeric keys from the keyboard instead of an sr-box self.experiment.end_response_interval, resp = self._resp_func(None, self._timeout) try: resp = int(openexp.response.key_name(resp)) except: raise exceptions.runtime_error("An error occured in srbox '%s': Only number keys are accepted in dummy mode" % self.name) else: # Get the response try: srbox_send(self._lights, self.experiment.debug) srbox_start(self.experiment.debug) self.experiment.end_response_interval, resp = self._resp_func(self._allowed_responses, self._timeout) srbox_stop(self.experiment.debug) except Exception as e: raise exceptions.runtime_error("An error occured in srbox '%s': %s." % (self.name, e)) # Do some bookkeeping self.experiment.response_time = self.experiment.end_response_interval - self.experiment.start_response_interval self.experiment.total_response_time += self.experiment.response_time self.experiment.total_responses += 1 if self.experiment.debug: print "srbox.run(): received %s" % resp if type(resp) == list: self.experiment.response = resp[0] else: self.experiment.response = resp if self.has("correct_response"): correct_response = self.get("correct_response") else: correct_response = "undefined" self.process_response(correct_response) # Report success return True
def prepare(self): """Prepares the item.""" # Pass the word on to the parent item.item.prepare(self) # Prepare the allowed responses if self.has("allowed_responses"): self._allowed_responses = [] for r in self.unistr(self.get("allowed_responses")).split(";"): if r.strip() != "": try: r = int(r) except: raise exceptions.runtime_error( \ "'%s' is not a valid response on your joystick/gamepad. Expecting a number in the range of 1 to the amount of buttons." \ % (r,self.name)) if r < 0 or r > 255: raise exceptions.runtime_error( \ "'%s' is not a valid response on your joystick/gamepad. Expecting a number in the range of 1 to the amount of buttons." \ % (r, self.name)) self._allowed_responses.append(r) if len(self._allowed_responses) == 0: self._allowed_responses = None else: self._allowed_responses = None debug.msg("allowed responses has been set to %s" % self._allowed_responses) # In case of dummy-mode: self._keyboard = openexp.keyboard.keyboard(self.experiment) if self.has("_dummy") and self.get("_dummy") == "yes": self._resp_func = self._keyboard.get_key # Not in dummy-mode: else: # Prepare joybuttonlist and timeout joybuttonlist = self.get("_allowed_responses") timeout = self.get("timeout") # Dynamically load a joystick instance if not hasattr(self.experiment, "joystick"): path = os.path.join(os.path.dirname(__file__), "libjoystick.py") _joystick = imp.load_source("libjoystick", path) self.experiment.joystick = _joystick.libjoystick( self.experiment, [joybuttonlist, timeout]) #self.experiment.cleanup_functions.append(self.close) # Prepare auto response if self.experiment.auto_response: self._resp_func = self.auto_responder else: self._resp_func = self.experiment.joystick.get_joybutton self.prepare_timeout()
def run(self): """ Run the loop """ # First generate a list l = [] j = 0 # Walk through all complete repeats whole_repeats = int(self.repeat) for j in range(whole_repeats): for i in range(self.cycles): l.append((j, i)) # Add the leftover repeats partial_repeats = self.repeat - whole_repeats if partial_repeats > 0: all_cycles = range(self.cycles) sample = random.sample(all_cycles, int(len(all_cycles) * partial_repeats)) for i in sample: l.append((j, i)) # Randomize the list if necessary if self.order == "random": random.shuffle(l) # Walk through the list for j, i in l: if self.item in self.experiment.items: # Set the variables from the matrix if i in self.matrix: for var in self.matrix[i]: val = self.matrix[i][var] if type(val) == str: exec("self.experiment.%s = \"%s\"" % (var, val)) else: exec("self.experiment.%s = %s" % (var, val)) # Flush the responses to catch escape presses openexp.response.flush() if eval("self.experiment.items[\"%s\"].prepare()" % self.item): exec("self.experiment.items[\"%s\"].run()" % self.item) else: raise exceptions.runtime_error( "Failed to prepare item '%s', which is called by loop item '%s'" % (self.item, self.name)) else: raise exceptions.runtime_error( "Could not find item '%s', which is called by loop item '%s'" % (self.item, self.name)) return True
def run(self): """ Run the loop """ # First generate a list l = [] j = 0 # Walk through all complete repeats whole_repeats = int(self.repeat) for j in range(whole_repeats): for i in range(self.cycles): l.append((j, i)) # Add the leftover repeats partial_repeats = self.repeat - whole_repeats if partial_repeats > 0: all_cycles = range(self.cycles) sample = random.sample(all_cycles, int(len(all_cycles) * partial_repeats)) for i in sample: l.append((j, i)) # Randomize the list if necessary if self.order == "random": random.shuffle(l) # Walk through the list for j, i in l: if self.item in self.experiment.items: # Set the variables from the matrix if i in self.matrix: for var in self.matrix[i]: val = self.matrix[i][var] if type(val) == str: exec('self.experiment.%s = "%s"' % (var, val)) else: exec("self.experiment.%s = %s" % (var, val)) # Flush the responses to catch escape presses openexp.response.flush() if eval('self.experiment.items["%s"].prepare()' % self.item): exec('self.experiment.items["%s"].run()' % self.item) else: raise exceptions.runtime_error( "Failed to prepare item '%s', which is called by loop item '%s'" % (self.item, self.name) ) else: raise exceptions.runtime_error( "Could not find item '%s', which is called by loop item '%s'" % (self.item, self.name) ) return True
def prepare(self): """ Prepare a canvas Returns: True """ # Pass the word on to the parent item.item.prepare(self) # Create an offline canvas self.c = openexp.canvas.canvas(self.experiment, self.get("background"), self.get("foreground")) self.c.set_font(self.get("font_family"), self.get("font_size")) content = self.experiment.unsanitize(self.eval_text(self.get("content"))).split("\n") # Do line wrapping _content = [] for line in content: while len(line) > self.get("maxchar"): i = line.rfind(" ", 0, self.get("maxchar")) if i < 0: raise exceptions.runtime_error("Failed to do line wrapping in text_display '%s'. Perhaps one of the words is longer than the maximum number of characters per line?" % self.name) _content.append(line[:i]) line = line[i+1:] _content.append(line) content = _content if self.get("align") != "center": try: max_width = 0 max_height = 0 for line in content: size = self.c.text_size(line) max_width = max(max_width, size[0]) max_height = max(max_height, size[1]) except: raise exceptions.runtime_error("Failed to use alignment '%s' in text_display '%s'. Perhaps this alignment is not supported by the back-end. Please use 'center' alignment." % (self.get("align"), self.name)) line_nr = -len(content) / 2 for line in content: if self.get("align") == "center": self.c.textline(line, line_nr) elif self.get("align") == "left": self.c.text(line, False, self.c.xcenter() - 0.5 * max_width, self.c.ycenter() + 1.5 * line_nr * max_height) else: width = self.c.text_size(line)[0] self.c.text(line, False, self.c.xcenter() + 0.5 * max_width - width, self.c.ycenter() + 1.5 * line_nr * max_height) line_nr += 1 generic_response.generic_response.prepare(self) return True
def run(self): """ Run the item Returns: True on success, False on failure """ # Set the onset time self.set_item_onset() # Flush the keyboard so we can use the escape key self._keyboard.flush() # If no start response interval has been set, set it to the onset of # the current response item if self.experiment.start_response_interval == None: self.experiment.start_response_interval = self.get("time_%s" \ % self.name) if self.has("dummy") and self.get("dummy") == "yes": # In dummy mode, we simply take the numeric keys from the keyboard resp, self.experiment.end_response_interval = self._resp_func( \ None, self._timeout) try: resp = self._keyboard.to_chr(resp) if resp != "timeout": resp = int(resp) except: raise exceptions.runtime_error( \ "An error occured in srbox '%s': Only number keys are accepted in dummy mode" \ % self.name) else: # Get the response try: self.experiment.srbox.send(self._lights) self.experiment.srbox.start() resp, self.experiment.end_response_interval = \ self._resp_func(self._allowed_responses, self._timeout) self.experiment.srbox.stop() except Exception as e: raise exceptions.runtime_error( \ "An error occured in srbox '%s': %s." % (self.name, e)) debug.msg("received %s" % resp) if type(resp) == list: self.experiment.response = resp[0] else: self.experiment.response = resp generic_response.generic_response.response_bookkeeping(self) # Report success return True
def prepare(self): """Prepares the item.""" # Pass the word on to the parent item.item.prepare(self) # Prepare the allowed responses if self.has("allowed_responses"): self._allowed_responses = [] for r in self.unistr(self.get("allowed_responses")).split(";"): if r.strip() != "": try: r = int(r) except: raise exceptions.runtime_error( \ "'%s' is not a valid response on your joystick/gamepad. Expecting a number in the range of 1 to the amount of buttons." \ % (r,self.name)) if r < 0 or r > 255: raise exceptions.runtime_error( \ "'%s' is not a valid response on your joystick/gamepad. Expecting a number in the range of 1 to the amount of buttons." \ % (r, self.name)) self._allowed_responses.append(r) if len(self._allowed_responses) == 0: self._allowed_responses = None else: self._allowed_responses = None debug.msg("allowed responses has been set to %s" % self._allowed_responses) # In case of dummy-mode: self._keyboard = openexp.keyboard.keyboard(self.experiment) if self.has("_dummy") and self.get("_dummy") == "yes": self._resp_func = self._keyboard.get_key # Not in dummy-mode: else: # Prepare joybuttonlist and timeout joybuttonlist = self.get("_allowed_responses") timeout = self.get("timeout") # Dynamically load a joystick instance if not hasattr(self.experiment, "joystick"): path = os.path.join(os.path.dirname(__file__), "libjoystick.py") _joystick = imp.load_source("libjoystick", path) self.experiment.joystick = _joystick.libjoystick(self.experiment, [joybuttonlist, timeout]) #self.experiment.cleanup_functions.append(self.close) # Prepare auto response if self.experiment.auto_response: self._resp_func = self.auto_responder else: self._resp_func = self.experiment.joystick.get_joybutton self.prepare_timeout()
def prepare(self): """ Prepare the sampler """ item.item.prepare(self) sample = self.experiment.get_file(self.get("sample")) if sample == "": raise exceptions.runtime_error( "No sample has been specified in sampler '%s'" % self.name) try: self.sampler = openexp.sampler.sampler(sample) except Exception as e: raise exceptions.runtime_error( "Failed to load sample in sampler '%s': %s" % (self.name, e)) pan = self.get("pan") if pan == -20: pan = "left" elif pan == 20: pan = "right" self.sampler.pan(pan) self.sampler.volume(self.get("volume")) self.sampler.pitch(self.get("pitch")) self.sampler.fade_in(self.get("fade_in")) self.sampler.stop_after(self.get("stop_after")) dur = self.get("duration") if dur == "sound": self.block = True self._duration_func = self.dummy elif dur == "keypress": self._duration_func = self.experiment.wait elif dur == "mouseclick": self._duration_func = openexp.response.get_mouse else: try: self._duration = int(self.get("duration")) except: raise exceptions.runtime_error( "Invalid duration '%s' in sketchpad '%s'. Expecting a positive number or 'keypress'." % (self.get("duration"), self.name)) if self._duration == 0: self._duration_func = self.dummy else: self._duration_func = self.sleep_for_duration return True
def prepare_timeout(self): """Prepares the response timeout""" if self.get("timeout") == "infinite": self._timeout = None else: try: self._timeout = int(self.get("timeout")) except: raise exceptions.runtime_error("'%s' is not a valid timeout in keyboard_response '%s'. Expecting a positive integer or 'infinite'." % (self.get("timeout"), self.name)) if self._timeout < 0: raise exceptions.runtime_error("'%s' is not a valid timeout in keyboard_response '%s'. Expecting a positive integer or 'infinite'." % (self.get("timeout"), self.name))
def run(self): """ Run the item Returns: True on succes, False on failure """ # Set the onset time self.set_item_onset() # Flush keyboard, so the escape key can be used self._keyboard.flush() # If no start response interval has been set, set it to the onset of # the current response item if self.experiment.start_response_interval == None: self.experiment.start_response_interval = self.get("time_%s" \ % self.name) if self.has("_dummy") and self.get("_dummy") == "yes": # In dummy mode, no one can hear you scream! Oh, and we simply # take input from the keyboard resp, self.experiment.end_response_interval = self._resp_func( \ None, self._timeout) try: resp = self._keyboard.to_chr(resp) if resp != "timeout": resp = int(resp) except: raise exceptions.runtime_error( \ "An error occured in joystick '%s': Only number keys are accepted in dummy mode" \ % self.name) else: # Get the response try: resp, self.experiment.end_response_interval = \ self._resp_func(self._allowed_responses, self._timeout) except Exception as e: raise exceptions.runtime_error( \ "An error occured in joystick '%s': '%s." % (self.name, e)) debug.msg("received %s" % resp) self.experiment.response = resp generic_response.generic_response.response_bookkeeping(self) # Report succes return True
def prepare(self): """ Opens the video file for playback and compiles the event handler code Returns: True on success, False on failure """ # Pass the word on to the parent item.item.prepare(self) # Give a sensible error message if the proper back-end has not been selected if not self.has( "canvas_backend") or self.get("canvas_backend") != "legacy": raise exceptions.runtime_error( "The media_player plug-in requires the legacy back-end. Sorry!" ) # Byte-compile the event handling code (if any) if self.event_handler.strip() != "": self._event_handler = compile(self.event_handler, "<string>", "exec") else: self._event_handler = None # Determine when the event handler should be called if self.event_handler_trigger == "on keypress": self._event_handler_always = False else: self._event_handler_always = True # Find the full path to the video file. This will point to some # temporary folder where the file pool has been placed path = self.experiment.get_file( str(self.eval_text(self.get("video_src")))) if self.experiment.debug: print "media_player.prepare(): loading '%s'" % path # Open the video file if not os.path.exists(path) or str( self.eval_text("video_src")).strip() == "": raise exceptions.runtime_error( "Video file '%s' was not found in video_player '%s' (or no video file was specified)." % (os.path.basename(path), self.name)) self.load(path) # Report success return True
def prepare(self): """ Prepare the sampler """ item.item.prepare(self) sample = self.experiment.get_file(self.get("sample")) if sample == "": raise exceptions.runtime_error("No sample has been specified in sampler '%s'" % self.name) try: self.sampler = openexp.sampler.sampler(sample) except Exception as e: raise exceptions.runtime_error("Failed to load sample in sampler '%s': %s" % (self.name, e)) pan = self.get("pan") if pan == -20: pan = "left" elif pan == 20: pan = "right" self.sampler.pan(pan) self.sampler.volume(self.get("volume")) self.sampler.pitch(self.get("pitch")) self.sampler.fade_in(self.get("fade_in")) self.sampler.stop_after(self.get("stop_after")) dur = self.get("duration") if dur == "sound": self.block = True self._duration_func = self.dummy elif dur == "keypress": self._duration_func = self.experiment.wait elif dur == "mouseclick": self._duration_func = openexp.response.get_mouse else: try: self._duration = int(self.get("duration")) except: raise exceptions.runtime_error("Invalid duration '%s' in sketchpad '%s'. Expecting a positive number or 'keypress'." % (self.get("duration"), self.name)) if self._duration == 0: self._duration_func = self.dummy else: self._duration_func = self.sleep_for_duration return True
def run(self): """ Run the item Returns: True on succes, False on failure """ # Set the onset time self.set_item_onset() # Flush keyboard, so the escape key can be used self._keyboard.flush() # If no start response interval has been set, set it to the onset of # the current response item if self.experiment.start_response_interval == None: self.experiment.start_response_interval = self.get("time_%s" \ % self.name) if self.has("dummy") and self.get("dummy") == "yes": # In dummy mode, no one can hear you scream! Oh, and we simply # take input from the keyboard resp, self.experiment.end_response_interval = self._resp_func( \ None, self._timeout) try: resp = self._keyboard.to_chr(resp) if resp != "timeout": resp = int(resp) except: raise exceptions.runtime_error( \ "An error occured in joystick '%s': Only number keys are accepted in dummy mode" \ % self.name) else: # Get the response try: resp, self.experiment.end_response_interval = \ self._resp_func(self._allowed_responses, self._timeout) except Exception as e: raise exceptions.runtime_error( \ "An error occured in joystick '%s': '%s." % (self.name, e)) debug.msg("received %s" % resp) self.experiment.response = resp generic_response.generic_response.response_bookkeeping(self) # Report succes return True
def prepare(self): """Prepare the boks""" item.item.prepare(self) self._keyboard = keyboard(self.experiment) # Prepare the device string if self.get(u'_dummy') == u'yes': dev = u'dummy' else: dev = self.get(u'dev') if dev == u'autodetect': dev = None # Dynamically load a boks instance if not hasattr(self.experiment, u'boks'): self.experiment.boks = libboks.libboks(dev, experiment= \ self.experiment) self.experiment.cleanup_functions.append(self.close) model, firmware_version = self.experiment.boks.info() self.experiment.set(u'boks_model', model) self.experiment.set(u'boks_firmware_version', firmware_version) # Prepare the allowed responses if self.has(u"allowed_responses"): self._allowed_responses = [] for r in self.unistr(self.get(u"allowed_responses")).split(u";"): if r.strip() != u"": try: r = int(r) except: raise exceptions.runtime_error( \ u"'%s' is not a valid response in boks '%s'. Expecting a number in the range 1 .. 4." \ % (r, self.name)) if r not in range(1,9): raise exceptions.runtime_error( \ u"'%s' is not a valid response in boks '%s'. Expecting a number in the range 1 .. 8." \ % (r, self.name)) self._allowed_responses.append(r) if len(self._allowed_responses) == 0: self._allowed_responses = None else: self._allowed_responses = None debug.msg(u"allowed responses set to %s" % self._allowed_responses) # Prepare the timeout self.prepare_timeout()
def get_file(self, path): """<DOC> Returns the path to a file. First checks if the file is in the file pool and then the folder of the current experiment (if any) Otherwise, simply return the path. Arguments: path -- the filename Returns: The full path to the file Example: >>> image_path = exp.get_file('my_image.png') >>> my_canvas = exp.offline_canvas() >>> my_canvas.image(image_path) </DOC>""" if type(path) not in(unicode, str): raise exceptions.runtime_error( \ "A string should be passed to experiment.get_file(), not '%s'" \ % path) if os.path.exists(os.path.join(self.pool_folder, path)): return os.path.join(self.pool_folder, path) elif self.experiment_path != None and os.path.exists(os.path.join( \ self.experiment_path, path)): return os.path.join(self.experiment_path, path) else: return path
def get_check(self, var, default=None, valid=None): """<DOC> Similar to get(), but falls back to a default if the variable has not been set. It also raises an error if the value is not part of the valid list. Arguments: var -- the name of the variable default -- a default 'fallback' value or None for no fallback, in which case an exception is rased if the value does not exist. valid -- a list of allowed values (or None for no restrictions). An exception is raised if the value is not an allowed value. Exceptions: Raises a runtime_error if the variable is not defined and there is no default value, or if the variable value is not part of the 'valid' list. Returns: The value </DOC>""" if default == None: val = self.get(var) elif self.has(var): val = self.get(var) else: val = default if valid != None and val not in valid: raise exceptions.runtime_error( \ "Variable '%s' is '%s', expecting '%s'" % (var, val, \ " or ".join(valid))) return val
def apply_cycle(self, cycle): """ Set all the loop variables according to the cycle Arguments: cycle -- the cycle nr """ # If the cycle is not defined, we don't have to do anything if cycle not in self.matrix: return # Otherwise apply all variables from the cycle for var in self.matrix[cycle]: val = self.matrix[cycle][var] # By starting with an "=" sign, users can incorporate a # Python statement, for example to call functions from # the random or math module if type(val) == unicode and len(val) > 1 and val[0] == "=": try: val = eval(val[1:]) except Exception as e: raise exceptions.runtime_error( \ "Failed to evaluate '%s' in loop item '%s': %s" \ % (val[1:], self.name, e)) # Set it! self.experiment.set(var, val)
def run(self): """ Run the item. """ self.set_item_onset() try: x = int(self.get("xpos", _eval=True)) y = int(self.get("ypos", _eval=True)) except: raise exceptions.runtime_error("Please use numeric values for the coordinates in eyetracker_drift_correct item '%s'" % self.name) if not self.has("coordinates") or self.get("coordinates") == "relative": x += self.get("width") / 2 y += self.get("height") / 2 # Draw a fixation cross c = openexp.canvas.canvas(self.experiment, self.get("background"), self.get("foreground")) c.set_penwidth(3) c.line(x - 5, y, x + 5, y) c.line(x, y - 5, x, y + 5) c.show() # Do drift correction while not self.experiment.eyetracker.drift_correction( (x, y), \ self.get("mode") == self._mode_auto): self.experiment.eyetracker.calibrate() c.show() # Report success return True
def usanitize(self, s, strict=False): """ Convert all special characters to U+XXXX notation, so that the resulting string can be treated as plain ASCII text. Arguments: s -- A unicode string to be santized Keyword arguments: strict -- if True, special characters are ignored rather than recoded (default=False) Returns: A regular Python string with all special characters replaced by U+XXXX notation """ if not isinstance(s, unicode): raise exceptions.runtime_error( \ u'usanitize() expects first argument to be unicode, not "%s"' \ % type(s)) _s = '' for ch in s: # Encode non ASCII and slash characters if ord(ch) > 127 or ord(ch) == 92: if not strict: _s += 'U+%.4X' % ord(ch) else: _s += ch return _s.replace(os.linesep, '\n')
def prepare(self): """ Prepare the item """ item.item.prepare(self) try: if self.get("jitter_mode") is "Uniform": self._duration = int( self.get("duration") + random.uniform(0, self.get("jitter")) - self.get("jitter") * 0.5) else: self._duration = int( self.get("duration") + random.gauss(0, self.get("jitter"))) except: raise exceptions.runtime_error( "Invalid duration and/ or jitter in advanced_delay '%s'" % self.name) if self._duration < 0: self._duration = 0 self.experiment.set("delay_%s" % self.name, self._duration) debug.msg("delay for %s ms" % self._duration) return True
def sample(self): """ Gets the most recent gaze sample from the eyelink Returns: A tuple (x, y) containing the coordinates of the sample Exceptions: Raises an exceptions.runtime_error on failure """ if not self.recording: raise exceptions.runtime_error( "Please start recording before collecting eyelink data") if self.eye_used == None: self.set_eye_used() s = pylink.getEYELINK().getNewestSample() if s != None: if self.eye_used == self.right_eye and s.isRightSample(): gaze = s.getRightEye().getGaze() elif self.eye_used == self.left_eye and s.isLeftSample(): gaze = s.getLeftEye().getGaze() return gaze
def apply_cycle(self, cycle): """ Sets all the loop variables according to the cycle. Arguments: cycle -- The cycle nr. """ # If the cycle is not defined, we don't have to do anything if cycle not in self.matrix: return # Otherwise apply all variables from the cycle for var in self.matrix[cycle]: val = self.matrix[cycle][var] # By starting with an "=" sign, users can incorporate a # Python statement, for example to call functions from # the random or math module if type(val) == unicode and len(val) > 1 and val[0] == "=": try: val = eval(val[1:]) except Exception as e: raise exceptions.runtime_error( \ "Failed to evaluate '%s' in loop item '%s': %s" \ % (val[1:], self.name, e)) # Set it! self.experiment.set(var, val)
def get_refs(self, text): """<DOC> Returns a list of variables that are referred to by the string. (E.g., 'this is a [variable]') Arguments: text -- a string of text Returns: A list of variable names or an empty list if the string contains no references. </DOC>""" # If the text is not a string, there cannot be any variables, # so return right away if type(text) != str: return [] l = [] s = "" start = -1 while True: # Find the start and end of a variable definition start = text.find("[", start + 1) if start < 0: break end = text.find("]", start + 1) if end < 0: raise exceptions.runtime_error( \ "Missing closing bracket ']' in string '%s', in item '%s'" \ % (text, self.name)) var = text[start + 1:end] l.append(var) var = var[end:] return l
def get_refs(self, text): """<DOC> Returns a list of variables that are referred to by a string of text Example: >>> print self.get_refs('There are [two] [references] here') >>> # Prints ['two', 'references'] Arguments: text -- a string of text Returns: A list of variable names or an empty list if the string contains no references. </DOC>""" text = self.unistr(text) l = [] start = -1 while True: # Find the start and end of a variable definition start = text.find(u'[', start + 1) if start < 0: break end = text.find(u']', start + 1) if end < 0: raise exceptions.runtime_error( \ u"Missing closing bracket ']' in string '%s', in item '%s'" \ % (text, self.name)) var = text[start+1:end] l.append(var) var = var[end:] return l
def run(self): """ Run the item. In this case this means putting the offline canvas to the display and waiting for the specified duration. """ self.set_item_onset() try: x = int(self.get("xpos")) y = int(self.get("ypos")) except: raise exceptions.runtime_error("Please use numeric values for the coordinates in eyelink_drift_correct item '%s'" % self.name) if not self.has("coordinates") or self.get("coordinates") == "relative": x += self.get("width") / 2 y += self.get("height") / 2 # Draw a fixation dot c = openexp.canvas.canvas(self.experiment, self.get("background"), self.get("foreground")) c.set_penwidth(3) c.line(c.xcenter() - 5, c.ycenter(), c.xcenter() + 5, c.ycenter()) c.line(c.xcenter(), c.ycenter() - 5, c.xcenter(), c.ycenter() + 5) c.show() # Do drift correction while not self.experiment.eyelink.drift_correction( (x, y), self.get("mode") == self._mode_auto): self.experiment.eyelink.calibrate() c.show() # Report success return True
def run(self): """The run phase of the plug-in goes here.""" if self.get(u"auto_log") == u"yes": # Log everything self.logvars = [] for logvar, val, item in self.experiment.var_list(): if (self.has(logvar) or self.get(u"ignore_missing") == u"yes") and logvar not in self.logvars: self.logvars.append(logvar) debug.msg(u'auto-logging "%s"' % logvar) else: # Parse variable to log from user input (stopgap function, until # proper UI can be used. self.logvars = self._vars_string.strip(" ").split("\n") trial_data = dict() for var in self.logvars: try: val = self.experiment.get(var) except exceptions.runtime_error as e: if self.get(u"ignore_missing") == u"yes": val = u"NA" else: raise exceptions.runtime_error( u"Logger '%s' tries to log the variable '%s', but this variable is not available. Please deselect '%s' in logger '%s' or enable the 'Use NA for variables that have not been set' option." % (self.name, var, var, self.name) ) trial_data[var] = val self.experiment.log_list.append(trial_data)
def set_rect(self, rect): """<DOC> Sets the widget geometry Arguments: rect -- a (left, top, width, height) tuple </DOC>""" self.rect = rect if self.adjust: x, y, w, h = self.rect try: img = Image.open(self.path) img_w, img_h = img.size except: try: import pygame img = pygame.image.load(self.path) except: raise exceptions.runtime_error( \ 'Failed to open image "%s". Perhaps the file is not an image, or the image format is not supported.' \ % self.path) img_w, img_h = img.get_width() scale_x = 1.*w/img_w scale_y = 1.*h/img_h self.scale = min(scale_x, scale_y) else: self.scale = 1
def prepare(self): """ Opens the video file for playback """ # Pass the word on to the parent item.item.prepare(self) # Byte-compile the event handling code (if any) if self.event_handler.strip() != "": self._event_handler = compile(self.event_handler, "<string>", "exec") else: self._event_handler = None # Find the full path to the video file. This will point to some # temporary folder where the file pool has been placed path = self.experiment.get_file(str(self.get("video_src"))) # Open the video file if not os.path.exists(path) or str(self.get("video_src")).strip() == "": raise exceptions.runtime_error( "Video file '%s' was not found in video_player '%s' (or no video file was specified)." % (os.path.basename(path), self.name) ) self.load(path) # Report success return True
def set_rect(self, rect): """<DOC> Sets the widget geometry. Arguments: rect -- A (left, top, width, height) tuple. </DOC>""" self.rect = rect if self.adjust: x, y, w, h = self.rect try: img = Image.open(self.path) img_w, img_h = img.size except: try: import pygame img = pygame.image.load(self.path) except: raise exceptions.runtime_error( \ u'Failed to open image "%s". Perhaps the file is not an image, or the image format is not supported.' \ % self.path) img_w, img_h = img.get_width() scale_x = 1. * w / img_w scale_y = 1. * h / img_h self.scale = min(scale_x, scale_y) else: self.scale = 1
def get_refs(self, text): """<DOC> Returns a list of variables that are referred to by a string of text. Arguments: text -- A string of text. Returns: A list of variable names or an empty list if the string contains no # references. Example: >>> print self.get_refs('There are [two] [references] here') >>> # Prints ['two', 'references'] </DOC>""" text = self.unistr(text) l = [] start = -1 while True: # Find the start and end of a variable definition start = text.find(u'[', start + 1) if start < 0: break end = text.find(u']', start + 1) if end < 0: raise exceptions.runtime_error( \ u"Missing closing bracket ']' in string '%s', in item '%s'" \ % (text, self.name)) var = text[start+1:end] l.append(var) var = var[end:] return l
def prepare_duration(self): """Prepare the duration""" if type(self.get("duration")) == int: # Prepare a duration in milliseconds self._duration = int(self.get("duration")) if self._duration == 0: self._duration_func = self.dummy else: self.prepare_compensation() if self._compensation != 0: self._duration_func = self.sleep_for_comp_duration else: self._duration_func = self.sleep_for_duration else: # Prepare a special duration, such as 'keypress', which are # handles by special functions prepare_func = "prepare_duration_%s" % self.get("duration") if hasattr(self, prepare_func): exec("self.%s()" % prepare_func) else: raise exceptions.runtime_error( \ "'%s' is not a valid duration in item '%s'" % \ (self.get("duration"), self.name))
def confirm_abort_experiment(self): """ Asks for confirmation before aborting the experiment. Displays a # confirmation screen, collects the response, and acts accordingly. Exceptions: Raises a response_error upon confirmation. Returns: False if no confirmation was given. """ # Display the confirmation screen conf_canvas = canvas(self.experiment) conf_kb = keyboard(self.experiment, timeout=None) yc = conf_canvas.ycenter() ld = 40 conf_canvas.clear() conf_canvas.text(u'Really abort experiment?', y=yc-3*ld) conf_canvas.text(u'Press \'Y\' to abort', y=yc-0.5*ld) conf_canvas.text(u'Press any other key or wait 5s to go to setup', \ y = yc+0.5*ld) conf_canvas.show() # process the response: try: key, time = conf_kb.get_key(timeout=5000) except: return False # if confirmation, close experiment if key == u'y': raise exceptions.runtime_error(u'The experiment was aborted') else: return False
def usanitize(self, s, strict=False): """ Convert all special characters to U+XXXX notation, so that the resulting string can be treated as plain ASCII text. Arguments: s -- A unicode string to be santized Keyword arguments: strict -- if True, special characters are ignored rather than recoded (default=False) Returns: A regular Python string with all special characters replaced by U+XXXX notation """ if type(s) != unicode: raise exceptions.runtime_error( \ 'usanitize() expects first argument to be unicode, not "%s"' \ % type(s)) _s = '' for ch in s: # Encode non ASCII and slash characters if ord(ch) > 127 or ord(ch) == 92: if not strict: _s += 'U+%.4X' % ord(ch) else: _s += ch return _s.replace(os.linesep, "\n")
def prepare_timeout(self): """Prepares the response timeout""" if self.get("timeout") == "infinite": self._timeout = None else: try: self._timeout = int(self.get("timeout")) except: raise exceptions.runtime_error( \ "'%s' is not a valid timeout in keyboard_response '%s'. Expecting a positive integer or 'infinite'." \ % (self.get("timeout"), self.name)) if self._timeout < 0: raise exceptions.runtime_error( \ "'%s' is not a valid timeout in keyboard_response '%s'. Expecting a positive integer or 'infinite'." \ % (self.get("timeout"), self.name))
def prepare(self): """ Opens the video file for playback """ # Pass the word on to the parent item.item.prepare(self) # Byte-compile the event handling code (if any) if self.event_handler.strip() != "": self._event_handler = compile(self.event_handler, "<string>", "exec") else: self._event_handler = None # Find the full path to the video file. This will point to some # temporary folder where the file pool has been placed path = self.experiment.get_file(str(self.get("video_src"))) # Open the video file if not os.path.exists(path) or str( self.get("video_src")).strip() == "": raise exceptions.runtime_error( "Video file '%s' was not found in video_player '%s' (or no video file was specified)." % (os.path.basename(path), self.name)) self.load(path) # Report success return True
def run(self): """Log the selected variables""" if not self.log_started: self.log_started = True # If auto logging is enabled, collect all variables if self.get(u'auto_log') == u'yes': self.logvars = [] for logvar, val, item in self.experiment.var_list(): if (self.has(logvar) or self.get(u'ignore_missing') == \ u'yes') and logvar not in self.logvars: self.logvars.append(logvar) debug.msg(u'auto-logging "%s"' % logvar) # Sort the logvars to ascertain a consistent ordering self.logvars.sort() # Draw the first line with variables self.log(u','.join(self.logvars)) l = [] for var in self.logvars: try: val = self.unistr(self.get(var)) except exceptions.runtime_error as e: if self.get(u'ignore_missing') == u'yes': val = u'NA' else: raise exceptions.runtime_error( \ u"Logger '%s' tries to log the variable '%s', but this variable is not available. Please deselect '%s' in logger '%s' or enable the 'Use NA for variables that have not been set' option." \ % (self.name, var, var, self.name)) l.append(val) if self.get(u'use_quotes') == u'yes': self.log(u'"' + (u'","'.join(l)) + u'"') else: self.log(u",".join(l))