Esempio n. 1
0
	def set_rect(self, rect):

		"""
		desc:
			Sets the widget geometry.

		arguments:
			rect:
				desc:	A (left, top, width, height) tuple.
				type:	tuple
		"""

		self.rect = rect
		_path = safe_str(self.path, enc=misc.filesystem_encoding())
		if not os.path.isfile(_path):
			raise osexception(u'"%s" does not exist' % _path)
		if self.adjust:
			x, y, w, h = self.rect
			try:
				img = Image.open(_path)
				img_w, img_h = img.size
			except:
				try:
					import pygame
					img = pygame.image.load(_path)
				except:
					raise osexception(
						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_size()
			scale_x = 1.*w/img_w
			scale_y = 1.*h/img_h
			self.scale = min(scale_x, scale_y)
		else:
			self.scale = 1
Esempio n. 2
0
    def image(self, fname, center=True, x=None, y=None, scale=None):

        _fname = safe_str(fname, enc=misc.filesystem_encoding())
        if not os.path.isfile(_fname):
            raise osexception(u'"%s" does not exist' % fname)
        try:
            surface = pygame.image.load(_fname)
        except pygame.error:
            raise osexception(u"'%s' is not a supported image format" % fname)
        if scale is not None:
            try:
                surface = pygame.transform.smoothscale(
                    surface, (int(surface.get_width() * scale), int(surface.get_height() * scale))
                )
            except:
                debug.msg(u"smooth scaling failed for '%s'" % fname, reason=u"warning")
                surface = pygame.transform.scale(
                    surface, (int(surface.get_width() * scale), int(surface.get_height() * scale))
                )
        size = surface.get_size()
        x, y = self.to_xy(x, y)
        if center:
            x -= size[0] / 2
            y -= size[1] / 2
        self.surface.blit(surface, (x, y))
Esempio n. 3
0
	def from_string(self, string):

		"""
		desc:
			Parses a definition string.

		arguments:
			string:		A definition string.
		"""

		self.variables = {}
		self.comments = []
		self.reset()
		for line in string.split(u'\n'):
			if not self.parse_variable(line):
				l = self.split(line)
				if len(l) > 0:
					if l[0] == u'draw':
						if len(l) == 1:
							raise osexception(
								u'Incomplete draw command: \'%s\'' % line)
						element_type = l[1]
						if not hasattr(self.element_module(), element_type):
							raise osexception(
								u'Unknown sketchpad element: \'%s\'' \
								% element_type)
						element_class = getattr(self.element_module(),
							element_type)
						element = element_class(self, line)
						self.elements.append(element)
		self.elements.sort(key=lambda element: -element.z_index)
Esempio n. 4
0
	def set_widget(self, widget, pos, colspan=1, rowspan=1):

		"""<DOC>
		Adds a widget to the form.

		Arguments:
		widget -- The widget to add.
		pos -- The position to add the widget, which can be an index or a
			   (column, row) tuple.

		Keyword arguments:
		colspan -- The number of columns that the widget should span (default=1).
		rowspan -- The number of rows that the widget should span (default=1).
		</DOC>"""

		index = self.cell_index(pos)
		if index >= len(self.widgets):
			raise osexception( \
				u'Widget position (%s, %s) is outside of the form' % pos)
		if type(colspan) != int or colspan < 1 or colspan > len(self.cols):
			raise osexception( \
				u'Column span %s is invalid (i.e. too large, too small, or not a number)' \
				% colspan)
		if type(rowspan) != int or rowspan < 1 or rowspan > len(self.rows):
			raise osexception( \
				u'Row span %s is invalid (i.e. too large, too small, or not a number)' \
				% rowspan)
		self.widgets[index] = widget
		self.span[index] = colspan, rowspan
		widget.set_rect(self.get_rect(index))
Esempio n. 5
0
def synth(experiment, osc="sine", freq=440, length=100, attack=0, decay=5):

	"""
	desc: |
		A factory that synthesizes a sound and returns it as a `sampler object`.
		For a full description of keywords, see `python_workspace_api.synth`.

		For backwards compatibility, this function behaves as though it is a
		back-end.

	arguments:
		experiment:
			desc:		The experiment object.
			type:		experiment

	returns:
		desc:	A `sampler` object.
		type:	sampler
	"""

	if np is None:
		raise osexception(
			u'The synth is not available, because numpy is missing.')
	if attack < 0 or attack > length:
		raise osexception(
			u'Attack must be a numeric value between 0 and the sound length')
	if decay < 0 or decay > length:
		raise osexception(
			u'Decay must be a numeric value between 0 and the sound length')
	# We need to multiply the rate by two to get a stereo signal
	rate = 2*experiment.var.get(u'sampler_frequency', 48100)
	signal = osc_gen(osc, key_to_freq(freq), length, rate)
	_envelope = envelope(length, attack, decay, rate)
	sound = to_int_16(signal * _envelope)
	return sampler(experiment, sound)
Esempio n. 6
0
def _color(color):

	"""
	desc:
		Creates a PyGame color object.

	returns:
		A pygame color object.
	"""

	if isinstance(color, unicode):
		return pygame.Color(str(color))
	if isinstance(color, str):
		return pygame.Color(color)
	if isinstance(color, int):
		return pygame.Color(color, color, color, 255)
	if isinstance(color, float):
		i = int(255 * color)
		return pygame.Color(i, i, i, 255)
	if isinstance(color, tuple):
		if len(color) == 3:
			return pygame.Color(color[0], color[1], color[2], 255)
		if len(color) > 3:
			return pygame.Color(color[0], color[1], color[2], color[3])
		raise osexception(u'Unknown color: %s' % color)
	if isinstance(color, pygame.Color):
		return color
	raise osexception(u'Unknown color: %s' % color)
Esempio n. 7
0
	def prepare(self):

		"""
		desc:
			Executes the prepare script. The code that you enter in the
			'prepare' tab of an inline_script item in the GUI is used as a body
			for this function.
		"""

		item.item.prepare(self)
		# 'self' must always be registered, otherwise we get confusions between
		# the various inline_script items.
		self.experiment.python_workspace[u'self'] = self
		# Compile prepare script
		try:
			self.cprepare = self.experiment.python_workspace._compile(
				self.var.get(u'_prepare', _eval=False))
		except Exception as e:
			raise osexception(u'Failed to compile inline script',
				line_offset=-1, item=self.name, phase=u'prepare', exception=e)
		# Compile run script
		try:
			self.crun = self.experiment.python_workspace._compile(
				self.var.get(u'_run', _eval=False))
		except Exception as e:
			raise osexception(u'Failed to compile inline script',
				line_offset=-1, item=self.name, phase=u'run', exception=e)
		# Run prepare script
		try:
			self.experiment.python_workspace._exec(self.cprepare)
		except Exception as e:
			raise osexception(u'Error while executing inline script',
				line_offset=-1, item=self.name, phase=u'prepare', exception=e)
	def process_user_input_customized(self, event=None):
		"""
		Allows the user to insert custom code. Code is stored in the event_handler variable.

		Arguments:
		event -- a tuple containing the type of event (key or mouse button press)
			   and the value of the key or mouse button pressed (which character or mouse button)
		"""

		# Listen for escape presses and collect keyboard and mouse presses if no event has been passed to the function
		# If only one button press or mouse press is in the event que, the resulting event variable will just be a tuple
		# Otherwise the collected event tuples will be put in a list, which the user can iterate through with his custom code
		# This way the user will have either
		#  1. a single tuple with the data of the event (either collected here from the event que or passed from process_user_input)
		#  2. a list of tuples containing all key and mouse presses that have been pulled from the event queue

		if event is None:
			events = pygame.event.get()
			event = []  # List to contain collected info on key and mouse presses
			for ev in events:
				if ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
					self.main_player.playing = False
					raise osexception(u"The escape key was pressed")
				elif ev.type == pygame.KEYDOWN or ev.type == pygame.MOUSEBUTTONDOWN:
					# Exit on ESC press
					if ev.type == pygame.KEYDOWN:
						event.append(("key", pygame.key.name(ev.key)))
					elif ev.type == pygame.MOUSEBUTTONDOWN:
						event.append(("mouse", ev.button))
			# If there is only one tuple in the list of collected events, take it out of the list
			if len(event) == 1:
				event = event[0]

		continue_playback = True

		# Variables for user to use in custom script
		try:
			self.main_player.python_workspace['continue_playback'] = True
			self.main_player.python_workspace['frame'] = self.main_player.frame_no
			self.main_player.python_workspace['times_played'] = self.main_player.times_played
			self.main_player.python_workspace['paused'] = self.main_player.paused
			self.main_player.python_workspace['event'] = event
		except Exception as e:
			raise osexception("Error assigning variables in media_player: {}".format(e))

		# Add more convenience functions?

		try:
			self.main_player.python_workspace._exec(self.custom_event_code)
		except Exception as e:
			self.main_player.playing = False
			raise osexception(u"Error while executing event handling code: %s" % e)

		# Get potentially altered value of continue_playback from the workspace
		continue_playback = self.main_player.python_workspace['continue_playback']
		if type(continue_playback) != bool:
			continue_playback = False

		pygame.event.pump()
		return continue_playback
Esempio n. 9
0
	def _prepare_allowed_responses(self):

		"""
		desc:
			Processes the allowed_responses variable, and checks whether it is
			valid.

		returns:
			desc:	A list of allowed responses.
			type:	list
		"""

		allowed_responses = safe_decode(
			self.var.get(u'allowed_responses', default=u''))
		if allowed_responses == u'':
			return
		if py3:
			allowed_responses = [r.strip() \
				for r in allowed_responses.split(';')]
		else:
			allowed_responses = [safe_decode(r.strip()) \
				for r in safe_encode(allowed_responses).split(';')]
		for r in allowed_responses:
			if not self.validate_response(r):
				raise osexception(u'Invalid value in allowed_responses: %s' % r)
		# If allowed responses are provided, the list should not be empty
		if not allowed_responses:
			raise osexception(u'allowed_responses should not be an empty list')
		return allowed_responses
Esempio n. 10
0
	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 osexception( \
					u'Unknown jitter mode in advanced_delay %s' % self.name)
		except:
			raise osexception( \
				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)
Esempio n. 11
0
    def __init__(self, experiment, src):

        """<DOC>
		Initializes the sampler with a specified file.

		Arguments:
		experiment -- An instance of libopensesame.experiment.experiment.
		src -- A path to a .wav or .ogg file.

		Example:
		>>> from openexp.sampler import sampler
		>>> src = exp.get_file('my_sound.ogg')
		>>> my_sampler = sampler(exp, src)
		</DOC>"""

        if src != None:
            if not os.path.exists(src):
                raise osexception(u"openexp._sampler.legacy.__init__() the file '%s' does not exist" % src)

            if os.path.splitext(src)[1].lower() not in (".ogg", ".wav"):
                raise osexception(u"openexp._sampler.legacy.__init__() the file '%s' is not an .ogg or .wav file" % src)

            self.sound = mixer.Sound(src)

        self.experiment = experiment
        self.keyboard = keyboard(experiment)
        self._stop_after = 0
        self._fade_in = 0
        self._volume = 1.0
Esempio n. 12
0
	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 osexception( \
				_('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 osexception( \
					'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
Esempio n. 13
0
	def prepare(self):

		"""Prepares for playback."""

		item.item.prepare(self)
		if safe_decode(self.var.sample).strip() == u'':
			raise osexception(
				u'No sample has been specified in sampler "%s"' % self.name)
		sample = self.experiment.get_file(self.var.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 osexception(
					u'Failed to load sample in sampler "%s": %s' % (self.name, \
					e))
		pan = self.var.pan
		if pan == -20:
			pan = u'left'
		elif pan == 20:
			pan = u'right'
		self.sampler.pan = pan
		self.sampler.volume = self.var.volume
		self.sampler.pitch = self.var.pitch
		self.sampler.fade_in = self.var.fade_in
		self.sampler.duration = self.var.stop_after
		self.sampler.block = self.block
		generic_response.generic_response.prepare(self)
Esempio n. 14
0
	def prepare(self):

		"""See item."""

		base_response_item.prepare(self)
		if safe_decode(self.var.sample).strip() == u'':
			raise osexception(
				u'No sample has been specified in sampler "%s"' % self.name)
		sample = self.experiment.pool[self.var.sample]
		try:
			self.sampler = openexp_sampler(self.experiment, sample)
		except Exception as e:
			raise osexception(u'Failed to load sample: %s' % sample,
				exception=e)
		pan = self.var.pan
		if pan == -20:
			pan = u'left'
		elif pan == 20:
			pan = u'right'
		self.sampler.pan = pan
		self.sampler.volume = self.var.volume
		self.sampler.pitch = self.var.pitch
		self.sampler.fade_in = self.var.fade_in
		self.sampler.duration = self.var.stop_after
		self.sampler.block = self.var.duration == u'sound'
Esempio n. 15
0
	def validate_geometry(self):

		"""
		Checks whether the form has a valid geometry.

		Exceptions:
		osexception		--	When the geometry is invalid.
		"""

		for index1 in range(len(self.widgets)):
			if self.widgets[index1] is None:
				continue
			l = self.get_cell(index1)
			colspan, rowspan = self.span[index1]
			for col in range(l[0], l[0]+colspan):
				for row in range(l[1], l[1]+rowspan):
					index2 = self.cell_index((col, row))
					if index1 == index2:
						continue
					if len(self.widgets) <= index2:
						raise osexception(
							u'The widget at position (%d, %s) falls outside of your form' \
							% (l[0], l[1]))
					if self.widgets[index2] is not None:
						raise osexception(
							u'The widget at position (%d, %d) overlaps with another widget' \
							% (l[0], l[1]))
Esempio n. 16
0
	def prepare(self):

		"""Prepares for playback."""

		item.item.prepare(self)
		if self.sample.strip() == u'':
			raise osexception( \
				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 osexception( \
					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)
Esempio n. 17
0
	def from_string(self, string):

		"""
		desc:
			Parses a definition string.

		arguments:
			string:		A definition string.
		"""

		self.variables = {}
		self.comments = []
		self.reset()
		if string is None:
			return
		for line in string.split(u'\n'):
			if self.parse_variable(line):
				continue
			cmd, arglist, kwdict = self.syntax.parse_cmd(line)
			if cmd != u'draw':
				continue
			if len(arglist) == 0:
				raise osexception(u'Incomplete draw command: \'%s\'' % line)
			element_type = arglist[0]
			if not hasattr(self.element_module(), element_type):
				raise osexception(
					u'Unknown sketchpad element: \'%s\'' % element_type)
			element_class = getattr(self.element_module(), element_type)
			element = element_class(self, line)
			self.elements.append(element)
		self.elements.sort(key=lambda element: -element.z_index)
Esempio n. 18
0
	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)
		
		if self.module == None:
			try:
				self.module = imp.load_source("file", os.path.join( \
					self.experiment.pool_folder, self.file))
			except Exception as e:
				raise osexception( \
					"Failed to import '%s' in the prepare phase of external_script item '%s': %s" \
					% (self.file, self.name, e))
			
		try:
			getattr(self.module, self.prepare_func)(self)
		except Exception as e:
			raise osexception( \
				"Failed to run function '%s(item)' in the prepare phase of external_script item '%s': %s" \
				% (self.prepare_func, self.name, e))				
		
		# Report success
		return True
Esempio n. 19
0
	def key_to_freq(self, key):

		"""<DOC>
		Converts a key (e.g., A1) to a frequency.

		Arguments:
		key -- A string like "A1", "eb2", etc.

		Returns:
		An integer value containing the frequency in hertz.

		Example:
		>>> from openexp.synth import synth
		>>> my_synth = synth(exp)
		>>> print('An a2 is %d Hz' % my_synth.key_to_freq('a2'))
		</DOC>"""

		if type(key) != str or len(key) < 2:
			raise osexception( \
				"synth.key_to_freq(): '%s' is not a valid note, expecting something like 'A1'")

		n = key[:-1].lower()
		try:
			o = int(key[-1])
		except:
			raise osexception( \
				"synth.key_to_freq(): '%s' is not a valid note, expecting something like 'A1'")

		if n == "a":
			f = 440.0
		elif n == "a#" or n == "bb":
			f = 466.16
		elif n == "b":
			f = 493.92
		elif n == "c":
			f = 523.28
		elif n == "c#" or n == "db":
			f = 554.40
		elif n == "d":
			f = 587.36
		elif n == "d#" or n == "eb":
			f = 698.47
		elif n == "e":
			f = 659.48
		elif n == "f":
			f = 698.48
		elif n == "f#" or n == "gb":
			f = 740.00
		elif n == "g":
			f = 784.00
		elif n == "ab" or n == "g#":
			f == 830.64

		if o < 1:
			o = 0.5 ** (abs(o) + 1)
			freq = f * o
		else:
			freq = f ** o

		return freq
Esempio n. 20
0
	def set_response(self, response=None, response_time=None, correct=None):

		"""<DOC>
		Processes a response in such a way that feedback variables are updated #
		as well.

		Keyword arguments:
		response		--	The response value. (default=None)
		response_time	--	The response time. (default=None)
		correct			--	The correctness value. (default=None)

		Example:
		>>> from openexp.keyboard import keyboard
		>>> my_keyboard = keyboard(exp)
		>>> t1 = self.time()
		>>> button, timestamp = my_keyboard.get_key()
		>>> if button == 'left':
		>>> 	correct = 1
		>>> else:
		>>> 	correct = 0
		>>> rt = timestamp - t1
		>>> self.set_response(response=button, response_time=rt, \
		>>> 	correct=correct)
		</DOC>"""

		# Handle response variables.
		self.experiment.set(u'total_responses', self.experiment.get( \
			u'total_responses') + 1)
		self.experiment.set(u'response', response)
		self.experiment.set(u'response_time', response_time)
		if response_time != None:
			if type(response_time) not in (int, float):
				raise osexception(u'response should be a numeric value or None')
			self.experiment.set(u'total_response_time', self.experiment.get( \
			u'total_response_time') + self.get(u'response_time'))
		if correct != None:
			if correct not in (0, 1, True, False, None):
				raise osexception( \
					u'correct should be 0, 1, True, False, or None')
			if correct:
				self.experiment.set(u'total_correct', self.experiment.get( \
					u'total_correct') + 1)
				self.experiment.set(u'correct', 1)
			else:
				self.experiment.set(u'correct', 0)
		# Set feedback variables
		self.experiment.set(u'acc', 100.0 * self.experiment.get( \
			u'total_correct') / self.experiment.get(u'total_responses'))
		self.experiment.set(u'avg_rt', self.experiment.get( \
			u'total_response_time') / self.experiment.get(u'total_responses'))
		self.experiment.set(u'accuracy', self.experiment.get(u'acc'))
		self.experiment.set(u'average_response_time', self.experiment.get( \
			u'avg_rt'))
		# Copy the response variables to variables with a name suffix.
		self.experiment.set(u'correct_%s' % self.get(u'name'), \
			self.experiment.get(u'correct'))
		self.experiment.set(u'response_%s' % self.get(u'name'), \
			self.experiment.get(u'response'))
		self.experiment.set(u'response_time_%s' % self.get(u'name'), \
			self.experiment.get(u'response_time'))
Esempio n. 21
0
	def prepare(self):

		"""The preparation phase of the plug-in."""

		item.item.prepare(self)
		# Sanity check on the duration value, which should be a positive numeric
		# value.
		if type(self.get('duration')) not in (int, float) or \
			self.get('duration') < 0:
			raise osexception( \
				u'Duration should be a positive numeric value in advanced_delay %s' \
				% self.name)
		if self.get(u'jitter_mode') == u'Uniform':
			self._duration = random.uniform(self.get(u'duration')-self.get( \
				u'jitter')/2, self.get(u'duration')+self.get(u'jitter')/2)
		elif self.get(u'jitter_mode') == u'Std. Dev.':
			self._duration = random.gauss(self.get(u'duration'), self.get( \
				u'jitter'))
		else:
			raise osexception( \
				u'Unknown jitter mode in advanced_delay %s' % self.name)
		# Don't allow negative durations.
		if self._duration < 0:
			self._duration = 0
		self._duration = int(self._duration)
		self.experiment.set(u'delay_%s' % self.name, self._duration)
		debug.msg(u"delay for %s ms" % self._duration)
Esempio n. 22
0
	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 osexception( \
				u"A string should be passed to experiment.get_file(), not '%s'" \
				% path)
		if isinstance(path, str):
			path = path.decode(self.encoding)
		if path.strip() == u'':
			raise osexception( \
				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
Esempio n. 23
0
	def from_string(self, string):

		"""
		Reads the entire experiment from a string.

		Arguments:
		string	--	The definition string.
		"""

		debug.msg(u"building experiment")
		s = iter(string.split("\n"));
		line = next(s, None)
		while line != None:
			get_next = True
			try:
				l = self.split(line)
			except ValueError as e:
				raise osexception( \
					u"Failed to parse script. Maybe it contains illegal characters or unclosed quotes?", \
					exception=e)
			if len(l) > 0:
				self.parse_variable(line)
				# Parse definitions
				if l[0] == u"define":
					if len(l) != 3:
						raise osexception( \
							u'Failed to parse definition', line=line)
					item_type = l[1]
					item_name = self.sanitize(l[2])
					line, def_str = self.read_definition(s)
					get_next = False
					self.parse_definition(item_type, item_name, def_str)
			# Advance to next line
			if get_next:
				line = next(s, None)
Esempio n. 24
0
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 osexception.
	
	Keyword arguments:
	min_len	--	The minimum length of the list. (default=None)
	max_len	--	The maximum length of the list. (default=None)
	
	Raises:
	A osexception if the variable could not be converted.
	
	Returns:
	A list of floats.
	"""
		
	try:
		l = list(l)
	except:
		raise osexception( \
			u'Expecting a list or compatible type not "%s" for "%s"' % (l, \
				desc))
	if min_len is not None and len(l) < min_len:
		raise osexception( \
			u'Expecting a list of at least %d items for "%s"' % (min_len, desc))
	if max_len is not None and len(l) > max_len:
		raise osexception( \
			u'Expecting a list of at most %d items for "%s"' % (max_len, desc))
	return l
Esempio n. 25
0
	def validate_geometry(self):

		"""
		Checks whether the form has a valid geometry.

		Exceptions:
		osexception		--	When the geometry is invalid.
		"""

		for index1 in range(len(self.widgets)):
			if self.widgets[index1] == None:
				continue
			l = self.get_cell(index1)
			colspan, rowspan = self.span[index1]
			for col in range(l[0], l[0]+colspan):
				for row in range(l[1], l[1]+rowspan):
					index2 = self.cell_index((col, row))
					if index1 == index2:
						continue
					print '%s, %s (%s)' % (col, row, index2)
					if len(self.widgets) <= index2:
						raise osexception( \
							u'One or more widgets fall outside of your form')
					if self.widgets[index2] != None:
						raise osexception( \
							u'Two or more widgets in your form are overlapping')
Esempio n. 26
0
	def run(self):

		"""
		Everything in this function is run in a new process, therefore all
		import statements are put in here. The function reroutes all output to
		stdin and stderr to the pipe to the main process so OpenSesame can
		handle all prints and errors.
		"""

		import os
		import sys
		from libopensesame import misc
		from libopensesame.experiment import experiment
		from libopensesame.exceptions import osexception
		# Under Windows, change the working directory to the OpenSesame folder,
		# so that the new process can find the main script.
		if os.name == u'nt':
			os.chdir(misc.opensesame_folder())
		# Reroute output to OpenSesame main process, so everything will be
		# printed in the Debug window there.
		pipeToMainProcess = OutputChannel(self.output)
		sys.stdout = pipeToMainProcess
		sys.stderr = pipeToMainProcess
		# First initialize the experiment and catch any resulting Exceptions
		try:
			exp = experiment(string=self.script, pool_folder= self.pool_folder,
				experiment_path=self.experiment_path,
				fullscreen=self.fullscreen, auto_response=self.auto_response,
				subject_nr=self.subject_nr, logfile=self.logfile)
		except Exception as e:
			if not isinstance(e, osexception):
				e = osexception(u'Unexpected error', exception=e)
			# Communicate the exception and exit with error
			self.output.put(e)
			sys.exit(1)
		print(u'Starting experiment as %s' % self.name)
		# Run the experiment and catch any Exceptions.
		e_run = None
		exp.set_output_channel(self.output)
		try:
			exp.run()
			print('done!')
		except Exception as e_run:
			if not isinstance(e_run, osexception):
				e_run = osexception(u'Unexpected error', exception=e_run)
		exp.transmit_workspace()
		# End the experiment and catch any Exceptions. These exceptions are just
		# printed out and not explicitly passed on to the user, because they are
		# less important than the run-related exceptions.
		try:
			exp.end()
		except Exception as e_exp:
			print(u'An Exception occurred during exp.end(): %s' % e_exp)
		# Communicate the exception and exit with error
		if e_run is not None:
			self.output.put(e_run)
			sys.exit(1)
		# Exit with success
		sys.exit(0)
Esempio n. 27
0
	def prepare(self):

		"""Prepares the text display canvas."""

		# Pass the word on to the parent
		item.prepare(self)
		# Create an offline canvas
		self.c = openexp.canvas.canvas(self.experiment, self.get( \
			u"background"), self.get(u"foreground"))
		self.c.set_font(self.get(u"font_family"), self.get(u"font_size"))
		# Make sure that the content is a unicode string that is evaluated
		# for variables and then split into separated lines, using either the
		# os-specific or the Unix-style line separator.
		content = self.unistr(self.get(u'content'))
		content = content.replace(os.linesep, u'\n')
		content = self.eval_text(content).split(u"\n")
		# Do line wrapping
		_content = []
		for line in content:
			while len(line) > self.get(u"maxchar"):
				i = line.rfind(" ", 0, self.get(u"maxchar"))
				if i < 0:
					raise osexception( \
						u"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(u"align") != u"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 osexception( \
					u"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(u"align"), self.name))

		line_nr = -len(content) / 2
		for line in content:

			if self.get(u"align") == u"center":
				self.c.textline(line, line_nr)
			elif self.get(u"align") == u"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.prepare(self)
Esempio n. 28
0
	def get_click(self, buttonlist=None, timeout=None, visible=None):

		if buttonlist == None:
			buttonlist = self.buttonlist
		if timeout == None:
			timeout = self.timeout
		if visible == None:
			visible = self.visible
		enable_escape = self.experiment.get_check('enable_escape', 'no', \
			['yes', 'no']) == 'yes'
		if self.cursor == None:
			pygame.mouse.set_visible(visible)
		elif visible:
			pygame.mouse.set_visible(False)

		start_time = pygame.time.get_ticks()
		time = start_time

		while True:
			time = pygame.time.get_ticks()

			# Draw a cusom cursor if necessary
			if self.cursor != None and visible:
				surface = self.experiment.last_shown_canvas.copy()
				surface.blit(self.cursor, pygame.mouse.get_pos())
				self.experiment.surface.blit(surface, (0,0))
				pygame.display.flip()

			# Process the input
			for event in pygame.event.get():
				if event.type == KEYDOWN and event.key == pygame.K_ESCAPE:
					raise osexception( \
						"The escape key was pressed.")
				if event.type == MOUSEBUTTONDOWN:

					# Check escape sequence. If the top-left and top-right
					# corner are clicked successively within 2000ms, the
					# experiment is aborted
					if enable_escape and event.pos[0] < 64 and event.pos[1] \
						< 64:
						_time = pygame.time.get_ticks()
						while pygame.time.get_ticks() - _time < 2000:
							for event in pygame.event.get():
								if event.type == MOUSEBUTTONDOWN:
									if event.pos[0] > self.experiment.get( \
										'width')-64 and event.pos[1] < 64:
										raise osexception( \
											"The escape sequence was clicked/ tapped")

					if (buttonlist == None or event.button in buttonlist):
						if self.cursor is None:
							pygame.mouse.set_visible(self.visible)
						return event.button, event.pos, time
			if timeout != None and time-start_time >= timeout:
				break

		if self.cursor == None:
			pygame.mouse.set_visible(self.visible)
		return None, None, time
Esempio n. 29
0
	def run(self):

		"""Run the item"""

		# Parse the option list
		option_list = self.var.options.split(u'\n') # split by return
		# Filter out empty options
		option_list = list(filter(lambda option: option != u'', option_list))
		# option_list.pop(len(option_list)-1) # remove last (empty) option
		if len(option_list) == 0:
			raise osexception(
				u'You must specify at least one response option in form_multiple_choice item "%s"' \
				% self.name)

		# Determine whether a button is shown and determine the number of rows
		rows = len(option_list) + 2
		if self.var.advance_immediately == u'no' \
			or self.var.allow_multiple == u'yes':
			show_button = True
			click_accepts = False
			rows += 1
		else:
			show_button = False
			click_accepts = True

		# Determine the group for the checkboxes
		if self.var.allow_multiple == u'no':
			group = u'response_group'
		else:
			group = None

		# The variable in which the response is stored
		var = self.var.form_var

		# Build the form
		try:
			margins = [float(i) for i in str(self.var.margins).split(u';')]
		except:
			raise osexception(
				_(u'margins should be numeric values separated by a semi-colon'))
		if self.var.timeout == u'infinite':
			timeout = None
		else:
			timeout = self.var.timeout
		form = widgets.form(self.experiment, cols=1, rows=rows,
			spacing=self.var.spacing, margins=margins, theme=self.var._theme,
			item=self, timeout=timeout, clicks=self.var.form_clicks==u'yes')
		form.set_widget(widgets.label(form, self.var.form_title), (0,0))
		form.set_widget(widgets.label(form, self.var.question), (0,1))
		i = 2
		for option in option_list:
			form.set_widget(widgets.checkbox(form, option,
				group=group, click_accepts=click_accepts, var=var), (0,i))
			i += 1
		if show_button:
			form.set_widget(widgets.button(form, self.var.button_text), (0,i))

		# Go!
		form._exec()
Esempio n. 30
0
	def prepare(self):

		"""
		desc:
			Prepare the item.
		"""

		item.item.prepare(self)
		self.prepare_timeout()
		self._require_state_change = self.require_state_change == u'yes'
		# Prepare the allowed responses
		self._allowed_responses = None
		if u'allowed_responses' in self.var:
			self._allowed_responses = []
			for r in safe_decode(self.var.allowed_responses).split(u';'):
				if r.strip() != u'':
					try:
						r = int(r)
					except:
						raise osexception(
							u"'%s' is not a valid response in srbox '%s'. Expecting a number in the range 0 .. 5." \
							% (r, self.name))
					if r < 0 or r > 255:
						raise osexception(
							u"'%s' is not a valid response in srbox '%s'. Expecting a number in the range 0 .. 5." \
							% (r, self.name))
					self._allowed_responses.append(r)
			if not self._allowed_responses:
				self._allowed_responses = None
		debug.msg(u"allowed responses set to %s" % self._allowed_responses)
		# Prepare keyboard for dummy-mode and flushing
		self._keyboard = openexp.keyboard.keyboard(self.experiment)
		if self.var._dummy == u'yes':
			self._resp_func = self._keyboard.get_key
			return
		# Prepare the device string
		dev = self.var.dev
		if dev == u"autodetect":
			dev = None
		# Dynamically create an srbox instance
		if not hasattr(self.experiment, "srbox"):
			self.experiment.srbox = libsrbox.libsrbox(self.experiment, dev)
			self.experiment.cleanup_functions.append(self.close)
			self.python_workspace[u'srbox'] = self.experiment.srbox
		# Prepare the light byte
		s = "010" # Control string
		for i in range(5):
			if str(5 - i) in str(self.var.lights):
				s += "1"
			else:
				s += "0"
		self._lights = chr(int(s, 2))
		debug.msg(u"lights string set to %s (%s)" % (s, self.var.lights))
		# Prepare auto response
		if self.experiment.auto_response:
			self._resp_func = self.auto_responder
		else:
			self._resp_func = self.experiment.srbox.get_button_press
Esempio n. 31
0
def _match_env(env):
    """
	Allows for easy translation between various envelope names

	Arguments:
	env -- an envelope name

	Exception:
	Throws an osexception if an unknown envelope was specified

	Returns:
	A standard envelope name ("c", "g", "r" or "l")
	"""

    global env_synonyms
    if env not in env_synonyms:
        raise osexception(u"'%s' is not a valid envelope" % env)
    return env_synonyms[env]
Esempio n. 32
0
    def _activate(self):
        """
		visible:
			False

		desc:
			A wrapper around [activate] to catch Exceptions.
		"""

        try:
            self.activate()
        except Exception as e:
            if not isinstance(e, osexception):
                e = osexception(msg=u'Extension error', exception=e)
            self.notify(
             u'Extension %s misbehaved on activate (see debug window for stack trace)' \
             % self.name())
            self.console.write(e)
Esempio n. 33
0
	def set_value(self, val):
	
		"""
		desc:
			Sets the rating scale value.
		
		arguments:
			val:
				desc:	The value.
				type:	int
		"""
		
		if val != None and (val >= len(self.nodes) or val < 0):
			raise osexception( \
				u'Trying to select a non-existing node (%s). Did you specify an incorrect default value?' \
				% val)
		self.value = val
		self.set_var(val)
Esempio n. 34
0
	def from_string(self, string):

		"""See item."""

		self.variables = {}
		self.comments = []
		self.reset()
		if string is None:
			return
		for line in string.split(u'\n'):
			self.parse_variable(line)
			cmd, arglist, kwdict = self.experiment.syntax.parse_cmd(line)
			if cmd == u'log' and len(arglist) > 0:
				for var in arglist:
					if not self.experiment.syntax.valid_var_name(
						safe_decode(var)):
						raise osexception(u'Invalid variable name: %s' % var)
				self.logvars += arglist
Esempio n. 35
0
    def get_joyinput(self, joybuttonlist=None, timeout=None):
        """See _libjoystick.basejoystick"""

        if joybuttonlist == None or joybuttonlist == []:
            joybuttonlist = self._joybuttonlist
        if timeout == None:
            timeout = self.timeout

        pos = []
        ballpos = []
        hatpos = []
        eventtype = None
        start_time = pygame.time.get_ticks()
        time = start_time

        while timeout == None or time - start_time <= timeout:
            time = pygame.time.get_ticks()
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        raise osexception(u"The escape key was pressed.")
                if event.type == JOYBUTTONDOWN:
                    if joybuttonlist == None or event.button + 1 in \
                     joybuttonlist:
                        eventtype = u'joybuttonpress'
                        bpress = event.button + 1
                        return eventtype, bpress, time
                if event.type == JOYAXISMOTION:
                    eventtype = u'joyaxismotion'
                    for axis in range(self.js.get_numaxes()):
                        pos.append(self.js.get_axis(axis))
                    return eventtype, pos, time
                if event.type == JOYBALLMOTION:
                    eventtype = u'joyballmotion'
                    for ball in range(self.js.get_numballs()):
                        ballpos.append(self.js.get_ball(ball))
                    return eventtype, ballpos, time
                if event.type == JOYHATMOTION:
                    eventtype = u'joyhatmotion'
                    for hat in range(self.js.get_numhats()):
                        hatpos.append(self.js.get_hat(hat))
                    return eventtype, hatpos, time

        return eventtype, None, time
Esempio n. 36
0
	def set_var(self, val, var=None):

		"""
		desc:
			Sets an experimental variable.

		arguments:
			val:
				desc:	A value.
				type:	[str, unicode]

		keywords:
			var:
				desc:	A variable name, or `None` to use widget default.
				type:	[str, unicode, NoneType]
		"""

		if var is None:
			var = self.var
		if var is None:
			return

		# Set the response variable
		l_val = []

		# When this function is called via the constructor, the checkbox is not
		# yet part of the form. Therefore, we need to add it explicitly to the
		# widget list.
		widget_list = self.form.widgets[:]
		if self not in self.form.widgets:
			widget_list += [self]

		for widget in widget_list:
			if widget is not None and widget.type == u'checkbox' and \
				widget.var == self.var:
				if widget.group != self.group and self.group is not None:
					raise osexception(_( \
						u'All checkbox widgets without a group or within the same group should have the same variable.'))
				if widget.checked or widget.checked == u'yes':
					l_val.append(safe_decode(widget.text))
		val = u';'.join(l_val)
		if val == u'':
			val = u'no'
		button.set_var(self, val, var=var)
Esempio n. 37
0
	def handle_starttag(self, tag, attrs):

		"""
		Handle an opening tag

		Arguments:
		tag -- the closing tag
		attrs -- the tag attributes
		"""

		if tag not in self.valid_start_tags:
			return
		if tag == u'br':
			self.text.append(self.paragraph)
			self.paragraph = []
			return
		self.current_tag = tag
		if tag == u'span':
			style = {}
			for var, val in attrs:
				if var == u'style':
					var = u'font_family'
				elif var == u'bold':
					var = u'font_bold'
				elif var == u'italic':
					var = u'font_italic'
				elif var == u'bold':
					var = u'font_underline'
				elif var == u'size':
					var = u'font_size'
					try:
						val = int(val)
					except:
						raise osexception(u'Invalid font size: %s' % val)
				style[str(var)] = val
			self.push_style(**style)
		elif tag == u'b':
			self.push_style(font_bold=True)
		elif tag == u'i':
			self.push_style(font_italic=True)
		elif tag == u'u':
			self.push_style(font_underline=True)
		else:
			debug.msg(u'Unrecognized tag: %s' % tag)
Esempio n. 38
0
	def init_display(experiment):

		if experiment.resolution() != resolution:
			raise osexception(
				(u'The droid back-end requires a resolution of %d x %d. Your '
				u'display will be scaled automatically to fit devices with '
				u'different resolutions.') % resolution
			)
		# Intialize PyGame
		if not pygame.display.get_init():
			pygame.init()
		experiment.window = pygame.display.set_mode(resolution)
		experiment.surface = pygame.display.get_surface()
		# Set the time functions to use pygame
		experiment._time_func = pygame.time.get_ticks
		experiment._sleep_func = pygame.time.delay
		experiment.time = experiment._time_func
		experiment.sleep = experiment._sleep_func
		# Initialze the Android device if necessary
		if android is not None:
			android.init()
			android.map_key(android.KEYCODE_BACK, pygame.K_ESCAPE)
			dpi = android.get_dpi()
		else:
			# A dummy dpi if we are not on Android
			dpi = 96
		# Log the device characteristics
		info = pygame.display.Info()
		diag = hypot(info.current_w, info.current_h) / dpi
		experiment.var.device_resolution_width = info.current_w
		experiment.var.device_resolution_height = info.current_h
		experiment.var.device_dpi = dpi
		experiment.var.device_screen_diag = diag
		experiment.var.device_is_tablet = u'yes' if diag >= 6 else u'no'
		# Start with a splash screen
		splash = pygame.image.load(experiment.resource('android-splash.jpg'))
		x = resolution[0]/2 - splash.get_width()/2
		y = resolution[1]/2 - splash.get_height()/2
		experiment.surface.blit(splash, (x, y))
		for i in range(10):
			pygame.display.flip()
			pygame.time.delay(100)
		if android is not None and android.check_pause():
			android.wait_for_resume()
Esempio n. 39
0
	def init_display(experiment):

		global _experiment, _old_gamma
		_experiment = experiment
		# Set the PsychoPy monitor, default to testMonitor
		monitor = experiment.var.get(u'psychopy_monitor', u'testMonitor')
		waitblanking = experiment.var.get(u'psychopy_waitblanking', u'yes', \
			[u'yes', u'no']) == u'yes'
		screen = experiment.var.get(u'psychopy_screen', 0)
		# Print some information to the debug window
		print(u'openexp._canvas.psycho.init_display(): waitblanking = %s' % \
			waitblanking)
		print(u'openexp._canvas.psycho.init_display(): monitor = %s' % monitor)
		print(u'openexp._canvas.psycho.init_display(): screen = %s' % screen)
		# Initialize the PsychoPy window and set various functions

		experiment.window = visual.Window(experiment.resolution(),
			screen=screen, waitBlanking=waitblanking,
			fullscr=experiment.var.fullscreen==u'yes', monitor=monitor,
			units=u'pix',
			rgb=color(experiment, experiment.var.background).backend_color,
			winType=u'pyglet', allowStencil=True)
		event.Mouse(visible=False, win=experiment.window)
		experiment.window.winHandle.set_caption(u'OpenSesame (PsychoPy backend)')
		# Set Gamma value if specified
		gamma = experiment.var.get(u'psychopy_gamma', u'unchanged')
		if type(gamma) in (int, float) and gamma > 0:
			_old_gamma = experiment.window.gamma
			experiment.window.setGamma(gamma)
		elif gamma != u'unchanged':
			raise osexception( \
				u'Gamma should be a positive numeric value or "unchanged"')
		# Register the built-in OpenSesame fonts.
		for font in [u'sans', u'serif', u'mono', u'arabic', u'hebrew', u'hindi',
			u'chinese-japanese-korean']:
			font_path = experiment.resource(u'%s.ttf' % font)
			register_font(font_path)
		# Override the default quit function, so that the application is not exited
		core.quit = _psychopy_clean_quit
		# Optionally change the logging level to avoid a lot of warnings in the
		# debug window
		if experiment.var.get(u'psychopy_suppress_warnings', u'yes'):
			logging.console.setLevel(logging.CRITICAL)
Esempio n. 40
0
	def __getitem__(self, extension_name):

		"""
		desc:
			Emulates a dict interface for retrieving extensions.

		arguments:
			extension_name:
				desc:	The extension name.
				type:	str

		returns:
			type:	base_extension
		"""

		for ext in self._extensions:
			if ext.name() == extension_name:
				return ext
		raise osexception(u'Extension %s does not exist' % extension_name)
Esempio n. 41
0
	def __init__(self, coroutines, _item, start_time, end_time,
		abort_on_end=False):

		"""
		desc:
			Constructor.

		arguments:
			item:
				desc:	An item object.
				type:	item
		"""

		if not hasattr(_item, u'coroutine'):
			raise osexception(
				u'%s not supported by coroutines' % _item.item_type)
		self._item = _item
		base_task.__init__(self, coroutines, start_time, end_time, abort_on_end)
		self.coroutines.event(u'initialize %s' % _item.coroutine)
Esempio n. 42
0
	def execute(self):
		
		"""See base_runner.execute()."""
		
		# Exceptions during the run phase are important and returned so that the
		# user is notified.
		e = None
		try:
			self.experiment.run()
		except Exception as e:
			if not isinstance(e, osexception):
				e = osexception(u'Unexpected error', e)
		# Exceptions during the end phase are less important and only printed
		# to the debug window.
		try:
			self.experiment.end()
		except Exception as _e:
			debug.msg(u'Exception during experiment.end(): %s' % _e)
		return e
Esempio n. 43
0
    def image(self, fname, center=True, x=None, y=None, scale=None):

        x, y = self.to_xy(x, y)
        if not center:
            _fname = safe_decode(fname)
            try:
                surf = pygame.image.load(_fname)
            except pygame.error:
                raise osexception(u"'%s' is not a supported image format" %
                                  fname)
            if scale is None:
                x += surf.get_width() / 2
                y -= surf.get_height() / 2
            else:
                x += scale * surf.get_width() / 2
                y -= scale * surf.get_height() / 2
        stim = stimuli.Picture(fname, position=(x, y))
        if scale is not None: stim.scale((scale, scale))
        self.add_stim(stim)
Esempio n. 44
0
    def get_property(self, name, _type=str, fallback=None):
        """
		desc:
			Gets an element property.

		arguments:
			name:	The property name.

		keywords:
			_type:		The property type.
			fallback:	A fallback value, in case the value cannot be cast to
						the requested type.

		returns:
			The property in the specified type, or None if the property doesn't
			exist.
		"""

        properties = self.eval_properties()
        if name not in properties:
            return None
        val = properties[name]
        if _type == str:
            return str(val)
        if _type == int:
            try:
                return int(val)
            except ValueError:
                return fallback
        if _type == float:
            try:
                return float(val)
            except ValueError:
                return fallback
        if _type == bool:
            if isinstance(val, str):
                if val in (u'yes', u'1'):
                    return True
                if val in (u'no', u'0'):
                    return False
                return fallback
            return bool(val)
        raise osexception(u'Unknown type: %s' % _type)
Esempio n. 45
0
    def fade_in(self, ms):
        """<DOC>
		Sets the fade-in time in milliseconds.

		Arguments:
		ms -- An integer value specifying the duration in milliseconds.

		Example:
		>>> from openexp.sampler import sampler
		>>> src = exp.get_file('my_sound.ogg')
		>>> my_sampler = sampler(exp, src)
		>>> my_sampler.fade_in(100)
		</DOC>"""

        if type(ms) != int or ms < 0:
            raise osexception( \
             u"openexp._sampler.legacy.fade_in() requires a positive integer")

        self._fade_in = ms
Esempio n. 46
0
    def get_file(self, path):
        """
		desc: |
			Returns the full path to a file. The logic is as follows:

			1. First checks if `path` is a file in the file pool.
			2. If not, check if `path` is a file in the folder of the current
			   experiment (if any).
			3. If not, check if `path` is a file in the `__pool__` subfolder of
			   the current experiment.
			4. If not, simply return `path`.

		arguments:
			path:
				desc:	A filename. This can be any type, but will be coerced
						to `unicode` if it is not `unicode`.

		returns:
			desc:	The full path to the file.
			type:	unicode

		example: |
			image_path = exp.get_file('my_image.png')
			my_canvas = exp.offline_canvas()
			my_canvas.image(image_path)
		"""

        path = self.unistr(path)
        if path.strip() == u'':
            raise osexception(
                u"An empty string was passed to experiment.get_file(). Please "
                u"specify a valid filename.")
        if os.path.exists(os.path.join(self.pool_folder, path)):
            return os.path.join(self.pool_folder, path)
        if self.experiment_path != None:
            if os.path.exists(os.path.join(self.experiment_path, path)):
                return os.path.join(self.experiment_path, path)
            if self.fallback_pool_folder != None and os.path.exists(
                    os.path.join(self.experiment_path,
                                 self.fallback_pool_folder, path)):
                return os.path.join(self.experiment_path,
                                    self.fallback_pool_folder, path)
        return path
Esempio n. 47
0
    def get_click(self):

        if android is None:
            pygame.mouse.set_visible(self.visible)
        buttonlist = self.buttonlist
        timeout = self.timeout
        enable_escape = self.experiment.var.get(u'enable_escape', u'no',
                                                [u'yes', u'no']) == u'yes'
        start_time = pygame.time.get_ticks()
        time = start_time
        while True:
            time = pygame.time.get_ticks()
            # Process the input
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.experiment.pause()
                        continue
                    pygame.event.post(event)
                if event.type == MOUSEBUTTONDOWN:
                    # Check escape sequence. If the top-left and top-right
                    # corner are clicked successively within 2000ms, the
                    # experiment is aborted
                    if enable_escape and event.pos[0] < 64 and event.pos[1] \
                     < 64:
                        _time = pygame.time.get_ticks()
                        while pygame.time.get_ticks() - _time < 2000:
                            for event in pygame.event.get():
                                if event.type == MOUSEBUTTONDOWN:
                                    if event.pos[0] > \
                                     self.experiment.var.width-64 and \
                                     event.pos[1] < 64:
                                        raise osexception(
                                            u"The escape sequence was clicked/ tapped"
                                        )
                    if buttonlist is None or event.button in buttonlist:
                        return event.button, self.from_xy(event.pos), time
            if timeout is not None and time - start_time >= timeout:
                break
            # Allow Android interrupt
            if android is not None and android.check_pause():
                android.wait_for_resume()
        return None, None, time
Esempio n. 48
0
    def prepare(self):
        """Prepares for playback."""

        item.item.prepare(self)
        try:
            self.sampler = openexp.synth.synth(self.experiment, \
             self.get(u'osc'), self.get(u'freq'), self.get(u'length'), \
             self.get(u'attack'), self.get(u'decay'))
        except Exception as e:
            raise osexception( \
             u"Failed to generate sound in synth '%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'))
        generic_response.generic_response.prepare(self)
Esempio n. 49
0
def _match_env(env):
    """
	desc:
		Translation between various envelope names.

	arguments:
		env:
			desc:	An envelope name.
			type:	[str, unicode]

	returns:
		desc: A standard envelope name ("c", "g", "r" or "l")
		type: unicode
	"""

    global env_synonyms
    if env not in env_synonyms:
        raise osexception(u"'%s' is not a valid envelope" % env)
    return env_synonyms[env]
Esempio n. 50
0
    def _init_canvas_elements(self):
        """
		desc:
			Initializes all canvas elements.
		"""

        _path = safe_str(self.path, enc=misc.filesystem_encoding())
        if not os.path.exists(_path):
            raise osexception(
                u'No valid path has been specified in image widget')
        x, y, w, h = self.rect
        x += w / 2
        y += h / 2
        print(_path)
        self.canvas.add_element(
            ImageElement(_path, x=x, y=y, scale=self.scale,
                         center=True).construct(self.canvas))
        if self.frame:
            self._update_frame(self.rect)
Esempio n. 51
0
    def __init__(self,
                 experiment,
                 buttonlist=None,
                 timeout=None,
                 visible=False):

        self.experiment = experiment
        self.set_buttonlist(buttonlist)
        self.set_timeout(timeout)
        self.set_visible(visible)
        if self.experiment.get_check('custom_cursor', 'no') == 'yes':
            if self.experiment.expyriment.screen._fullscreen:
                raise osexception(
                    'The xpyriment mouse back-end does not support custom cursors in fullscreen mode (you can change this in the back-end settings)'
                )
            self.cursor = stimuli.Picture(
                self.experiment.resource('cursor.png'))
        else:
            self.cursor = None
Esempio n. 52
0
    def stop_after(self, ms):
        """<DOC>
		Specifies a duration after which the sampler stops playing.

		Arguments:
		ms -- An integer value specifying the duration in milliseconds.

		Example:
		>>> from openexp.sampler import sampler
		>>> src = exp.get_file('my_sound.ogg')
		>>> my_sampler = sampler(exp, src)
		>>> my_sampler.stop_after(100)
		</DOC>"""

        if type(ms) != int or ms < 0:
            raise osexception( \
             u"openexp._sampler.legacy.stop_after() requires a positive integer")

        self._stop_after = ms
Esempio n. 53
0
	def render(self):

		"""
		desc:
			Draws the widget.
		"""

		x, y, w, h = self.rect
		cx = x+w/2
		cy = y+h/2
		_h = self.form.theme_engine.box_size()
		if self.orientation == u'horizontal':
			# Some ugly maths, but basically it evenly spaces the checkboxes and
			# draws a frame around it.
			dx = (1*w-3*_h)/(len(self.nodes)-1)
			self.form.theme_engine.frame(x, cy-.5*_h, w, 2*_h, style=u'light')
			_x = x+_h
			i = 0
			for node in self.nodes:
				self.form.theme_engine.box(_x, cy, checked=(self.value == i))
				text_height = self.form.canvas.text_size(node)[1]
				self.form.canvas.text(node, center=True, x=_x+self.box_size/2, \
					y=cy-text_height)
				self.pos_list.append( (_x, cy) )
				_x += dx
				i += 1
		elif self.orientation == u'vertical':
			dy = (1*h-3*_h)/(len(self.nodes)-1)
			self.form.theme_engine.frame(cx-.5*_h, y, 2*_h, h, style=u'light')
			_y = y+_h
			i = 0
			for node in self.nodes:
				self.form.theme_engine.box(cx, _y, checked=(self.value == i))
				text_width = self.form.canvas.text_size(node)[0]
				self.form.canvas.text(node, center=True, x=cx-text_width,
					y=_y+self.box_size/2)
				self.pos_list.append( (cx, _y) )
				_y += dy
				i += 1
		else:
			raise osexception( \
				u'rating_scale orientation must be "horizontal" or "vertical", not "%s"' % \
				self.orientation)
Esempio n. 54
0
    def __init__(self, form):
        """<DOC>
		Constructor.
		
		Arguments:
		form -- The parent form.
		</DOC>"""

        self.type = u'widget'
        self.form = form
        self.rect = None
        self.focus = False
        self.var = None

        # Check if the form parameter is valid
        if not isinstance(form, _form):
            raise osexception( \
             u'The first parameter passed to the constructor of a form widget should be a form, not "%s"' \
             % form)
Esempio n. 55
0
    def shift(self, key, mods=[u"shift"]):
        """
		DEPRECATED
		
		This function has been deprecated as of 0.27.4. Shift is handled
		transparently by keyboard.get_key()
		
		Arguments:
		key 	--	A key.
		
		Keyword arguments:
		mods	--	A list of keyboard modifiers.
		
		Exception:
		This function always raises an exception
		"""

        raise osexception( \
         u"keyboard.shift() is deprecated")
Esempio n. 56
0
    def time(self):
        """
		desc:
			Returns a timestamp for the current time. This timestamp only has
			a relative meaning, i.e. you can use it to determine the interval
			between two moments, but not the actual time. Whether the timestamp
			is a `float` or `int` depends on the back-end.

		returns:
			desc:	A timestamp of the current time.
			type:	[int, float]

		example: |
			print('The time is %s' % self.time())
		"""

        # This function is set by item.prepare()
        raise osexception( \
         u"item.time(): This function should be set by the canvas backend.")
Esempio n. 57
0
    def run(self):
        """<DOC>
		Executes the run script. The code that you enter in the 'run' tab of #
		an inline_script item in the GUI is used as a body for this function.
		</DOC>"""

        global _globals, _locals
        # 'self' must always be registered, otherwise we get confusions between
        # the various inline_script items.
        _globals[u'self'] = self
        if self.experiment.transparent_variables == u'yes':
            self.start_transparency()
        try:
            exec(self.crun, _globals)
        except Exception as e:
            raise osexception(u'Error while executing inline script', item= \
             self.name, phase=u'run', exception=e)
        if self.experiment.transparent_variables == u'yes':
            self.end_transparency()
Esempio n. 58
0
    def drop_get_item_snippet(self, data):
        """
		desc:
			Gets the item and list of newly created items for item-snippet
			drops.

		arguments:
			data:
				desc:	The drop data.
				type:	dict

		returns:
			desc:	An (name, new_items) tuple.
			type:	tuple
		"""

        for item_dict in data[u'items']:
            if not self.experiment.items.valid_type(item_dict[u'item-type']):
                raise osexception(
                    _(u'Unknown item type: %s') % item_dict[u'item-type'])
        rename = []
        new_items = []
        main_item = None
        for item_dict in data[u'items']:
            item = self.experiment.items.new(item_dict[u'item-type'],
                                             item_dict[u'item-name'],
                                             item_dict[u'script'],
                                             catch_exceptions=False)
            if item_dict[u'item-name'] == data[u'main-item-name']:
                main_item = item
            # If the item didn't get the suggested name
            if item.name != item_dict[u'item-name']:
                rename.append((item_dict[u'item-name'], item.name))
            new_items.append(item)
            self.extension_manager.fire(u'new_item',
                                        name=item.name,
                                        _type=item.item_type)
        # Inform all newly created items of any renames that occurred
        for old_name, new_name in rename:
            for item in new_items:
                item.rename(old_name, new_name)
        return main_item, [item.name for item in new_items]
Esempio n. 59
0
    def run(self):
        """
		desc:
			Executes the run script. The code that you enter in the 'run' tab of
			an inline_script item in the GUI is used as a body for this
			function.
		"""

        self.set_item_onset()
        # 'self' must always be registered, otherwise we get confusions between
        # the various inline_script items.
        self.experiment.python_workspace[u'self'] = self
        try:
            self.experiment.python_workspace._exec(self.crun)
        except Exception as e:
            raise osexception(u'Error while executing inline script',
                              line_offset=-1,
                              item=self.name,
                              phase=u'run',
                              exception=e)
Esempio n. 60
0
def libjoystick(experiment, **kwargs):
    """
	A factory that returns a back-end specific joystick module.

	Arguments:
	experiment		--	The experiment object.

	Keyword arguments:
	**kwargs		--	A keyword-argument dictionary.
	"""

    if experiment.get(u'canvas_backend') == u'psycho':
        raise osexception(
            u'The joystick plug-in does not yet support the psycho back-end')
    backend = u'legacy'
    cls = plugins.load_cls(__file__,
                           cls=backend,
                           mod=backend,
                           pkg=u'_libjoystick')
    return cls(experiment, **kwargs)