Example #1
0
    def execute(self):
        """See base_runner.execute()."""

        import multiprocessing
        from libqtopensesame.misc import process, _
        from libopensesame import misc, debug
        from StringIO import StringIO
        if os.name == u'nt':
            # Under Windows, the multiprocess runner assumes that there is a
            # file called `opensesame.py` or `opensesame.pyc`. If this file does
            # not exist, try to copy it from the main script (`opensesame`). If
            # this fails, provide an informative error message.
            os_folder = misc.opensesame_folder()
            if not os.path.exists(os.path.join(os_folder, u'opensesame.pyc')) \
             and not os.path.exists(os.path.join(os_folder, u'opensesame.py')):
                import shutil
                try:
                    shutil.copyfile(os.path.join(os_folder, u'opensesame'), \
                     os.path.join(os_folder, u'opensesame.py'))
                except Exception as e:
                    return osexception( \
                     _(u'Failed to copy `opensesame` to `opensesame.py`, which is required for the multiprocess runner. Please copy the file manually, or select a different runner under Preferences.'), exception=e)
        self.channel = multiprocessing.Queue()
        self.exp_process = process.ExperimentProcess(self.experiment, \
         self.channel)
        # Start process!
        self.exp_process.start()
        # Variables used for ugly hack to suppress 'None' print by Queue.get()
        _stdout = sys.stdout
        _pit = StringIO()
        # Wait for experiment to finish.
        # Listen for incoming messages in the meantime.
        while self.exp_process.is_alive() or not self.channel.empty():
            QtGui.QApplication.processEvents()
            # Make sure None is not printed. Ugly hack for a bug in the Queue
            # class?
            sys.stdout = _pit
            # Wait for messages. Will throw Exception if no message is received
            # before timeout.
            try:
                msg = self.channel.get(True, 0.05)
            except:
                msg = None
            # Restore connection to stdout
            sys.stdout = _stdout
            # For standard print statements
            if isinstance(msg, basestring):
                sys.stdout.write(msg)
            # Errors arrive as a tuple with (Error object, traceback)
            elif isinstance(msg, Exception):
                return msg
            # Anything that is not a string, not an Exception, and not None is
            # unexpected
            elif msg != None:
                return osexception( \
                 u"Illegal message type received from child process: %s (%s)" \
                 % (msg, type(msg)))
        # Return None if experiment finished without problems
        return None
Example #2
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)
Example #3
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
		try:
			exp.run()
		except Exception as e_run:
			if not isinstance(e_run, osexception):
				e_run = osexception(u'Unexpected error', exception=e_run)
		# 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 != None:
			self.output.put(e_run)
			sys.exit(1)
		# Exit with success
		sys.exit(0)
Example #4
0
    def execute(self):
        """See base_runner.execute()."""

        import platform
        # In OS X the multiprocessing module is horribly broken, but a fixed
        # version has been released as the 'billiard' module
        if platform.system() == 'Darwin':
            import billiard as multiprocessing
            multiprocessing.forking_enable(0)
        else:
            import multiprocessing

        from libqtopensesame.misc import process, _
        from libopensesame import misc

        self._workspace_globals = {}
        if os.name == u'nt' or (sys.platform == u'darwin' \
         and not hasattr(sys,"frozen")):
            # Under Windows and OSX, the multiprocess runner assumes that there
            # is a file called `opensesame.py` or `opensesame.pyc`. If this file
            # does not exist, try to copy it from the main script
            # (`opensesame`). If this fails, provide an informative error
            # message.
            os_folder = misc.opensesame_folder()
            # misc.opensesame_folder() doesn't work for OSX and returns None then,
            # so determine OpenSesame's rootdir in another way
            if os_folder is None:
                os_folder = os.path.dirname(
                    os.path.abspath(sys.modules['__main__'].__file__))
            if not os.path.exists(os.path.join(os_folder, u'opensesame.pyc')) \
             and not os.path.exists(os.path.join(os_folder, u'opensesame.py')):
                import shutil
                try:
                    shutil.copyfile(os.path.join(os_folder, u'opensesame'),
                                    os.path.join(os_folder, u'opensesame.py'))
                except Exception as e:
                    return osexception(_(
                        u'Failed to copy `opensesame` to `opensesame.py`, which is required for the multiprocess runner. Please copy the file manually, or select a different runner under Preferences.'
                    ),
                                       exception=e)
        self.channel = multiprocessing.Queue()
        try:
            self.exp_process = process.ExperimentProcess(
                self.experiment, self.channel)
        except Exception as e:
            return osexception(_(u'Failed to initialize experiment process'),
                               exception=e)
        # Start process!
        self.exp_process.start()
        # Wait for experiment to finish.
        # Listen for incoming messages in the meantime.
        while self.exp_process.is_alive() or not self.channel.empty():
            # We need to process the GUI. To make the GUI feel more responsive
            # during pauses, we refresh the GUI more often when paused.
            QtGui.QApplication.processEvents()
            if self.paused:
                for i in range(25):
                    time.sleep(.01)
                    QtGui.QApplication.processEvents()
            # Make sure None is not printed. Ugly hack for a bug in the Queue
            # class?
            self.console.suppress_stdout()
            # Wait for messages. Will throw Exception if no message is received
            # before timeout.
            try:
                msg = self.channel.get(True, 0.05)
            except:
                continue
            # Restore connection to stdout
            self.console.capture_stdout()
            if isinstance(msg, basestring):
                sys.stdout.write(safe_decode(msg, errors=u'ignore'))
                continue
            # Capture exceptions
            if isinstance(msg, Exception):
                return msg
            # The workspace globals are sent as a dict. A special __pause__ key
            # indicates whether the experiment should be paused or resumed.
            if isinstance(msg, dict):
                self._workspace_globals = msg
                if u'__heartbeat__' in msg:
                    self.console.set_workspace_globals(msg)
                    self.main_window.extension_manager.fire(u'heartbeat')
                elif u'__pause__' in msg:
                    if msg[u'__pause__']:
                        self.pause()
                    else:
                        self.resume()
                continue
            # Anything that is not a string, not an Exception, and not None is
            # unexpected
            return osexception(
             u"Illegal message type received from child process: %s (%s)" \
             % (msg, type(msg)))
        # Return None if experiment finished without problems
        return None
    def execute(self):

        """See base_runner.execute()."""

        import multiprocessing
        from libqtopensesame.misc import process, _
        from libopensesame import misc, debug
        from StringIO import StringIO

        if os.name == u"nt":
            # Under Windows, the multiprocess runner assumes that there is a
            # file called `opensesame.py` or `opensesame.pyc`. If this file does
            # not exist, try to copy it from the main script (`opensesame`). If
            # this fails, provide an informative error message.
            os_folder = misc.opensesame_folder()
            if not os.path.exists(os.path.join(os_folder, u"opensesame.pyc")) and not os.path.exists(
                os.path.join(os_folder, u"opensesame.py")
            ):
                import shutil

                try:
                    shutil.copyfile(os.path.join(os_folder, u"opensesame"), os.path.join(os_folder, u"opensesame.py"))
                except Exception as e:
                    return osexception(
                        _(
                            u"Failed to copy `opensesame` to `opensesame.py`, which is required for the multiprocess runner. Please copy the file manually, or select a different runner under Preferences."
                        ),
                        exception=e,
                    )
        self.channel = multiprocessing.Queue()
        self.exp_process = process.ExperimentProcess(self.experiment, self.channel)
        # Start process!
        self.exp_process.start()
        # Variables used for ugly hack to suppress 'None' print by Queue.get()
        _stdout = sys.stdout
        _pit = StringIO()
        # Wait for experiment to finish.
        # Listen for incoming messages in the meantime.
        while self.exp_process.is_alive() or not self.channel.empty():
            QtGui.QApplication.processEvents()
            # Make sure None is not printed. Ugly hack for a bug in the Queue
            # class?
            sys.stdout = _pit
            # Wait for messages. Will throw Exception if no message is received
            # before timeout.
            try:
                msg = self.channel.get(True, 0.05)
            except:
                msg = None
                # Restore connection to stdout
            sys.stdout = _stdout
            # For standard print statements
            if isinstance(msg, basestring):
                sys.stdout.write(msg)
                # Errors arrive as a tuple with (Error object, traceback)
            elif isinstance(msg, Exception):
                return msg
                # Anything that is not a string, not an Exception, and not None is
                # unexpected
            elif msg != None:
                return osexception(u"Illegal message type received from child process: %s (%s)" % (msg, type(msg)))
                # Return None if experiment finished without problems
        return None
	def execute(self):
		
		"""See base_runner.execute()."""
		
		import platform
		# In OS X the multiprocessing module is horribly broken, but a fixed
		# version has been released as the 'billiard' module
		if platform.system() == 'Darwin':
			import billiard as multiprocessing
			multiprocessing.forking_enable(0)
		else:
			import multiprocessing
	
		from libqtopensesame.misc import process, _
		from libopensesame import misc, debug
		from StringIO import StringIO
		if os.name == u'nt' or (sys.platform == u'darwin' and not hasattr(sys,"frozen")):
			# Under Windows and OSX, the multiprocess runner assumes that there is a
			# file called `opensesame.py` or `opensesame.pyc`. If this file does
			# not exist, try to copy it from the main script (`opensesame`). If
			# this fails, provide an informative error message.
			os_folder = misc.opensesame_folder()
			
			# misc.opensesame_folder() doesn't work for OSX and returns None then, 
			# so determine OpenSesame's rootdir in another way
			if os_folder is None:
				os_folder = os.path.dirname(os.path.abspath(sys.modules['__main__'].__file__))

			if not os.path.exists(os.path.join(os_folder, u'opensesame.pyc')) \
				and not os.path.exists(os.path.join(os_folder, u'opensesame.py')):
				import shutil
				try:
					shutil.copyfile(os.path.join(os_folder, u'opensesame'), \
						os.path.join(os_folder, u'opensesame.py'))
				except Exception as e:			
					return osexception( \
						_(u'Failed to copy `opensesame` to `opensesame.py`, which is required for the multiprocess runner. Please copy the file manually, or select a different runner under Preferences.'), exception=e)
		self.channel = multiprocessing.Queue()
		self.exp_process = process.ExperimentProcess(self.experiment, \
			self.channel)
		# Start process!
		self.exp_process.start()
		# Variables used for ugly hack to suppress 'None' print by Queue.get()
		_stdout = sys.stdout	
		_pit = StringIO()
		# Wait for experiment to finish.
		# Listen for incoming messages in the meantime.
		while self.exp_process.is_alive() or not self.channel.empty():
			QtGui.QApplication.processEvents()
			# Make sure None is not printed. Ugly hack for a bug in the Queue
			# class?
			sys.stdout = _pit
			# Wait for messages. Will throw Exception if no message is received
			# before timeout.
			try:
				msg = self.channel.get(True, 0.05)
			except:
				msg = None
			# Restore connection to stdout
			sys.stdout = _stdout
			# For standard print statements
			if isinstance(msg, basestring):
				sys.stdout.write(msg)
			# Errors arrive as a tuple with (Error object, traceback)
			elif isinstance(msg, Exception):
				return msg
			# Anything that is not a string, not an Exception, and not None is
			# unexpected
			elif msg != None:
				return osexception( \
					u"Illegal message type received from child process: %s (%s)" \
					% (msg, type(msg)))
		# Return None if experiment finished without problems
		return None
	def execute(self):

		"""See base_runner.execute()."""

		import platform
		# In OS X the multiprocessing module is horribly broken, but a fixed
		# version has been released as the 'billiard' module
		if platform.system() == 'Darwin':
			import billiard as multiprocessing
			multiprocessing.forking_enable(0)
		else:
			import multiprocessing

		from libqtopensesame.misc import process, _
		from libopensesame import misc

		self._workspace_globals = {}
		if os.name == u'nt' or (sys.platform == u'darwin' \
			and not hasattr(sys,"frozen")):
			# Under Windows and OSX, the multiprocess runner assumes that there
			# is a file called `opensesame.py` or `opensesame.pyc`. If this file
			# does not exist, try to copy it from the main script
			# (`opensesame`). If this fails, provide an informative error
			# message.
			os_folder = misc.opensesame_folder()
			# misc.opensesame_folder() doesn't work for OSX and returns None then,
			# so determine OpenSesame's rootdir in another way
			if os_folder is None:
				os_folder = os.path.dirname(
					os.path.abspath(sys.modules['__main__'].__file__))
			if not os.path.exists(os.path.join(os_folder, u'opensesame.pyc')) \
				and not os.path.exists(os.path.join(os_folder, u'opensesame.py')):
				import shutil
				try:
					shutil.copyfile(os.path.join(os_folder, u'opensesame'),
						os.path.join(os_folder, u'opensesame.py'))
				except Exception as e:
					return osexception(
						_(u'Failed to copy `opensesame` to `opensesame.py`, which is required for the multiprocess runner. Please copy the file manually, or select a different runner under Preferences.'), exception=e)
		self.channel = multiprocessing.Queue()
		try:
			self.exp_process = process.ExperimentProcess(self.experiment,
				self.channel)
		except Exception as e:
			return osexception(_(u'Failed to initialize experiment process'),
				exception=e)
		# Start process!
		self.exp_process.start()
		# Wait for experiment to finish.
		# Listen for incoming messages in the meantime.
		while self.exp_process.is_alive() or not self.channel.empty():
			# We need to process the GUI. To make the GUI feel more responsive
			# during pauses, we refresh the GUI more often when paused.
			QtGui.QApplication.processEvents()
			if self.paused:
				for i in range(25):
					time.sleep(.01)
					QtGui.QApplication.processEvents()
			# Make sure None is not printed. Ugly hack for a bug in the Queue
			# class?
			self.console.suppress_stdout()
			# Wait for messages. Will throw Exception if no message is received
			# before timeout.
			try:
				msg = self.channel.get(True, 0.05)
			except:
				continue
			# Restore connection to stdout
			self.console.capture_stdout()
			if isinstance(msg, basestring):
				sys.stdout.write(safe_decode(msg, errors=u'ignore'))
				continue
			# Capture exceptions
			if isinstance(msg, Exception):
				return msg
			# The workspace globals are sent as a dict. A special __pause__ key
			# indicates whether the experiment should be paused or resumed.
			if isinstance(msg, dict):
				self._workspace_globals = msg
				if u'__heartbeat__' in msg:
					self.console.set_workspace_globals(msg)
					self.main_window.extension_manager.fire(u'heartbeat')
				elif u'__pause__' in msg:
					if msg[u'__pause__']:
						self.pause()
					else:
						self.resume()
				continue
			# Anything that is not a string, not an Exception, and not None is
			# unexpected
			return osexception(
				u"Illegal message type received from child process: %s (%s)" \
				% (msg, type(msg)))
		# Return None if experiment finished without problems
		return None