Example #1
0
	def start(self):
		if self.use_DVR:
			print "Starting DVR"
			from DVRwriter				import DVRwriter
			from datetime 				import datetime
			
			metadata = 'unused per-file meta data' #Can be filled in with useful metadata if desired.
			
			if None == self.writer: #need to lazy initialize this because it has to be called after viz.go()
				sz = viz.window.getSize()
				self.now = datetime.now()
				nameRoot = '%s%d.%d.%d.%d-%d' % (self.sysCfg['writer']['outFileDir'], self.now.year, self.now.month, self.now.day, self.now.hour, self.now.minute)
				outFile = '%s.%s' % (nameRoot, self.sysCfg['writer']['outFileName'])
				self.expCfg.filename = '%s.expCfg.cfg' % (nameRoot)
				self.sysCfg.filename = '%s.sysCfg.cfg' % (nameRoot)
				
				
				if 'L' == self.sysCfg['eyetracker']['eye']: 
					viewport = (0,      0,sz[0]/2,sz[1])
				else:               
					viewport = (sz[0]/2,0,sz[0]/2,sz[1])
				#fi
				
				print "OutfileName:" + self.sysCfg['writer']['outFileName']
				print "Metadata:" + metadata
				print "Viewport:" + str(viewport)
				print "Eyetracking:" + str(self.use_eyeTracking)
				
				self.writer = DVRwriter(outFile, metadata, viewport, self.use_eyeTracking)
				self.expCfg.write()
				self.sysCfg.write()
				
			self.writer.turnOn()
Example #2
0
    def start(self):
        if self.use_DVR:
            print "Starting DVR"
            from DVRwriter import DVRwriter
            from datetime import datetime

            metadata = 'unused per-file meta data'  #Can be filled in with useful metadata if desired.

            if None == self.writer:  #need to lazy initialize this because it has to be called after viz.go()
                sz = viz.window.getSize()
                self.now = datetime.now()
                nameRoot = '%s%d.%d.%d.%d-%d' % (
                    self.sysCfg['writer']['outFileDir'], self.now.year,
                    self.now.month, self.now.day, self.now.hour,
                    self.now.minute)
                outFile = '%s.%s' % (nameRoot,
                                     self.sysCfg['writer']['outFileName'])
                self.expCfg.filename = '%s.expCfg.cfg' % (nameRoot)
                self.sysCfg.filename = '%s.sysCfg.cfg' % (nameRoot)

                if 'L' == self.sysCfg['eyetracker']['eye']:
                    viewport = (0, 0, sz[0] / 2, sz[1])
                else:
                    viewport = (sz[0] / 2, 0, sz[0] / 2, sz[1])
                #fi

                print "OutfileName:" + self.sysCfg['writer']['outFileName']
                print "Metadata:" + metadata
                print "Viewport:" + str(viewport)
                print "Eyetracking:" + str(self.use_eyeTracking)

                self.writer = DVRwriter(outFile, metadata, viewport,
                                        self.use_eyeTracking)
                self.expCfg.write()
                self.sysCfg.write()

            self.writer.turnOn()
    def start(self):
        if not self.use_dvr:
            return

        print 'Starting DVR'
        from DVRwriter import DVRwriter

        # Can be filled in with useful metadata if desired.
        metadata = 'unused per-file meta data'

        # need to lazy initialize this because it has to be called after viz.go()
        if self.writer is None:
            root = os.path.join(self.sys['writer']['outFileDir'],
                                datetime.datetime.now().strftime('%Y.%m.%d.%H-%M'))

            self.exp.filename = '{}.exp.cfg'.format(root)
            self.sys.filename = '{}.sys.cfg'.format(root)

            width, height = viz.window.getSize()
            viewport = [width / 2, 0, width / 2, height]
            if 'L' == self.sys['eyetracker']['eye']:
                viewport[0] = 0

            print 'OutfileName:' + self.sys['writer']['outFileName']
            print 'Metadata:' + metadata
            print 'Viewport:' + str(viewport)
            print 'Eyetracking:' + str(self.use_eyetracking)

            self.writer = DVRwriter(
                '{}.{}' % (root, self.sys['writer']['outFileName']),
                metadata, viewport, self.use_eyetracking)

            self.exp.write()
            self.sys.write()

        self.writer.turnOn()
Example #4
0
class VRLabConfig:
    """
	This class represents the configuration for a particular experiment. It has two main components: VRLabConfig.sysCfg
	and VRLabConfig.expCfg that contain the system configuration and the experiment configuration respectively.
	
	VRLabCong.start(): Final initialization after viz.go()
	
	VRLabConfig.sysCfg: The system configuration (a ConfigObj)
	VRLabConfig.expCfg: The experiment configuration (a ConfigObj)
	
	VRLabConfig.writables: A list of variables to be written to the .mov each frame
	VRLabConfig.HMD: The HMD (defined in this file). Is still an HMD even if not using HMD, just disabled.
	VRLabConfig.writer: The DVR writer. None if the writer is not being used or has not been initialized.
	VRLabConfig.eyeTrackingCal: The eyetracking interface. None if we aren't eyetracking
	VRLabConfig.camera: The virtual camera, positioned by headtracking. None if no such camera.
	VRLabConfig.bodyCam: A second virtual camera or tracker
	VRLabConfig.phase_space_markers: Markers for phasespace. Undefined if use_phasespace is false.
	VRLabConfig.phasespace_server: Server for phasespace. Undefined if use_phasespace is false.
	
	VRLabConfig.use_phasespace: True if phasespace is enabled
	VRLabConfig.use_HMD: True if HMD is being used (otherwise configure just for screen)
	VRLabConfig.use_hiball: True if hiball is enabled.
	VRLabConfig.use_eyetracking: True if eyetracking is enabled
	VRLabConfig.use_DVR: True if DVR should record the experiment
	"""
    def __init__(self, expCfgName=""):
        """
		Opens and interprets both the system config (as defined by the <platform>.cfg file) and the experiment config
		(as defined by the file in expCfgName). Both configurations MUST conform the specs given in sysCfgSpec.ini and
		expCfgSpec.ini respectively. It also initializes the system as specified in the sysCfg.
		"""

        self.writables = list()
        if expCfgName:
            self.__createExpCfg(expCfgName)
        else:
            self.expCfg = None
        self.__createSysCfg()

        for pathName in self.sysCfg['set_path']:
            viz.res.addPath(pathName)

        self.__setupSystem()

    def __createSysCfg(self):
        """
		Set up the system config section (sysCfg)
		"""
        sysCfgName = platform.node() + ".cfg"
        if not (os.path.isfile(sysCfgName)):
            sysCfgName = "defaultSys.cfg"
        print "Loading system config file: " + sysCfgName
        sysCfg = ConfigObj(sysCfgName,
                           configspec='sysCfgSpec.ini',
                           raise_errors=True)
        validator = Validator()
        sysCfgOK = sysCfg.validate(validator)
        if sysCfgOK == True:
            print "System config file parsed correctly"
        else:
            print 'System config file validation failed!'
            res = sysCfg.validate(validator, preserve_errors=True)
            for entry in flatten_errors(sysCfg, res):
                # each entry is a tuple
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = 'Missing value or section.'
                print section_string, ' = ', error
            sys.exit(1)
        self.sysCfg = sysCfg
        #self.writables.append(self.sysCfg)

    def __createExpCfg(self, expCfgName):
        """
		Set up the experiment config section (expCfg)
		"""
        print "Loading experiment config file: " + expCfgName

        # This is where the parser is called.
        expCfg = ConfigObj(expCfgName,
                           configspec='expCfgSpec.ini',
                           raise_errors=True,
                           file_error=True)

        validator = Validator()
        expCfgOK = expCfg.validate(validator)
        if expCfgOK == True:
            print "Experiment config file parsed correctly"
        else:
            print 'Experiment config file validation failed!'
            res = expCfg.validate(validator, preserve_errors=True)
            for entry in flatten_errors(expCfg, res):
                # each entry is a tuple
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = 'Missing value or section.'
                print section_string, ' = ', error
            sys.exit(1)
        if expCfg.has_key('_LOAD_'):
            for ld in expCfg['_LOAD_']['loadList']:
                print 'Loading: ' + ld + ' as ' + expCfg['_LOAD_'][ld][
                    'cfgFile']
                curCfg = ConfigObj(expCfg['_LOAD_'][ld]['cfgFile'],
                                   configspec=expCfg['_LOAD_'][ld]['cfgSpec'],
                                   raise_errors=True,
                                   file_error=True)
                validator = Validator()
                expCfgOK = curCfg.validate(validator)
                if expCfgOK == True:
                    print "Experiment config file parsed correctly"
                else:
                    print 'Experiment config file validation failed!'
                    res = curCfg.validate(validator, preserve_errors=True)
                    for entry in flatten_errors(curCfg, res):
                        # each entry is a tuple
                        section_list, key, error = entry
                        if key is not None:
                            section_list.append(key)
                        else:
                            section_list.append('[missing section]')
                        section_string = ', '.join(section_list)
                        if error == False:
                            error = 'Missing value or section.'
                        print section_string, ' = ', error
                    sys.exit(1)
                expCfg.merge(curCfg)

        self.expCfg = expCfg

    def __setupSystem(self):

        # Set up the wiimote
        ################################################################
        ################################################################
        ##  Misc. Design specific items here.
        if (self.sysCfg['use_wiimote']):
            # Create wiimote holder
            self.wiimote = 0
            self._connectWiiMote()

        #Set up the HMD
        if self.sysCfg['use_hmd']:
            self.hmd = HMD(self.sysCfg['hmd'], True)
            self.use_HMD = True
        else:
            self.hmd = HMD(self.sysCfg['hmd'], False)
            self.use_HMD = False

        viz.window.setFullscreenMonitor(self.sysCfg['displays'])

        viz.setMultiSample(self.sysCfg['antiAliasPasses'])
        viz.MainWindow.clip(0.01, 200)
        viz.vsync(1)

        viz.setOption("viz.glfinish", 1)
        viz.setOption("viz.dwm_composition", 0)

        #Set up recording
        if self.sysCfg['use_DVR'] == 1:
            self.use_DVR = True
        else:
            self.use_DVR = False
        self.writer = None  #Will get initialized later when the system starts

        #Set up the eye tracking callibration/configuration (eyeTrackingCal)

        if self.sysCfg['use_eyetracking']:
            self.use_eyeTracking = True
            if self.sysCfg['hmd']['type'] == 'nvis':

                import EyeTrackerCalibrationNVIS_MT
                self.eyeTrackingCal = EyeTrackerCalibrationNVIS_MT.EyeTrackerCalibrationNVIS(
                    self.sysCfg['eyetracker']['settingsDir'])
                self.eyeTrackingCal.changeDisplayNum(
                    self.sysCfg['displays'][0])

                print "Eye tracking enabled using NVIS visor"
            else:
                print "Error in VRLabConfig: Eye-tracking not setup for this HMD."
                sys.exit(1)
        else:
            self.use_eyeTracking = False
            self.eyeTrackingCal = None

        self.mocap = None
        self.bodyCam = None

        if self.sysCfg['use_phasespace']:

            from mocapInterface import phasespaceInterface
            self.mocap = phasespaceInterface(self.sysCfg)

            self.use_phasespace = True
        else:
            self.use_phasespace = False

        if self.sysCfg['use_virtualPlane']:

            isAFloor = self.sysCfg['virtualPlane']['isAFloor']
            planeName = self.sysCfg['virtualPlane']['planeName']
            planeCornerFile = self.sysCfg['virtualPlane']['planeCornerFile']
            self.virtualPlane = virtualPlane.virtualPlane(
                self, planeName, isAFloor, planeCornerFile)

        if self.sysCfg['use_virtualPlane']:
            viz.go(viz.FULLSCREEN | viz.QUAD_BUFFER)
        elif self.sysCfg['use_fullscreen']:
            viz.go(viz.FULLSCREEN)
        else:
            viz.go()

        #self._setWinPriority(priority=5)

    def start(self):
        if self.use_DVR:
            print "Starting DVR"
            from DVRwriter import DVRwriter
            from datetime import datetime

            metadata = 'unused per-file meta data'  #Can be filled in with useful metadata if desired.

            if None == self.writer:  #need to lazy initialize this because it has to be called after viz.go()
                sz = viz.window.getSize()
                self.now = datetime.now()
                nameRoot = '%s%d.%d.%d.%d-%d' % (
                    self.sysCfg['writer']['outFileDir'], self.now.year,
                    self.now.month, self.now.day, self.now.hour,
                    self.now.minute)
                outFile = '%s.%s' % (nameRoot,
                                     self.sysCfg['writer']['outFileName'])
                self.expCfg.filename = '%s.expCfg.cfg' % (nameRoot)
                self.sysCfg.filename = '%s.sysCfg.cfg' % (nameRoot)

                if 'L' == self.sysCfg['eyetracker']['eye']:
                    viewport = (0, 0, sz[0] / 2, sz[1])
                else:
                    viewport = (sz[0] / 2, 0, sz[0] / 2, sz[1])
                #fi

                print "OutfileName:" + self.sysCfg['writer']['outFileName']
                print "Metadata:" + metadata
                print "Viewport:" + str(viewport)
                print "Eyetracking:" + str(self.use_eyeTracking)

                self.writer = DVRwriter(outFile, metadata, viewport,
                                        self.use_eyeTracking)
                self.expCfg.write()
                self.sysCfg.write()

            self.writer.turnOn()

    def __record_data__(self, e):

        if self.use_DVR and self.writer != None:
            #print "Writing..."
            self.writer.write(self.writables)

    def _connectWiiMote(self):

        wii = viz.add('wiimote.dle')  #Add wiimote extension

        # Replace old wiimote
        if (self.wiimote):
            print 'Wiimote removed.'
            self.wiimote.remove()

        self.wiimote = wii.addWiimote()  # Connect to first available wiimote

        vizact.onexit(
            self.wiimote.remove)  # Make sure it is disconnected on quit

        self.wiimote.led = wii.LED_1 | wii.LED_4  #Turn on leds to show connection

    def _setWinPriority(self, pid=None, priority=1):
        """ Set The Priority of a Windows Process.  Priority is a value between 0-5 where
			2 is normal priority.  Default sets the priority of the current
			python process but can take any valid process ID. """

        import win32api, win32process, win32con

        priorityclasses = [
            win32process.IDLE_PRIORITY_CLASS,
            win32process.BELOW_NORMAL_PRIORITY_CLASS,
            win32process.NORMAL_PRIORITY_CLASS,
            win32process.ABOVE_NORMAL_PRIORITY_CLASS,
            win32process.HIGH_PRIORITY_CLASS,
            win32process.REALTIME_PRIORITY_CLASS
        ]
        if pid == None:
            pid = win32api.GetCurrentProcessId()

        handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
        win32process.SetPriorityClass(handle, priorityclasses[priority])
class Config:
    '''This class represents the configuration for a particular experiment.

    It has two main components: vrlab.Config.sys and vrlab.Config.exp that
    contain the system configuration and the experiment configuration
    respectively.

    Attributes
    ----------
    sys : ConfigObj
        The system configuration
    exp : ConfigObj
        The experiment configuration

    writables : list
        A list of variables to be written to the .mov each frame.
    hmd : HMD
        Our HMD object.
    writer :
        The DVR writer. None if the writer is not being used or has not been
        initialized.
    eyetracker :
        The eyetracking interface. None if we aren't eyetracking.
    body_camera :
        A second virtual camera or tracker

    use_phasespace : bool
        True if phasespace is enabled.
    use_hmd: bool
        True if HMD is being used (otherwise configure just for screen).
    use_hiball: bool
        True if hiball is enabled.
    use_eyetracking : bool
        True if eyetracking is enabled.
    use_dvr : bool
        True if DVR should record the experiment.
    '''

    def __init__(self, filename=''):
        '''Opens and interprets configuration files for running experiments.

        This constructor opens both the system config (as defined by the
        <platform>.cfg file) and the experiment config (as defined by the given
        filename).

        Both configurations must conform the specs given in SYSTEM.ini and
        experiment.ini respectively. It also initializes the system as specified
        in the system config.
        '''
        self.exp = self.create_exp_config(filename)
        self.sys = self.create_sys_config()
        for path in self.sys['set_path']:
            viz.res.addPath(path)

        viz.window.setFullscreenMonitor(self.sys['displays'])
        viz.setMultiSample(self.sys['antiAliasPasses'])
        viz.MainWindow.clip(0.01, 200)

        self.writables = []
        self.writer = None
        self.mocap = None
        self.body_camera = None

        self._setup_hmd()
        self._setup_recorder()
        self._setup_eyetracking()
        self._setup_phasespace()
        self._setup_hiball()

        self.writables.append(self.mocap)
        self.writables.append(self.body_camera)

        if self.sys['use_fullscreen']:
            viz.go(viz.FULLSCREEN)
        else:
            viz.go()

    def create_sys_config(self):
        '''Set up the system config section.'''
        filename = '{}.cfg'.format(platform.node().upper())
        if not os.path.isfile(filename):
            filename = 'DEFAULT.cfg'
        print 'Loading system config file: {}'.format(filename)
        cfg = ConfigObj(filename, configspec='SYSTEM.ini', raise_errors=True)
        self.validate(cfg, 'System')
        print 'System config file parsed correctly'
        return cfg

    def create_exp_config(self, filename):
        '''Set up the experiment config section.'''
        if not filename:
            return None
        print 'Loading experiment config file: {}'.format(filename)
        cfg = ConfigObj(filename,
                        configspec='experiment.ini',
                        raise_errors=True,
                        file_error=True)
        self.validate(cfg, 'Experiment')
        print 'Experiment config file parsed correctly'
        for ld in cfg.get('_LOAD_', {}).get('loadList', ()):
            source = cfg['_LOAD_'][ld]
            print 'Loading: {} as {}'.format(ld, source['cfgFile'])
            c = ConfigObj(source['cfgFile'],
                          configspec=source['cfgSpec'],
                          raise_errors=True,
                          file_error=True)
            self.validate(c, 'Experiment[{}]'.format(ld))
            print 'Experiment config file parsed correctly'
            cfg.merge(c)
        return cfg

    def validate(self, cfg, which):
        if cfg.validate(Validator()):
            return
        errs = cfg.validate(Validator(), preserve_errors=True)
        for sections, key, err in configobj.flatten_errors(cfg, errs):
            sections.append(key or '[missing section]')
            print ', '.join(sections), ' = ', error or 'Missing value or section.'
        raise ValueError('{} config file validation failed!'.format(which))

    def _setup_hmd(self):
        if self.sys['use_hmd']:
            self.hmd = HMD(self.sys['hmd'], True)
            self.use_hmd = True
        else:
            self.hmd = HMD(self.sys['hmd'], False)
            self.use_hmd = False

    def _setup_recorder(self):
        if self.sys['use_DVR']:
            self.use_dvr = True
        else:
            self.use_dvr = False

    def _setup_eyetracking(self):
        if self.sys['use_eyetracking']:
            self.use_eyetracking = True
            if self.sys['hmd']['type'] != 'nvis':
                raise ValueError('Error in vrlab.Config: Eye-tracking not setup for this HMD.')
            import eyetracker
            self.eyetracker = eyetracker.NvisCalibration(self.sys['eyetracker']['settingsDir'])
            #self.eyetracker.distance = 10
            #self.eyetracker.fractionX = 4
            #self.eyetracker.fractionY = 4
            #self.eyetracker.stimScale = 5
            print 'Eye tracking enabled using NVIS HMD.'
        else:
            self.use_eyetracking = False
            self.eyetracker = None

    def _setup_phasespace(self):
        if self.sys['use_phasespace']:
            self.mocap = phasespace.Mocap(self.sys['phasespace']['server'])
            self.mocap.start_thread()
            self.use_phasespace = True
        else:
            self.use_phasespace = False

    def _setup_hiball(self):
        if self.sys['use_hiball']:
            cfg = self.sys['hiball']
            self.mocap = hiball.Camera(
                cfg['origin'],
                particle=None,
                sensorNum=cfg['headCam'],
                attachTo=viz.MainView,
                preTrans=cfg['preTransHead'])
            self.body_camera = None
            if cfg['bodyCam'] != -1:
                self.body_camera = hiball.Camera(
                    cfg['origin'],
                    particle=None,
                    sensorNum=cfg['bodyCam'],
                    attachTo=None,
                    preTrans=cfg['preTransBody'])
            self.use_hiball = True
        else:
            self.use_hiball = False

    def start(self):
        if not self.use_dvr:
            return

        print 'Starting DVR'
        from DVRwriter import DVRwriter

        # Can be filled in with useful metadata if desired.
        metadata = 'unused per-file meta data'

        # need to lazy initialize this because it has to be called after viz.go()
        if self.writer is None:
            root = os.path.join(self.sys['writer']['outFileDir'],
                                datetime.datetime.now().strftime('%Y.%m.%d.%H-%M'))

            self.exp.filename = '{}.exp.cfg'.format(root)
            self.sys.filename = '{}.sys.cfg'.format(root)

            width, height = viz.window.getSize()
            viewport = [width / 2, 0, width / 2, height]
            if 'L' == self.sys['eyetracker']['eye']:
                viewport[0] = 0

            print 'OutfileName:' + self.sys['writer']['outFileName']
            print 'Metadata:' + metadata
            print 'Viewport:' + str(viewport)
            print 'Eyetracking:' + str(self.use_eyetracking)

            self.writer = DVRwriter(
                '{}.{}' % (root, self.sys['writer']['outFileName']),
                metadata, viewport, self.use_eyetracking)

            self.exp.write()
            self.sys.write()

        self.writer.turnOn()

    def __record_data__(self, e):
        if self.use_dvr and self.writer != None:
            self.writer.write(self.writables)
Example #6
0
class VRLabConfig:
	"""
	This class represents the configuration for a particular experiment. It has two main components: VRLabConfig.sysCfg
	and VRLabConfig.expCfg that contain the system configuration and the experiment configuration respectively.
	
	VRLabCong.start(): Final initialization after viz.go()
	
	VRLabConfig.sysCfg: The system configuration (a ConfigObj)
	VRLabConfig.expCfg: The experiment configuration (a ConfigObj)
	
	VRLabConfig.writables: A list of variables to be written to the .mov each frame
	VRLabConfig.HMD: The HMD (defined in this file). Is still an HMD even if not using HMD, just disabled.
	VRLabConfig.writer: The DVR writer. None if the writer is not being used or has not been initialized.
	VRLabConfig.eyeTrackingCal: The eyetracking interface. None if we aren't eyetracking
	VRLabConfig.camera: The virtual camera, positioned by headtracking. None if no such camera.
	VRLabConfig.bodyCam: A second virtual camera or tracker
	VRLabConfig.phase_space_markers: Markers for phasespace. Undefined if use_phasespace is false.
	VRLabConfig.phasespace_server: Server for phasespace. Undefined if use_phasespace is false.
	
	VRLabConfig.use_phasespace: True if phasespace is enabled
	VRLabConfig.use_HMD: True if HMD is being used (otherwise configure just for screen)
	VRLabConfig.use_hiball: True if hiball is enabled.
	VRLabConfig.use_eyetracking: True if eyetracking is enabled
	VRLabConfig.use_DVR: True if DVR should record the experiment
	"""
	
	def __init__(self, expCfgName = ""):
		"""
		Opens and interprets both the system config (as defined by the <platform>.cfg file) and the experiment config
		(as defined by the file in expCfgName). Both configurations MUST conform the specs given in sysCfgSpec.ini and
		expCfgSpec.ini respectively. It also initializes the system as specified in the sysCfg.
		"""
		
		self.writables = list()
		if expCfgName:
			self.__createExpCfg(expCfgName)
		else:
			self.expCfg = None
		self.__createSysCfg()
		
		for pathName in self.sysCfg['set_path']:
			viz.res.addPath(pathName)
		
		self.__setupSystem()
		
	def __createSysCfg(self):
		"""
		Set up the system config section (sysCfg)
		"""
		sysCfgName = platform.node()+".cfg"
		if not(os.path.isfile(sysCfgName)):
			sysCfgName = "defaultSys.cfg"
		print "Loading system config file: " + sysCfgName
		sysCfg = ConfigObj(sysCfgName, configspec='sysCfgSpec.ini', raise_errors = True)
		validator = Validator()
		sysCfgOK = sysCfg.validate(validator)
		if sysCfgOK == True:
			print "System config file parsed correctly"
		else:
			print 'System config file validation failed!'
			res = sysCfg.validate(validator, preserve_errors=True)
			for entry in flatten_errors(sysCfg, res):
			# each entry is a tuple
				section_list, key, error = entry
				if key is not None:
					section_list.append(key)
				else:
					section_list.append('[missing section]')
				section_string = ', '.join(section_list)
				if error == False:
					error = 'Missing value or section.'
				print section_string, ' = ', error
			sys.exit(1)
		self.sysCfg = sysCfg
		#self.writables.append(self.sysCfg)
		
	def __createExpCfg(self, expCfgName):
		"""
		Set up the experiment config section (expCfg)
		"""
		print "Loading experiment config file: " + expCfgName
		
		# This is where the parser is called.
		expCfg = ConfigObj(expCfgName, configspec='expCfgSpec.ini', raise_errors = True, file_error = True)

		validator = Validator()
		expCfgOK = expCfg.validate(validator)
		if expCfgOK == True:
			print "Experiment config file parsed correctly"
		else:
			print 'Experiment config file validation failed!'
			res = expCfg.validate(validator, preserve_errors=True)
			for entry in flatten_errors(expCfg, res):
			# each entry is a tuple
				section_list, key, error = entry
				if key is not None:
					section_list.append(key)
				else:
					section_list.append('[missing section]')
				section_string = ', '.join(section_list)
				if error == False:
					error = 'Missing value or section.'
				print section_string, ' = ', error
			sys.exit(1)
		if expCfg.has_key('_LOAD_'):
			for ld in expCfg['_LOAD_']['loadList']:
				print 'Loading: ' + ld + ' as ' + expCfg['_LOAD_'][ld]['cfgFile']
				curCfg = ConfigObj(expCfg['_LOAD_'][ld]['cfgFile'], configspec = expCfg['_LOAD_'][ld]['cfgSpec'], raise_errors = True, file_error = True)
				validator = Validator()
				expCfgOK = curCfg.validate(validator)
				if expCfgOK == True:
					print "Experiment config file parsed correctly"
				else:
					print 'Experiment config file validation failed!'
					res = curCfg.validate(validator, preserve_errors=True)
					for entry in flatten_errors(curCfg, res):
					# each entry is a tuple
						section_list, key, error = entry
						if key is not None:
							section_list.append(key)
						else:
							section_list.append('[missing section]')
						section_string = ', '.join(section_list)
						if error == False:
							error = 'Missing value or section.'
						print section_string, ' = ', error
					sys.exit(1)
				expCfg.merge(curCfg)
		
		self.expCfg = expCfg
		
		
		
	def __setupSystem(self):
		
		# Set up the wiimote
		################################################################
		################################################################
		##  Misc. Design specific items here.
		if( self.sysCfg['use_wiimote']):
			# Create wiimote holder
			self.wiimote = 0
			self._connectWiiMote()
		
		#Set up the HMD
		if self.sysCfg['use_hmd']:
			self.hmd = HMD(self.sysCfg['hmd'], True)
			self.use_HMD = True
		else:
			self.hmd = HMD(self.sysCfg['hmd'], False)
			self.use_HMD = False
		
		
		viz.window.setFullscreenMonitor(self.sysCfg['displays'])
		
		viz.setMultiSample(self.sysCfg['antiAliasPasses'])
		viz.MainWindow.clip(0.01 ,200)
		viz.vsync(1)
		
		viz.setOption("viz.glfinish", 1)
		viz.setOption("viz.dwm_composition", 0)
		
		#Set up recording
		if self.sysCfg['use_DVR'] == 1:
			self.use_DVR = True
		else:
			self.use_DVR = False
		self.writer = None #Will get initialized later when the system starts
		
		#Set up the eye tracking callibration/configuration (eyeTrackingCal)
		
		if self.sysCfg['use_eyetracking']:
			self.use_eyeTracking = True
			if self.sysCfg['hmd']['type'] == 'nvis':
			
				import EyeTrackerCalibrationNVIS_MT
				self.eyeTrackingCal = EyeTrackerCalibrationNVIS_MT.EyeTrackerCalibrationNVIS(self.sysCfg['eyetracker']['settingsDir'])
				self.eyeTrackingCal.changeDisplayNum(self.sysCfg['displays'][0])
				
				
				print "Eye tracking enabled using NVIS visor"
			else:
				print "Error in VRLabConfig: Eye-tracking not setup for this HMD."
				sys.exit(1)
		else:
			self.use_eyeTracking = False
			self.eyeTrackingCal = None
			
		#self.writables.append(self.eyeTrackingCal)
			
		self.mocap = None
		self.bodyCam = None
		
		if self.sysCfg['use_phasespace']:
			
			from mocapInterface import phasespaceInterface			
			self.mocap = phasespaceInterface(self.sysCfg);
				
			self.use_phasespace = True
		else:
			self.use_phasespace = False
		
		if self.sysCfg['use_hiball']:
			from HiBallCameraMT import HiBallCamera
			#self.mocap = HiBallCamera(self.sysCfg['hiball']['origin'], self.sysCfg['hiball']['scale'], None, None, self.sysCfg, None);
			self.mocap = HiBallCamera(self.sysCfg['hiball']['origin'], particle=None, sensorNum=self.sysCfg['hiball']['headCam'], attachTo=viz.MainView, preTrans = self.sysCfg['hiball']['preTransHead'])
			if self.sysCfg['hiball']['bodyCam'] != -1:
				self.bodyCam = HiBallCamera(self.sysCfg['hiball']['origin'], particle=None, sensorNum=self.sysCfg['hiball']['bodyCam'], attachTo=None, preTrans = self.sysCfg['hiball']['preTransBody'])
			else:
				self.bodyCam = None
			self.use_hiball = True
		else:
			self.use_hiball = False
		

		self.writables.append(self.mocap)
		self.writables.append(self.bodyCam)
		
		if self.sysCfg['use_fullscreen']:
			viz.go(viz.FULLSCREEN)
		else:
			viz.go()
		
		self._setWinPriority(priority=5)
		
			
	def start(self):
		if self.use_DVR:
			print "Starting DVR"
			from DVRwriter				import DVRwriter
			from datetime 				import datetime
			
			metadata = 'unused per-file meta data' #Can be filled in with useful metadata if desired.
			
			if None == self.writer: #need to lazy initialize this because it has to be called after viz.go()
				sz = viz.window.getSize()
				self.now = datetime.now()
				nameRoot = '%s%d.%d.%d.%d-%d' % (self.sysCfg['writer']['outFileDir'], self.now.year, self.now.month, self.now.day, self.now.hour, self.now.minute)
				outFile = '%s.%s' % (nameRoot, self.sysCfg['writer']['outFileName'])
				self.expCfg.filename = '%s.expCfg.cfg' % (nameRoot)
				self.sysCfg.filename = '%s.sysCfg.cfg' % (nameRoot)
				
				
				if 'L' == self.sysCfg['eyetracker']['eye']: 
					viewport = (0,      0,sz[0]/2,sz[1])
				else:               
					viewport = (sz[0]/2,0,sz[0]/2,sz[1])
				#fi
				
				print "OutfileName:" + self.sysCfg['writer']['outFileName']
				print "Metadata:" + metadata
				print "Viewport:" + str(viewport)
				print "Eyetracking:" + str(self.use_eyeTracking)
				
				self.writer = DVRwriter(outFile, metadata, viewport, self.use_eyeTracking)
				self.expCfg.write()
				self.sysCfg.write()
				
			self.writer.turnOn()
		
			
	def __record_data__(self, e):
		
		if self.use_DVR and self.writer != None:
			#print "Writing..."
			self.writer.write(self.writables)
	
	def _connectWiiMote(self):
		
		wii = viz.add('wiimote.dle')#Add wiimote extension
		
		# Replace old wiimote
		if( self.wiimote ):
			print 'Wiimote removed.'
			self.wiimote.remove()
			
		self.wiimote = wii.addWiimote()# Connect to first available wiimote
		
		vizact.onexit(self.wiimote.remove) # Make sure it is disconnected on quit
		
		self.wiimote.led = wii.LED_1 | wii.LED_4 #Turn on leds to show connection
	
	def _setWinPriority(self,pid=None,priority=1):
		
		""" Set The Priority of a Windows Process.  Priority is a value between 0-5 where
			2 is normal priority.  Default sets the priority of the current
			python process but can take any valid process ID. """
			
		import win32api,win32process,win32con
		
		priorityclasses = [win32process.IDLE_PRIORITY_CLASS,
						   win32process.BELOW_NORMAL_PRIORITY_CLASS,
						   win32process.NORMAL_PRIORITY_CLASS,
						   win32process.ABOVE_NORMAL_PRIORITY_CLASS,
						   win32process.HIGH_PRIORITY_CLASS,
						   win32process.REALTIME_PRIORITY_CLASS]
		if pid == None:
			pid = win32api.GetCurrentProcessId()
		
		handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
		win32process.SetPriorityClass(handle, priorityclasses[priority])