Esempio n. 1
0
	def __init__(self):
		super(DOE2py_Utility,self).__init__('DOE2py Utility')

		self._Input 	= ControlFile('Input file')
		self._Weather 	= ControlFile('Weather file')
		self._Library 	= ControlFile('User Library')
		self._Version	= ControlCombo('DOE-2 Version')
		#self._Status_1	= ControlLabel('Simulation Status:')
		#self._Status_2	= ControlLabel('-')
		self._Run		= ControlButton('Run Simulation')
		self._Close		= ControlButton('Close')

		self._formset = ['',('  ','_Input','  '),
		                    ('', '_Weather', '' ),
							('', '_Library', '' ),
							('','_Version', '' ),
							('', '_Run', '' ),
							('','_Close',''),''] #('','_Status_1','','_Status_2', '' )
	
		self._Run.value = self.__RunAction
		self._Close.value = self.__CloseAction	
		
		with open('settings-gui.json') as data_file:    
			data = json.load(data_file)
			self._Input.value = data["lastinput"]
			self._Weather.value = data["lastweather"]
			self._Library.value = data["lastlibrary"]
		for i in range(0,len(data["doe2versions"])):
			self._Version.add_item(data["doe2versions"][i])
Esempio n. 2
0
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg')
        TypeColorVideoPipe.__init__(self)
        OTModulePlugin.__init__(self, name, iconFile=icon_path)

        self._video = ModuleConnection("Video", connecting=TypeColorVideo)
        self._player = ControlPlayer("Video player")
        self._colorDomain = ControlCombo("Color domain")

        self._colorDomain.add_item("XYZ", cv2.COLOR_BGR2XYZ)
        self._colorDomain.add_item("YCrCb", cv2.COLOR_BGR2YCR_CB)
        self._colorDomain.add_item("HSV", cv2.COLOR_BGR2HSV)
        self._colorDomain.add_item("HLS", cv2.COLOR_BGR2HLS)
        self._colorDomain.add_item("Lab", cv2.COLOR_BGR2LAB)
        self._colorDomain.add_item("Luv", cv2.COLOR_BGR2LUV)

        self._colorDomain.changed_event = self._player.refresh
        self._video.changed_event = self.newVideoInputChoosen
        self._player.process_frame_event = self.processFrame

        self._formset = [
            '_video',
            '_colorDomain',
            "_player",
        ]
class LightSourceTab(BaseWidget):
    """
    Tab to select the lightsource device
    """

    _lightsource = None
    _update_function = None

    def __init__(self, update_function=None):
        super().__init__("Light Source Tab")

        self._update_function = update_function

        self._device_select = ControlCombo(label="Light Source")

        self._custom = ControlEmptyWidget()

        self._device_select.changed_event = self._on_device_change

        self._device_select.add_item('None', None)

        for class_type in LightSource.__subclasses__():
            self._device_select.add_item(class_type.__name__, class_type)

    def _on_device_change(self):
        device = self._device_select.value
        if callable(device):
            self._lightsource = device()
            self._custom.value = self._lightsource.get_custom_config()
        else:
            self._lightsource = None
            self._custom.value = None

        if callable(self._update_function):
            self._update_function({'lightsource': self._lightsource})
Esempio n. 4
0
    def __init__(self):
        super(SimpleExample1, self).__init__('my_variant_api')

        #init clinvar
        self._clinvariants = ControlTextArea('rsvariants', 'rs12315123')
        self._clinbutton = ControlButton('Press this button')
        self._clinresult = ControlTextArea('result')

        self._clinbutton.value = self.__clinbuttonAction
        #init flanking site
        self._flancchrom = ControlText('chrom')
        self._flancpos = ControlText('pos')
        self._flancthree = ControlText('expand_3prime', 300)
        self._flancfive = ControlText('expand_5prime', 300)
        self._flancassembly = ControlCombo('assembly')
        self._flancassembly.add_item('GRCh37')
        self._flancassembly.add_item('GRCh38')
        self._flancbutton = ControlButton('Press this button')
        self._flancresult = ControlTextArea('result')
        self._flancbutton.value = self.__flancbuttonAction

        self.formset = [{
            "Clinvar": ('_clinvariants', '_clinbutton', '_clinresult'),
            "Flanking Site": [('_flancchrom', '_flancpos', '_flancthree',
                               '_flancfive', '_flancassembly'), '_flancbutton',
                              '_flancresult']
        }]
Esempio n. 5
0
    def __init__(self, axis):
        super().__init__("Aux Jog")

        assert isinstance(axis, ControlAxis)

        self._axis = axis

        self.label = axis.get_name()

        self._value_field = ControlText(label="Target",
                                        default=str(axis.get_value()))

        self._set_button = ControlButton(label="Go to target")
        self._set_button.value = self._update_value

        self._saved_point_field = ControlCombo(label="Saved Point")

        self._saved_point_button = ControlButton(label="Go to saved point")
        self._saved_point_button.value = self._update_saved_point

        self._current_field = ControlLabel(
            label="Current Value ({})".format(axis.get_units()))

        self.setFrameShape(QFrame.StyledPanel)
        self.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed))

        self.set_margin(10)

        self.formset = [("info:{0} ({1}):".format(axis.get_name(),
                                                  axis.get_units()), '', '',
                         '_current_field'), ('_value_field', '_set_button'),
                        ('_saved_point_field', '_saved_point_button')]
class NewAxisWindow(BaseWidget):
    """
    Create a new Axis
    """
    def __init__(self, done_function):
        super().__init__("New Axis")

        self._done_function = done_function

        self._axis_name = ControlText(label="Name")

        self._axis_hw_type = ControlCombo(label="HW Type", default=None)

        for class_type in ControlAxis.__subclasses__():
            self._axis_hw_type.add_item(class_type.__name__, class_type)

        self._done_button = ControlButton(label="Done")

        self._done_button.value = self._done

    def _done(self):
        hw_type = self._axis_hw_type.value
        if issubclass(hw_type, ControlAxis):
            name = self._axis_name.value
            axis = hw_type(name)
            self._done_function(axis)
            self.close()
Esempio n. 7
0
	def __init__(self, timeline=None):
		super(ImportWindow, self).__init__('Import file', parent_win=timeline)
		self.setContentsMargins(10, 10, 10, 10)
		self._timeline = timeline

		# Definition of the forms fields
		self._filetype = ControlCombo('Please select the type of file you would like to import:')
		self._importButton = ControlButton('Import')
		self._panel = ControlEmptyWidget('Panel')
		self._file = ControlFile('File to import')

		self._panel.value = self._file
		self._filetype.add_item('Events file', 0)
		self._filetype.add_item('Graph file', 1)
		self._filetype.add_item('Bonsai events file', 2)

		self._formset = [
			('_filetype', ' '),
			'_panel',
			(' ', '_importButton'), ' ']

		self._filetype.changed_event = self.__fileTypeChanged
		self._importButton.value = self.__importData

		from pyforms.gui.dialogs.csv_parser import CsvParserDialog
		self._graphCsvParserDlg = CsvParserDialog()
		self._graphCsvParserDlg.xField.label = "Value column"
		self._graphCsvParserDlg.yField.hide()
		self._graphCsvParserDlg.zField.hide()
		self._graphCsvParserDlg.loadButton.hide()

		self._bonsaiImportDlg = BonsaiImportFileDlg()
Esempio n. 8
0
    def __init__(self):
        super(AdminStatsApp, self).__init__('Admin stats')

        self._totalExec_begin = ControlDate('Starting date', '2014-10-10')
        self._totalExec_end = ControlDate('Ending date', '2015-10-10')
        self._totalExec_btn = ControlButton('Refresh')

        self._totalExec_graph = ControlVisVis('Total execution time')

        self._apps_list = ControlCombo('Filter by application')
        self._totalExecApp_graph = ControlVisVis(
            'Total execution time per application')

        self._servers_list = ControlCombo('Filter by server')
        self._totalExecServer_graph = ControlVisVis(
            'Total execution time per server')

        self._formset = [
            ('_totalExec_begin', '_totalExec_end',
             '_totalExec_btn'), 'h3:Total execution time', '_totalExec_graph',
            'h3:Total execution time per application', '_apps_list',
            '_totalExecApp_graph', 'h3:Total execution time per server',
            '_servers_list', '_totalExecServer_graph'
        ]

        self._totalExec_btn.value = self.__total_exec_stats

        self._apps_list.addItem('--- All ---', '')
        for application in Algorithm.objects.all():
            self._apps_list.addItem(str(application.algorithm_name),
                                    str(application.algorithm_class))

        self._servers_list.addItem('--- All ---', '')
        for server in Server.objects.all().order_by('server_name'):
            self._servers_list.addItem(str(server.server_name), str(server.pk))
Esempio n. 9
0
class DOE2py_Utility(BaseWidget):
	
	def __init__(self):
		super(DOE2py_Utility,self).__init__('DOE2py Utility')

		self._Input 	= ControlFile('Input file')
		self._Weather 	= ControlFile('Weather file')
		self._Library 	= ControlFile('User Library')
		self._Version	= ControlCombo('DOE-2 Version')
		#self._Status_1	= ControlLabel('Simulation Status:')
		#self._Status_2	= ControlLabel('-')
		self._Run		= ControlButton('Run Simulation')
		self._Close		= ControlButton('Close')

		self._formset = ['',('  ','_Input','  '),
		                    ('', '_Weather', '' ),
							('', '_Library', '' ),
							('','_Version', '' ),
							('', '_Run', '' ),
							('','_Close',''),''] #('','_Status_1','','_Status_2', '' )
	
		self._Run.value = self.__RunAction
		self._Close.value = self.__CloseAction	
		
		with open('settings-gui.json') as data_file:    
			data = json.load(data_file)
			self._Input.value = data["lastinput"]
			self._Weather.value = data["lastweather"]
			self._Library.value = data["lastlibrary"]
		for i in range(0,len(data["doe2versions"])):
			self._Version.add_item(data["doe2versions"][i])
		
		
	def __RunAction(self):
		path = os.path.dirname(os.path.realpath(__file__))
		if self._Library.value <> "":
			ImportLib(self._Version.value, self._Library.value, path)
		RunDOE2(self._Input.value[:-4], self._Weather.value, self._Version.value, path)
		#self._Status_2.value = "Completed!"
	
	def __CloseAction(self):
		with open('settings-gui.json') as data_file:    
			data = json.load(data_file)
			data["lastinput"] = self._Input.value
			data["lastweather"] = self._Weather.value
			data["lastlibrary"] = self._Library.value
		with open('settings-gui.json','w') as data_file:			
			json.dump(data,data_file)
		sys.exit()	
    def __init__(self, done_function):
        super().__init__("New Axis")

        self._done_function = done_function

        self._axis_name = ControlText(label="Name")

        self._axis_hw_type = ControlCombo(label="HW Type", default=None)

        for class_type in ControlAxis.__subclasses__():
            self._axis_hw_type.add_item(class_type.__name__, class_type)

        self._done_button = ControlButton(label="Done")

        self._done_button.value = self._done
    def __init__(self, update_function=None):
        super().__init__("Light Source Tab")

        self._update_function = update_function

        self._device_select = ControlCombo(label="Light Source")

        self._custom = ControlEmptyWidget()

        self._device_select.changed_event = self._on_device_change

        self._device_select.add_item('None', None)

        for class_type in LightSource.__subclasses__():
            self._device_select.add_item(class_type.__name__, class_type)
Esempio n. 12
0
class SimpleExample1(BaseWidget):
    def __init__(self):
        super(SimpleExample1, self).__init__('my_variant_api')

        #init clinvar
        self._clinvariants = ControlTextArea('rsvariants', 'rs12315123')
        self._clinbutton = ControlButton('Press this button')
        self._clinresult = ControlTextArea('result')

        self._clinbutton.value = self.__clinbuttonAction
        #init flanking site
        self._flancchrom = ControlText('chrom')
        self._flancpos = ControlText('pos')
        self._flancthree = ControlText('expand_3prime', 300)
        self._flancfive = ControlText('expand_5prime', 300)
        self._flancassembly = ControlCombo('assembly')
        self._flancassembly.add_item('GRCh37')
        self._flancassembly.add_item('GRCh38')
        self._flancbutton = ControlButton('Press this button')
        self._flancresult = ControlTextArea('result')
        self._flancbutton.value = self.__flancbuttonAction

        self.formset = [{
            "Clinvar": ('_clinvariants', '_clinbutton', '_clinresult'),
            "Flanking Site": [('_flancchrom', '_flancpos', '_flancthree',
                               '_flancfive', '_flancassembly'), '_flancbutton',
                              '_flancresult']
        }]

    def __clinbuttonAction(self):
        results = []
        for rsid in self._clinvariants.value.split('\n'):
            clinsig = getClinicalSignificance(rsid)
            results.append(clinsig)
        self._clinresult.value = '\n'.join(results)

    def __flancbuttonAction(self):
        chrom = self._flancchrom.value
        pos = self._flancpos.value
        five = self._flancfive.value
        three = self._flancthree.value
        assembly = self._flancassembly.value
        uri = 'http://grch37.rest.ensembl.org/sequence/region/human/' + chrom + ':' + pos + '..' + pos + ':1?expand_3prime=' + three + '&expand_5prime=' + five + '&content-type=text/plain'
        site = getEnsemblResult(uri)
        fiveString = site[:int(five)]
        threeString = site[-int(three):]
        current = site[int(five):int(five) + 1]
        self._flancresult.value = fiveString + '\n' + current + '\n' + threeString
Esempio n. 13
0
    def __init__(self, timeline=None):
        super(ImportWindow, self).__init__("Import file")
        self.setContentsMargins(10, 10, 10, 10)
        self._timeline = timeline

        # Definition of the forms fields
        self._filetype = ControlCombo("Please select the type of file you would like to import:")
        self._importButton = ControlButton("Import")
        self._panel = ControlEmptyWidget("Panel")
        self._file = ControlFile("File to import")

        self._panel.value = self._file
        self._filetype.addItem("Events file", 0)
        self._filetype.addItem("Graph file", 1)
        self._filetype.addItem("Bonsai events file", 2)

        self._formset = [("_filetype", " "), "_panel", (" ", "_importButton"), " "]

        self._filetype.changed = self.__fileTypeChanged
        self._importButton.value = self.__importData

        from pyforms.dialogs import CsvParserDialog

        self._graphCsvParserDlg = CsvParserDialog()
        self._graphCsvParserDlg.xField.label = "Value column"
        self._graphCsvParserDlg.yField.hide()
        self._graphCsvParserDlg.zField.hide()
        self._graphCsvParserDlg.loadButton.hide()

        self._bonsaiImportDlg = BonsaiImportFileDlg()
    def get_custom_config(self):
        """
        Gets a pyforms BaseWidget to complete configuration for LinearAxis
        """

        if self._widget is None:
            widget = BaseWidget("Linear Axis Config")

            widget.device_list = ControlCombo(label="Device")

            widget.device_list += ('None', None)

            for device in DEVICES:
                widget.device_list += device

            if self._linear_stage is not None:
                widget.value = self._linear_stage.serial_number

                print("Stage:", self._linear_stage.serial_number)
                print("Widget:", widget.value)

            widget.device_list.current_index_changed_event = self._update_stage

            widget.formset = ['device_list', '']

            self._widget = widget

            self._update_stage(0)

        if self._linear_stage is not None:
            self._linear_stage.identify()

        return self._widget
Esempio n. 15
0
    def __init__(self, timeline=None):
        super(ImportWindow, self).__init__('Import file')
        self.setContentsMargins(10, 10, 10, 10)
        self._timeline = timeline

        # Definition of the forms fields
        self._filetype = ControlCombo('Please select the type of file you would like to import:')
        self._importButton = ControlButton('Import')
        self._panel = ControlEmptyWidget('Panel')
        self._file = ControlFile('File to import')

        self._panel.value = self._file
        self._filetype.addItem('Events file', 0)
        self._filetype.addItem('Graph file', 1)
        self._filetype.addItem('Bonsai events file', 2)

        self._formset = [
            ('_filetype', ' '),
            '_panel',
            (' ', '_importButton'), ' ']

        self._filetype.changed = self.__fileTypeChanged
        self._importButton.value = self.__importData

        self._graphCsvParserDlg = CsvParserDialog()
        self._graphCsvParserDlg.xField.label = "Value column"
        self._graphCsvParserDlg.yField.hide()
        self._graphCsvParserDlg.zField.hide()
        self._graphCsvParserDlg.loadButton.hide()

        self._bonsaiImportDlg = BonsaiImportFileDlg()
Esempio n. 16
0
    def __init__(self, columns, parent=None):
        super(GenericCsvParserDialog, self).__init__('CSV Choose the columns',
                                                     parent_win=parent)

        self._filename = None
        self._columns = columns
        self._columns_indexes = []
        self._rownum = 0

        # Definition of the forms fields
        self._filename = ControlFile('CSV File')
        self._separator = ControlCombo('Separator', default='auto')
        self._startingrow = ControlNumber('Starting row', default=0)

        for index, column in enumerate(columns):
            setattr(
                self, '_col_{0}'.format(index),
                ControlNumber(column, default=index, minimum=-1, maximum=1000))

        self._filePreview = ControlList('Preview')
        self._loadButton = ControlButton('Load')

        form_row = ['_separator'] + [
            '_col_{0}'.format(index) for index, column in enumerate(columns)
        ] + ['_loadButton']

        self._formset = [('_filename', '_startingrow'),
                         tuple(form_row), '_filePreview']
        self._separator.changed_event = self.__refreshPreview
        self._filename.changed_event = self.__refreshPreview
        self._startingrow.changed_event = self.__refreshPreview
        self._loadButton.value = self.load

        self._load_event = None

        self._separator.add_item('auto', 'auto')
        self._separator.add_item(';', ';')
        self._separator.add_item(',', ',')
        self._separator.add_item('TAB', '\t')
        self._separator.add_item('Excel', csv.excel)
        self._separator.add_item('Excel TAB', csv.excel_tab)
Esempio n. 17
0
def laser_custom_config():
    """
    Get the GUI config to configure the laser
    The GUI is the same for each laser axis and for the laser lightsource
    """
    global WIDGET

    if WIDGET is None:
        widget = BaseWidget("Laser Config")

        widget.power_supply = ControlCombo(label="Power Supply")

        widget.power_supply += ('None', None)

        for power in DEVICES['Power Supply']:
            widget.power_supply += power

        widget.power_supply.current_index_changed_event = update_laser

        widget.power_channel = ControlNumber(label="Power Supply Channel",
                                             default=1,
                                             minimum=1,
                                             maximum=4)

        widget.signal_generator = ControlCombo(label="Signal Generator")

        widget.signal_generator += ('None', None)

        for signal in DEVICES['Signal Generator']:
            widget.signal_generator += signal

        widget.signal_generator.current_index_changed_event = update_laser

        widget.formset = [
            "h5:Laser Using", 'power_supply', 'power_channel',
            'signal_generator', "(All laser axis use the same laser)"
        ]

        WIDGET = widget

    return WIDGET
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg')
        TypeBWVideoPipe.__init__(self)
        OTModulePlugin.__init__(self, name, iconFile=icon_path)

        self._video = ModuleConnection("Video",
                                       connecting=TypeComponentsVideoPipe)
        self._player = ControlPlayer("Video player")
        self._colorComponent = ControlCombo("Component")

        self._colorComponent.add_item("A", 0)
        self._colorComponent.add_item("B", 1)
        self._colorComponent.add_item("C", 2)
        self._colorComponent.changed_event = self.refreshValue
        self._video.changed_event = self.newVideoInputChoosen

        self._formset = [
            '_video',
            '_colorComponent',
            "_player",
        ]
    def __init__(self, update_function=None):
        super().__init__("Output Tab")

        # The update function will be called when the selected sensor changes
        # to fire the 'sensor' event
        self._update_function = update_function

        self._device_select = ControlCombo(label="Sensor")

        self._custom = ControlEmptyWidget()

        self._device_select.changed_event = self._on_device_change

        self._device_select.add_item('None', None)

        self._output = ControlList()

        self._live = ControlCheckBox(label="Live Output")
        self._live.changed_event = self._on_live

        for class_type in Sensor.__subclasses__():
            self._device_select.add_item(class_type.__name__, class_type)
class OTModuleSelectComponent(OTModulePlugin, TypeBWVideoPipe):
    def __init__(self, name):
        icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg')
        TypeBWVideoPipe.__init__(self)
        OTModulePlugin.__init__(self, name, iconFile=icon_path)

        self._video = ModuleConnection("Video",
                                       connecting=TypeComponentsVideoPipe)
        self._player = ControlPlayer("Video player")
        self._colorComponent = ControlCombo("Component")

        self._colorComponent.add_item("A", 0)
        self._colorComponent.add_item("B", 1)
        self._colorComponent.add_item("C", 2)
        self._colorComponent.changed_event = self.refreshValue
        self._video.changed_event = self.newVideoInputChoosen

        self._formset = [
            '_video',
            '_colorComponent',
            "_player",
        ]

    def refreshValue(self, value):
        self._player.refresh()

    def newVideoInputChoosen(self):
        ModuleConnection.changed_event(self._video)
        value = self._video.value
        if value:
            self.open(value)
            self._player.value = self
            print value

    def read(self):
        res, imgs = self._video.value.read()
        return res, imgs[self._colorComponent.value]
Esempio n. 21
0
 def __init__(self, isCreating):
     Movie.__init__(self, '', '', '', '')
     BaseWidget.__init__(self, 'Movie')
     self.__isCreating = isCreating
     self._idField = ControlText("Id")
     self._titleField = ControlText("Title")
     self._descriptionField = ControlTextArea("Description")
     self._genre = ControlCombo("Genre")
     for i in MOVIE_GENRE:
         self._genre += i
     self._buttonField = ControlButton('Add a new movie')
     self._buttonField.value = self._updateAction
     if not isCreating:
         self._idField.enabled = False
         self._buttonField.name = "Update movie"
     self._label = ControlLabel("")
    def get_custom_config(self):
        """
        Gets a pyforms BaseWidget to complete configuration for RotationAxis
        """

        if self._widget is None:
            widget = BaseWidget("Rotate Axis Config")

            widget.device_list = ControlCombo(label="Device")

            widget.device_list += ('None', None)

            for device in DEVICES:
                widget.device_list += device

            if self._rotation_stage is not None:
                widget.value = self._rotation_stage.serial_number

            widget.device_list.current_index_changed_event = self._update_stage

            widget.distance_field = ControlNumber(
                label="Distance to Surface",
                default=self._distance_to_surface,
                minimum=0,
                maximum=float('inf'),
                decimals=5)

            widget.distance_field.key_pressed_event = self._update_distance_to_surface

            widget.formset = ['device_list', 'distance_field', '']

            self._widget = widget

            self._update_stage(0)

        if self._rotation_stage is not None:
            self._rotation_stage.identify()

        return self._widget
Esempio n. 23
0
class MultipleBlobDetection(BaseWidget):
    def __init__(self):
        super(MultipleBlobDetection, self).__init__(
            'Multiple Blob Detection')

        # Definition of the forms fields
        self._videofile = ControlFile('Video')
        self._outputfile = ControlText('Results output file')

        self._threshold_box = ControlCheckBox('Threshold')
        self._threshold = ControlSlider('Binary Threshold', 114, 0, 255)

        self._roi_x_min = ControlSlider('ROI x top', 0, 0, 1000)
        self._roi_x_max = ControlSlider('ROI x bottom', 1000, 0, 1000)

        self._roi_y_min = ControlSlider('ROI y left', 0, 0, 1000)
        self._roi_y_max = ControlSlider('ROI y right', 1000, 0, 1000)

        # self._blobsize = ControlSlider('Minimum blob size', 100, 100, 2000)
        self._player = ControlPlayer('Player')
        self._runbutton = ControlButton('Run')
        self._start_frame = ControlText('Start Frame')
        self._stop_frame = ControlText('Stop Frame')

        self._color_list = ControlCombo('Color channels')
        self._color_list.add_item('Red Image Channel', 2)
        self._color_list.add_item('Green Image Channel', 1)
        self._color_list.add_item('Blue Image Channel', 0)

        self._clahe = ControlCheckBox('CLAHE      ')
        self._dilate = ControlCheckBox('Morphological Dilation')
        self._dilate_type = ControlCombo('Dilation Kernel Type')
        self._dilate_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._dilate_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._dilate_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._dilate_size = ControlSlider('Dilation Kernel Size', 3, 1, 10)

        self._erode = ControlCheckBox('Morphological Erosion')
        self._erode_type = ControlCombo('Erode Kernel Type')
        self._erode_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._erode_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._erode_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._erode_size = ControlSlider('Erode Kernel Size', 5, 1, 10)

        self._open = ControlCheckBox('Morphological Opening')
        self._open_type = ControlCombo('Open Kernel Type')
        self._open_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._open_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._open_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._open_size = ControlSlider('Open Kernel Size', 19, 1, 40)

        self._close = ControlCheckBox('Morphological Closing')
        self._close_type = ControlCombo('Close Kernel Type')
        self._close_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._close_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._close_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._close_size = ControlSlider('Close Kernel Size', 19, 1, 40)

        self._LoG = ControlCheckBox('LoG - Laplacian of Gaussian')
        self._LoG_size = ControlSlider('LoG Kernel Size', 30, 1, 60)

        self._progress_bar = ControlProgress('Progress Bar')

        # Define the function that will be called when a file is selected
        self._videofile.changed_event = self.__videoFileSelectionEvent
        # Define the event that will be called when the run button is processed
        self._runbutton.value = self.__runEvent
        # Define the event called before showing the image in the player
        self._player.process_frame_event = self.__processFrame

        # Define the organization of the Form Controls
        self.formset = [
            ('_videofile', '_outputfile'),
            ('_start_frame', '_stop_frame'),
            ('_color_list', '_clahe', '_roi_x_min', '_roi_y_min'),
            ('_threshold_box', '_threshold', '_roi_x_max', '_roi_y_max'),
            ('_dilate', '_erode', '_open', '_close'),
            ('_dilate_type', '_erode_type', '_open_type', '_close_type'),
            ('_dilate_size', '_erode_size', '_open_size', '_close_size'),
            ('_LoG', '_LoG_size'),
            '_runbutton',
            '_progress_bar',
            '_player'
        ]

    def __videoFileSelectionEvent(self):
        """
        When the videofile is selected instanciate the video in the player
        """
        self._player.value = self._videofile.value

    def __color_channel(self, frame):
        """
        Returns only one color channel of input frame.
        Output is in grayscale.
        """
        frame = frame[:, :, self._color_list.value]
        return frame

    def __create_kernels(self):
        """
        Creates kernels for morphological operations.
        Check cv2.getStructuringElement() doc for more info:
        http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/
        py_morphological_ops/py_morphological_ops.html

        Assumed that all kernels (except LoG kernel) are square.
        Example of use:
        open_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (19, 19))
        erosion_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
        dilate_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
        :return: _opening_kernel, _close_kernel, _erosion_kernel, \
            _dilate_kernel, _LoG_kernel
        """
        _opening_kernel = cv2.getStructuringElement(self._open_type.value,
                                                    (self._open_size.value,
                                                     self._open_size.value))
        _close_kernel = cv2.getStructuringElement(self._close_type.value,
                                                  (self._close_size.value,
                                                   self._close_size.value))
        _erosion_kernel = cv2.getStructuringElement(self._erode_type.value,
                                                    (self._erode_size.value,
                                                     self._erode_size.value))
        _dilate_kernel = cv2.getStructuringElement(self._dilate_type.value,
                                                   (self._dilate_size.value,
                                                    self._dilate_size.value))
        _LoG_kernel = get_log_kernel(self._LoG_size.value,
                                     int(self._LoG_size.value * 0.5))
        return _opening_kernel, _close_kernel, _erosion_kernel, \
            _dilate_kernel, _LoG_kernel

    def __morphological(self, frame):
        """
        Apply morphological operations selected by the user.
        :param frame: input frame of selected video.
        :return: preprocessed frame.
        """
        opening_kernel, close_kernel, erosion_kernel, \
            dilate_kernel, log_kernel = self.__create_kernels()
        # prepare image - morphological operations
        if self._erode.value:
            frame = cv2.erode(frame, erosion_kernel, iterations=1)
        if self._open.value:
            frame = cv2.morphologyEx(frame, cv2.MORPH_OPEN, opening_kernel)
        if self._close.value:
            frame = cv2.morphologyEx(frame, cv2.MORPH_CLOSE, close_kernel)
        if self._dilate.value:
            frame = cv2.dilate(frame, dilate_kernel, iterations=1)
            # create LoG kernel for finding local maximas
        if self._LoG.value:
            frame = cv2.filter2D(frame, cv2.CV_32F, log_kernel)
            frame *= 255
            # remove near 0 floats
            frame[frame < 0] = 0
        return frame

    def __roi(self, frame):
        """
        Define image region of interest.
        """
        # ROI
        height, width = frame.shape
        self._roi_x_max.min = int(height / 2)
        self._roi_x_max.max = height
        self._roi_y_max.min = int(width / 2)
        self._roi_y_max.max = width

        self._roi_x_min.min = 0
        self._roi_x_min.max = int(height / 2)
        self._roi_y_min.min = 0
        self._roi_y_min.max = int(width / 2)
        # x axis
        frame[:int(self._roi_x_min.value)][::] = 255
        frame[int(self._roi_x_max.value)::][::] = 255
        # y axis
        for m in range(height):  # height
            for n in range(width):  # width
                if n > self._roi_y_max.value or n < self._roi_y_min.value:
                    frame[m][n] = 255

        # frame[0::][:int(self._roi_y_min.value)] = 255
        # frame[0::][int(self._roi_y_max.value):] = 255
        return frame

    def _kalman(self, max_points, stop_frame, vid_fragment):
        """
        Kalman Filter function. Takes measurements from video analyse function
        and estimates positions of detected objects. Munkres algorithm is used
        for assignments between estimates (states) and measurements.
        :param max_points: measurements.
        :param stop_frame: number of frames to analise
        :param vid_fragment: video fragment for estimates displaying
        :return: x_est, y_est - estimates of x and y positions in the following
                 format: x_est[index_of_object][frame] gives x position of object
                 with index = [index_of_object] in the frame = [frame]. The same
                 goes with y positions.
        """
        # font for displaying info on the image
        font = cv2.FONT_HERSHEY_SIMPLEX
        index_error = 0
        value_error = 0
        # step of filter
        dt = 1.
        R_var = 1  # measurements variance between x-x and y-y
        # Q_var = 0.1  # model variance
        # state covariance matrix - no initial covariances, variances only
        # [10^2 px, 10^2 px, ..] -
        P = np.diag([100, 100, 10, 10, 1, 1])
        # state transition matrix for 6 state variables
        # (position - velocity - acceleration,
        # x, y)
        F = np.array([[1, 0, dt, 0, 0.5 * pow(dt, 2), 0],
                      [0, 1, 0, dt, 0, 0.5 * pow(dt, 2)],
                      [0, 0, 1, 0, dt, 0],
                      [0, 0, 0, 1, 0, dt],
                      [0, 0, 0, 0, 1, 0],
                      [0, 0, 0, 0, 0, 1]])
        # x and y coordinates only - measurements matrix
        H = np.array([[1., 0., 0., 0., 0., 0.],
                      [0., 1., 0., 0., 0., 0.]])
        # no initial corelation between x and y positions - variances only
        R = np.array(
            [[R_var, 0.], [0., R_var]])  # measurement covariance matrix
        # Q must be the same shape as P
        Q = np.diag([100, 100, 10, 10, 1, 1])  # model covariance matrix

        # create state vectors, max number of states - as much as frames
        x = np.zeros((stop_frame, 6))
        # state initialization - initial state is equal to measurements
        m = 0
        try:
            for i in range(len(max_points[0])):
                if max_points[0][i][0] > 0 and max_points[0][i][1] > 0:
                    x[m] = [max_points[0][i][0], max_points[0][i][1],
                            0, 0, 0, 0]
                    m += 1
        # required for django runserver tests
        except IndexError:
            index_error = 1

        est_number = 0
        # number of estimates at the start
        try:
            for point in max_points[::][0]:
                if point[0] > 0 and point[1] > 0:
                    est_number += 1
        except IndexError:
            index_error = 1

        # history of new objects appearance
        new_obj_hist = [[]]
        # difference between position of n-th object in m-1 frame and position
        # of the same object in m frame
        diff_2 = [[]]
        # for how many frames given object was detected
        frames_detected = []
        # x and y posterior positions (estimates) for drawnings
        x_est = [[] for i in range(stop_frame)]
        y_est = [[] for i in range(stop_frame)]

        # variable for counting frames where object has no measurement
        striked_tracks = np.zeros(stop_frame)
        removed_states = []
        new_detection = []
        ff_nr = 0  # frame number

        self._progress_bar.label = '3/4: Generating position estimates..'
        self._progress_bar.value = 0

        # kalman filter loop
        for frame in range(stop_frame):
            self._progress_bar.value = 100 * (ff_nr / stop_frame)
            # measurements in one frame
            try:
                frame_measurements = max_points[::][frame]
            except IndexError:
                index_error = 1

            measurements = []
            # make list of lists, not tuples; don't take zeros,
            # assuming it's image
            if not index_error:
                for meas in frame_measurements:
                    if meas[0] > 0 and meas[1] > 0:
                        measurements.append([meas[0], meas[1]])
            # count prior
            for i in range(est_number):
                x[i][::] = dot(F, x[i][::])
            P = dot(F, P).dot(F.T) + Q
            S = dot(H, P).dot(H.T) + R
            K = dot(P, H.T).dot(inv(S))
            ##################################################################
            # prepare for update phase -> get (prior - measurement) assignment
            posterior_list = []
            for i in range(est_number):
                if not np.isnan(x[i][0]) and not np.isnan(x[i][1]):
                    posterior_list.append(i)
                    # print(i)
            # print(posterior_list)
            #
            # print('state\n', x[0:est_number, 0:2])
            # print('\n')
            #    temp_matrix = np.array(x[0:est_number, 0:2])
            try:
                temp_matrix = np.array(x[posterior_list, 0:2])
                temp_matrix = np.append(temp_matrix, measurements, axis=0)
            except ValueError:
                value_error = 1

            # print(temp_matrix)
            distance = pdist(temp_matrix, 'euclidean')  # returns vector

            # make square matrix out of vector
            distance = squareform(distance)
            temp_distance = distance
            # remove elements that are repeated - (0-1), (1-0) etc.
            #    distance = distance[est_number::, 0:est_number]
            distance = distance[0:len(posterior_list), len(posterior_list)::]

            # munkres
            row_index, column_index = linear_sum_assignment(distance)
            final_cost = distance[row_index, column_index].sum()
            unit_cost = []
            index = []
            for i in range(len(row_index)):
                # index(object, measurement)
                index.append([row_index[i], column_index[i]])
                unit_cost.append(distance[row_index[i], column_index[i]])

            ##################################################################
            # index correction - take past states into account
            removed_states.sort()
            for removed_index in removed_states:
                for i in range(len(index)):
                    if index[i][0] >= removed_index:
                        index[i][0] += 1
            ##################################################################
            # find object to reject
            state_list = [index[i][0] for i in range(len(index))]
            reject = np.ones(len(posterior_list))
            i = 0
            for post_index in posterior_list:
                if post_index not in state_list:
                    reject[i] = 0
                i += 1
            # check if distance (residual) isn't to high for assignment
            for i in range(len(unit_cost)):
                if unit_cost[i] > 20:
                    print('cost to high, removing', i)
                    reject[i] = 0

            ##################################################################
            # update phase
            for i in range(len(index)):
                # find object that should get measurement next
                # count residual y: measurement - state
                if index[i][1] >= 0:
                    y = np.array([measurements[index[i][1]] -
                                  dot(H, x[index[i][0], ::])])
                    # posterior
                    x[index[i][0], ::] = x[index[i][0], ::] + dot(K, y.T).T
                    # append new positions
                #        if x[i][0] and x[i][1]:
                x_est[index[i][0]].append([x[index[i][0], 0]])
                y_est[index[i][0]].append([x[index[i][0], 1]])
            # posterior state covariance matrix
            P = dot(np.identity(6) - dot(K, H), P)
            print('posterior\n', x[0:est_number, 0:2])
            ##################################################################
            # find new objects and create new states for them
            new_index = []
            measurement_indexes = []
            for i in range(len(index)):
                if index[i][1] >= 0.:
                    # measurements that have assignment
                    measurement_indexes.append(index[i][1])

            for i in range(len(measurements)):
                if i not in measurement_indexes:
                    # find measurements that don't have assignments
                    new_index.append(i)
            new_detection.append([measurements[new_index[i]]
                                  for i in range(len(new_index))])
            # for every detections in the last frame
            for i in range(len(new_detection[len(new_detection) - 1])):
                if new_detection[frame][i] and \
                                new_detection[frame][i][0] > 380:
                    x[est_number, ::] = [new_detection[frame][i][0],
                                         new_detection[frame][i][1], 0, 0, 0,
                                         0]
                    est_number += 1
                    # print('state added', est_number)
                    # print('new posterior\n', x[0:est_number, 0:2])
            ##################################################################
            # find states without measurements and remove them
            no_track_list = []
            for i in range(len(reject)):
                if not reject[i]:
                    no_track_list.append(posterior_list[i])
                    #    print('no_trk_list', no_track_list)
            for track in no_track_list:
                if track >= 0:
                    striked_tracks[track] += 1
                    print('track/strikes', track, striked_tracks[track])
            for i in range(len(striked_tracks)):
                if striked_tracks[i] >= 1:
                    x[i, ::] = [None, None, None, None, None, None]
                    if i not in removed_states:
                        removed_states.append(i)
                    print('state_removed', i)
                ff_nr += 1
                # print(removed_states)
                # print(index)
        return x_est, y_est, est_number

    def _plot_points(self, vid_frag, max_points, x_est, y_est, est_number):
        self._progress_bar.label = '4/4: Plotting - measurements..'
        self._progress_bar.value = 0
        # plot raw measurements
        for frame_positions in max_points:
            for pos in frame_positions:
                plt.plot(pos[0], pos[1], 'r.')
        # try:
        plt.axis([0, vid_frag[0].shape[1], vid_frag[0].shape[0], 0])
        # except IndexError:
        #     index_error = 1
        plt.xlabel('width [px]')
        plt.ylabel('height [px]')
        plt.title('Objects raw measurements')
        ######################################################################
        # image border - 10 px
        x_max = vid_frag[0].shape[1] - 10
        y_max = vid_frag[0].shape[0] - 10

        self._progress_bar.label = '4/4: Plotting - estimates..'
        self._progress_bar.value = 0
        i = 0
        # plot estimated trajectories
        for ind in range(est_number):
            self._progress_bar.value = 100 * (i / est_number)
            i += 1
            # if estimate exists
            if len(x_est[ind]):
                for pos in range(len(x_est[ind])):
                    # don't draw near 0 points and near max points
                    if not np.isnan(x_est[ind][pos][0]) and \
                                    x_est[ind][pos][0] > 10 and \
                                    y_est[ind][pos][0] > 10 and \
                                    x_est[ind][pos][0] < x_max - 10 and \
                                    y_est[ind][pos][0] < y_max - 10:
                        plt.plot(x_est[ind][pos][0], y_est[ind][pos][0], 'g.')
                        # plt.plot(x_est[ind][::], y_est[ind][::], 'g-')
        # print(frame)
        #  [xmin xmax ymin ymax]
        # try:
        plt.axis([0, vid_frag[0].shape[1], vid_frag[0].shape[0], 0])
        # except IndexError:
        #     index_error = 1
        plt.xlabel('width [px]')
        plt.ylabel('height [px]')
        plt.title('Objects estimated trajectories')
        plt.grid()
        plt.show()

    def __processFrame(self, frame):
        """
        Do some processing to the frame and return the result frame
        """
        # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        frame = self.__color_channel(frame)

        if self._clahe.value:
            clahe = cv2.createCLAHE(clipLimit=8.0, tileGridSize=(8, 8))
            frame = clahe.apply(frame)

        frame = self.__roi(frame)

        if self._threshold_box.value:
            ret, frame = cv2.threshold(frame, self._threshold.value, 255,
                                       cv2.THRESH_BINARY)
            frame = self.__morphological(frame)
        return frame




    def __runEvent(self):
        """
        After setting the best parameters run the full algorithm
        """
        if not self._start_frame.value or not self._stop_frame.value or \
                self._start_frame.value >= self._stop_frame.value:
            raise ValueError('Wrong start or stop frame!')
        start_frame = int(self._start_frame.value)
        stop_frame = int(self._stop_frame.value)
        # pass cv2.VideoCapture object, not string
        # my_video = self._player.value
        video = self._player.value
        # self._load_bar.__init__('Processing..')
        vid_fragment = select_frames(video, start_frame, stop_frame)
        try:
            height = vid_fragment[0].shape[0]
            width = vid_fragment[0].shape[1]
        except IndexError:
            raise IndexError('No video loaded. Check video path.')

        i = 0
        bin_frames = []
        # preprocess image loop
        self._progress_bar.label = '1/4: Creating BW frames..'
        self._progress_bar.value = 0
        for frame in vid_fragment:
            gray_frame = self.__color_channel(frame)
            # create a CLAHE object (Arguments are optional)
            if self._clahe.value:
                clahe = cv2.createCLAHE(clipLimit=8.0, tileGridSize=(8, 8))
                gray_frame = clahe.apply(gray_frame)

            # ROI
            gray_frame = self.__roi(gray_frame)
            ret, th1 = cv2.threshold(gray_frame, self._threshold.value, 255,
                                     cv2.THRESH_BINARY)
            # frame_thresh1 = otsu_binary(cl1)
            bin_frames.append(th1)
            self._progress_bar.value = 100*(i/len(vid_fragment))
            i += 1
        ######################################################################
        i = 0
        maxima_points = []
        # gather measurements loop

        self._progress_bar.label = '2/4: Finding local maximas..'
        self._progress_bar.value = 0
        for frame in bin_frames:
            frame = self.__morphological(frame)
            # get local maximas of filtered image per frame
            maxima_points.append(local_maxima(frame))
            self._progress_bar.value = 100 * (i / len(bin_frames))
            i += 1

        x_est, y_est, est_number = self._kalman(maxima_points, stop_frame,
                                                vid_fragment)

        print('\nFinal estimates number:', est_number)
        self._plot_points(vid_fragment, maxima_points, x_est, y_est,
                          est_number)
        print('EOF - DONE')
Esempio n. 24
0
class ImportWindow(BaseWidget):

	def __init__(self, timeline=None):
		super(ImportWindow, self).__init__('Import file', parentWindow=timeline)
		self.setContentsMargins(10, 10, 10, 10)
		self._timeline = timeline

		# Definition of the forms fields
		self._filetype = ControlCombo('Please select the type of file you would like to import:')
		self._importButton = ControlButton('Import')
		self._panel = ControlEmptyWidget('Panel')
		self._file = ControlFile('File to import')

		self._panel.value = self._file
		self._filetype.addItem('Events file', 0)
		self._filetype.addItem('Graph file', 1)
		self._filetype.addItem('Bonsai events file', 2)

		self._formset = [
			('_filetype', ' '),
			'_panel',
			(' ', '_importButton'), ' ']

		self._filetype.changed = self.__fileTypeChanged
		self._importButton.value = self.__importData

		from pyforms.gui.dialogs.csv_parser import CsvParserDialog
		self._graphCsvParserDlg = CsvParserDialog()
		self._graphCsvParserDlg.xField.label = "Value column"
		self._graphCsvParserDlg.yField.hide()
		self._graphCsvParserDlg.zField.hide()
		self._graphCsvParserDlg.loadButton.hide()

		self._bonsaiImportDlg = BonsaiImportFileDlg()

	def __fileTypeChanged(self):
		if self._filetype.value == 0:
			self._panel.value = self._file

		elif self._filetype.value == 1:
			self._panel.value = self._graphCsvParserDlg

		elif self._filetype.value == 2:
			self._panel.value = self._bonsaiImportDlg

	def __importData(self):
		if self._filetype.value == 0:
			separator = ','
			with open(self._file.value, 'rU') as csvfile:
				line = csvfile.readline()
				if ";" in line:
					separator = ';'
			with open(self._file.value, 'rU') as csvfile:
				csvfile = csv.reader(csvfile, delimiter=separator)
				self._timeline._time.import_csv(csvfile)

		elif self._filetype.value == 1:
			self._timeline._time.importchart_csv(self._graphCsvParserDlg)
			self._timeline.show_graphs_properties()

		elif self._filetype.value == 2:
			with open(self._bonsaiImportDlg._file.value, 'rU') as csvfile:
				values = []
				pointEventValues = []
				csvfile = csv.reader(csvfile, delimiter=' ')
				for row in csvfile:  # strip Start/End word from all events names which are not PointEven
					try:
						timestr = row[1].rstrip('0')
						cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S.%f")
					except:
						timestr = row[1]
						cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S")

					seconds = (cvttime - datetime.datetime(1900, 1, 1)).total_seconds()
					frame = int(round(self._bonsaiImportDlg._fps.value * seconds))

					if row[2] == "PointEvent":
						eventtype = row[0]
						pointEventValues.append([eventtype, frame, row[2]])
					else:
						if row[0].startswith('Start'):
							eventtype = row[0][len('Start'):]  # strip Start word from the beginning
						else:
							eventtype = row[0][len('End'):]  # strip End word from the beginning
						values.append([eventtype, frame, row[2]])

				values = sorted(values, key=lambda x: (x[0].capitalize(), x[1]))
				pointEventValues = sorted(pointEventValues, key=lambda x: (x[0].capitalize(), x[1]))
				ntracks = len(set([x[0] for x in values])) + 1

				# collapse
				events = []
				eventsTypes = {}  # Events names
				currentTrack = 0
				for index in range(0, len(pointEventValues)):
					pointEventValue = pointEventValues[index]
					eventsTypes[pointEventValue[0]] = currentTrack
					self._timeline.addPeriod([pointEventValue[1], pointEventValue[1] + 50, pointEventValue[0]], track=currentTrack)

				currentTrack = 1

				for index in range(0, len(values), 2):
					row0 = values[index]
					row1 = values[index + 1]

					if row0[0] not in eventsTypes:
						eventsTypes[row0[0]] = currentTrack
						track = currentTrack
						currentTrack += 1
					else:
						track = eventsTypes[row0[0]]

					self._timeline.addPeriod([row0[1], row1[1], row0[0]], track=track)

		self.close()  # pylint: disable=no-member


	def import_chart(self, filename, frame_col=0, val_col=1):
		self._filetype.value = 1            
		self._graphCsvParserDlg.filename    = filename
		self._graphCsvParserDlg.frameColumn = frame_col
		self._graphCsvParserDlg.xColumn     = val_col
Esempio n. 25
0
class ImportWindow(BaseWidget):

    def __init__(self, timeline=None):
        super(ImportWindow, self).__init__('Import file')
        self.setContentsMargins(10, 10, 10, 10)
        self._timeline = timeline

        # Definition of the forms fields
        self._filetype = ControlCombo('Please select the type of file you would like to import:')
        self._importButton = ControlButton('Import')
        self._panel = ControlEmptyWidget('Panel')
        self._file = ControlFile('File to import')

        self._panel.value = self._file
        self._filetype.addItem('Events file', 0)
        self._filetype.addItem('Graph file', 1)
        self._filetype.addItem('Bonsai events file', 2)

        self._formset = [
            ('_filetype', ' '),
            '_panel',
            (' ', '_importButton'), ' ']

        self._filetype.changed = self.__fileTypeChanged
        self._importButton.value = self.__importData

        self._graphCsvParserDlg = CsvParserDialog()
        self._graphCsvParserDlg.xField.label = "Value column"
        self._graphCsvParserDlg.yField.hide()
        self._graphCsvParserDlg.zField.hide()
        self._graphCsvParserDlg.loadButton.hide()

        self._bonsaiImportDlg = BonsaiImportFileDlg()

    def __fileTypeChanged(self):
        if self._filetype.value == 0:
            self._panel.value = self._file

        elif self._filetype.value == 1:
            self._panel.value = self._graphCsvParserDlg

        elif self._filetype.value == 2:
            self._panel.value = self._bonsaiImportDlg

    def __importData(self):
        if self._filetype.value == 0:
            separator = ','
            with open(self._file.value, 'rU') as csvfile:
                line = csvfile.readline()
                if ";" in line:
                    separator = ';'
            with open(self._file.value, 'rU') as csvfile:
                csvfile = csv.reader(csvfile, delimiter=separator)
                self._timeline._time.import_csv(csvfile)

        elif self._filetype.value == 1:
            self._timeline._time.importchart_csv(self._graphCsvParserDlg)

        elif self._filetype.value == 2:
            with open(self._bonsaiImportDlg._file.value, 'rU') as csvfile:
                values = []
                csvfile = csv.reader(csvfile, delimiter=' ')
                for row in csvfile:
                    try:
                        timestr = row[1].rstrip('0')
                        cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S.%f")
                    except:
                        timestr = row[1]
                        cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S")

                    seconds = (cvttime - datetime.datetime(1900, 1, 1)).total_seconds()
                    frame = int(round(self._bonsaiImportDlg._fps.value * seconds))
                    if row[0].startswith('Start'):
                        eventtype = row[0][5:]
                    else:
                        eventtype = row[0][3:]
                    values.append([eventtype, frame, row[2]])

                values = sorted(values, key=lambda x: (x[0].capitalize(), x[1]))
                ntracks = len(set([x[0] for x in values]))

                # collapse
                events = []
                eventsTypes = {}
                currentTrack = 0
                for index in range(0, len(values), 2):
                    row0 = values[index]
                    row1 = values[index + 1]

                    if row0[0] not in eventsTypes:
                        eventsTypes[row0[0]] = currentTrack
                        track = currentTrack
                        currentTrack += 1
                    else:
                        track = eventsTypes[row0[0]]

                    self._timeline.addPeriod([row0[1], row1[1], row0[0]], track=track)

        self.close()
Esempio n. 26
0
    def __init__(self):

        Globals.init()

        # Initialize the Metronome GUI
        BaseWidget.__init__(self, "AutoMetronome")

        # Create the Settings GUI

        # Metronome Tab
        self._togglePause       = ControlButton("Play/Pause", checkable=True)
        self._minusOne          = ControlButton("-")
        self._addOne            = ControlButton("+")

        self._togglePause.value = self.togglePauseAction
        self._minusOne.value    = self.minusOneAction
        self._addOne.value      = self.addOneAction

        # Settings Tab
        self._minTempoInput     = ControlText(label="Minimum Tempo", defaultValue="30")
        self._maxTempoInput     = ControlText(label="Maximum Tempo", defaultValue="255")
        self._timeSignatureNumeratorInput = ControlNumber(label="Time Signature:", defaultValue=4)
        self._timeSignatureDenominatorInput = ControlNumber(label="/",defaultValue=4)
        self._subdivisionInput  = ControlNumber("Subdivisions per Beat:", defaultValue=1)

        self._tempoDividerSet   = ControlCombo("Tempo Defined ")
        self._tempoDividerSet.addItem("In Full Value", value="quarter")
        self._tempoDividerSet.addItem("In Cut Time", value="half")
        self._tempoDividerSet.addItem("In One", value="one")
        self._tempoDividerSet.addItem("In Two", value="eighth")
        self._tempoDividerSet.addItem("By Dotted Eighth Note (for 6/8 or similar times)", value="eighth_dot")
        self._tempoDividerSet.addItem("By Dotted Quarter Note (for 6/8 or similar times)", value="quarter_dot")

        self._updateSettings    = ControlButton("Save")
        self._updateSettings.value = self.updateSettingsAction

        # Programming Tab

        self._runProgram        = ControlButton("Run Program")
        self._runProgram.value  = self.runProgramAction
        self._loadProgram       = ControlFile(label="Load Program")

        self._programmingPanel        = ControlDockWidget()

        programmingWindow = Programming()
        programmingWindow.parent = self
        self._programmingPanel.value = programmingWindow
        # self._programmingPanel.hide()

        # End of UI creation

        global minTempo
        global maxTempo
        minTempo = int(self._minTempoInput.value)
        maxTempo = int(self._maxTempoInput.value)

        global timeSignatureNumerator
        global timeSignatureDenominator
        timeSignatureNumerator = int(self._timeSignatureNumeratorInput.value)
        timeSignatureDenominator = int(self._timeSignatureDenominatorInput.value)

        global subdivision
        subdivision = float(self._subdivisionInput.value)

        global tempoDivider
        global bpmMultiplier
        tempoDivider = self._tempoDividerSet.value
        bpmMultiplier = 1

        self._metronomeStatusLabel = ControlLabel("Time Signature: "+str(timeSignatureNumerator)+"/"+str(timeSignatureDenominator))
        self._metronomeSubdivLabel = ControlLabel("Subdivision: "+str(subdivision))

        # Draw the metronome
        Metronome.drawMetronome(self)

        # Set layout
        self._formset = [ {
            'Metronome': [('_tempoSlider', '_minusOne','_addOne'), ('_metronomeStatusLabel', '_metronomeSubdivLabel'),'=','_togglePause'],
            'Settings': ['_minTempoInput', '_maxTempoInput',('_timeSignatureNumeratorInput', '_timeSignatureDenominatorInput'), '_subdivisionInput', '_tempoDividerSet','_updateSettings'],
            'Programming':['_runProgram', '_loadProgram'],
            'Vade Mecum':['Programming: \n The window is relatively self explanatory, \n but there are a few hidden details. If you name an Event \"STOP\", \n the program will automatically stop at the beginning of that measure.\n If you name an Event \"REPEAT\", you can put the Event number \n (first Event being \'1\') in the Beats column \n and the number of times to repeat in the BPM column. \n \n Saving/Loading: \n Saving a program happens automatically when you open a file \n in the Save Program window. There is no feedback \n to indicate this yet.']
        }]
Esempio n. 27
0
class GenericCsvParserDialog(BaseWidget):
    def __init__(self, columns, parent=None):
        super(GenericCsvParserDialog, self).__init__('CSV Choose the columns',
                                                     parent_win=parent)

        self._filename = None
        self._columns = columns
        self._columns_indexes = []
        self._rownum = 0

        # Definition of the forms fields
        self._filename = ControlFile('CSV File')
        self._separator = ControlCombo('Separator', default='auto')
        self._startingrow = ControlNumber('Starting row', default=0)

        for index, column in enumerate(columns):
            setattr(
                self, '_col_{0}'.format(index),
                ControlNumber(column, default=index, minimum=-1, maximum=1000))

        self._filePreview = ControlList('Preview')
        self._loadButton = ControlButton('Load')

        form_row = ['_separator'] + [
            '_col_{0}'.format(index) for index, column in enumerate(columns)
        ] + ['_loadButton']

        self._formset = [('_filename', '_startingrow'),
                         tuple(form_row), '_filePreview']
        self._separator.changed_event = self.__refreshPreview
        self._filename.changed_event = self.__refreshPreview
        self._startingrow.changed_event = self.__refreshPreview
        self._loadButton.value = self.load

        self._load_event = None

        self._separator.add_item('auto', 'auto')
        self._separator.add_item(';', ';')
        self._separator.add_item(',', ',')
        self._separator.add_item('TAB', '\t')
        self._separator.add_item('Excel', csv.excel)
        self._separator.add_item('Excel TAB', csv.excel_tab)

    @property
    def load_file_event(self):
        return self._load_event

    @load_file_event.setter
    def load_file_event(self, value):
        self._load_event = value

    def __iter__(self):

        if self._filename.value != None and self._filename.value != '':
            csvfile = open(self._filename.value, 'U')
            if self.delimiter in ['auto', csv.excel, csv.excel_tab]:
                try:
                    dialect = csv.Sniffer().sniff(csvfile.read(1024))
                    csvfile.seek(0)
                    self._spamreader = csv.reader(csvfile, dialect)
                except:
                    self._spamreader = None
                    return self
            else:
                self._spamreader = csv.reader(csvfile,
                                              delimiter=self.delimiter)
            for i in range(int(self._startingrow.value)):
                next(self._spamreader, None)  # skip the headers
        else:
            self._spamreader = None

        return self

    # For compatibility with python 3
    def __next__(self):
        return self.next()

    def next(self):
        if self._spamreader != None:
            row = next(self._spamreader)
            res = []
            for col in self._columns_indexes:
                if col == -1:
                    res.append(self._rownum)
                else:
                    if row[col].lower() == 'nan':
                        res.append('None')
                    else:
                        res.append(row[col])

            self._rownum += 1

            return res
        else:
            raise StopIteration()

    def __refreshPreview(self):
        if self._filename.value != None and self._filename.value != '':
            with open(self._filename.value, 'U') as csvfile:
                if self.delimiter in ['auto', csv.excel, csv.excel_tab]:
                    try:
                        dialect = csv.Sniffer().sniff(csvfile.read(1024))
                        csvfile.seek(0)
                        spamreader = csv.reader(csvfile, dialect)
                    except:
                        self.message('Error when reading the file.')
                        return
                else:
                    spamreader = csv.reader(csvfile, delimiter=self.delimiter)

                for i in range(int(self._startingrow.value)):
                    next(spamreader, None)  # skip the headers
                self._filePreview.value = []
                self._filePreview.horizontalHeaders = map(str, range(1000))
                for i, row in enumerate(spamreader):
                    self._filePreview += row
                    if i >= 10:
                        break

    @property
    def delimiter(self):
        return self._separator.value

    def load(self):
        self.__refreshPreview()
        self._columns_indexes = []
        for index, column in enumerate(self._columns):
            self._columns_indexes.append(
                int(getattr(self, '_col_{0}'.format(index)).value))
        if self._load_event is not None: self._load_event()
Esempio n. 28
0
class Metronome(Programming, BaseWidget):

    # def global non-settings variables
    global playing
    playing = False
    global bpm
    global checkSliderThread
    global metronomeSoundThread
    global metronomeTime
    global timeSignatureNumerator
    global timeSignatureDenominator
    global subdivision
    
    Globals.programRunning = False

    # def global settings variables
    global minTempo
    global maxTempo

    def metronomeSound(self):
        global bpm
        global playing
        global metronomeTime
        global timeSignatureNumerator
        global timeSignatureDenominator
        global subdivision
        global measure
        measure = 0
        global tempoChangeCount
        count = 0

        global initialized
        initialized = False

        ## The numerator is the number of beats played.
        ## The denominator is the speed of the beats.
        ## If the the numerator is the same as the denominator, the the tempo should remain the same.
        ## If the numerator is not, the tempo should be increased by the denominator divided by four.
        ## TODO: Add changable beat definitions
        ## If the numerator is not, the numerator should be divided by the denominator divided by four.

        metronomeTime = (60.0 / bpm)/int(subdivision)


        beatOne = pyglet.media.load("sound/beatOne.wav", streaming=False)
        quarterBeat = pyglet.media.load("sound/quarterBeat.wav", streaming=False)
        offBeat = pyglet.media.load("sound/offBeat.wav", streaming=False)

        count = (timeSignatureNumerator*int(subdivision))
        timeSigMem = timeSignatureNumerator
        if not Globals.programRunning:
            print("Metronome Clicking as metronome")
            while playing:
                # May add again later - was moved down to be universal
                # if metronomeTime != 60.0 / bpm : metronomeTime = 60.0 / bpm

                if timeSigMem != timeSignatureNumerator:
                    measure = 1
                    player = beatOne.play()
                    print("UPDATE COUNT!")
                    count = (timeSignatureNumerator*subdivision)
                    timeSigMem = timeSignatureNumerator

                else:
                    if count%(timeSignatureNumerator*subdivision) == 0:
                        player = beatOne.play()
                        measure += 1

                    else:
                        if count%subdivision != 0 or subdivision == 1:
                            player = quarterBeat.play()
                        else:
                            player = offBeat.play()

                Metronome.busy_wait(self, metronomeTime)


                player.delete()
                count += 1
                
                Globals.programRunning = False

        else:
            print("Metronome Clicking as Program")
            global currentEvent
            currentEvent = 0
            global programmedBPM
            programmedBPM = Globals.globalEventList[0][1]
            global measure
            global repeatNumber
            repeatNumber = 1
            global changingTempo
            changingTempo = False
            global tempoChangeCount
            tempoChangeCount = 0

            while playing:
                metronomeTime = (60.0 / float(programmedBPM))/float(subdivision)
                subdivision = int(subdivision)
                # May add again later - was moved down to be universal
                # if metronomeTime != 60.0 / bpm : metronomeTime = 60.0 / bpm
                if int(count) % (int(timeSignatureNumerator)*int(subdivision)) == 0:
                    try:
                        if Globals.globalEventList[currentEvent][0] == "STOP" and measure == int(Globals.globalEventList[currentEvent][5]):
                            print("Program Ended")
                            self._runProgram.label="Run Program"
                            playing = False
                            Globals.programRunning = False
                            break

                        else:
                            if measure == int(Globals.globalEventList[currentEvent][5])-1:
                                print("Event Triggered: "+str(Globals.globalEventList[currentEvent][0]))

                                if int(Globals.globalEventList[currentEvent][6]) > 1:
                                    global changingTempo
                                    changingTempo = True

                                    tempoChange = int(Globals.globalEventList[currentEvent][1]) - int(programmedBPM)

                                    global tempoPerBeat
                                    tempoPerBeat = tempoChange/int(Globals.globalEventList[currentEvent][6])

                                else:
                                    programmedBPM = Globals.globalEventList[currentEvent][1]


                                global timeSignatureNumerator
                                global timeSignatureDenominator
                                global subdivision

                                timeSignatureNumerator = Globals.globalEventList[currentEvent][2]
                                timeSignatureDenominator = Globals.globalEventList[currentEvent][3]
                                subdivision = Globals.globalEventList[currentEvent][4]
                                programmedBPM = programmedBPM*(int(timeSignatureDenominator)/4)
                                subdivision = int(subdivision)
                                timeSignatureNumerator = int(timeSignatureNumerator)

                                global count
                                count = timeSignatureNumerator

                                self._tempoSlider.value = programmedBPM
                                self._metronomeStatusLabel.value = ("Time Signature: "+str(timeSignatureNumerator)+"/"+str(timeSignatureDenominator))
                                self._metronomeSubdivLabel.value = ("Subdivision: "+str(subdivision))

                            player = beatOne.play()
                            measure += 1

                        try:
                            Globals.globalEventList[currentEvent][6]
                        except IndexError:
                            print("Program Ended")
                            self._runProgram.label="Run Program"
                            playing = False
                            Globals.programRunning = False
                            break

                    except IndexError:
                        print("Program Ended")
                        self._runProgram.label="Run Program"
                        playing = False
                        Globals.programRunning = False
                        break

                        if Globals.globalEventList[currentEvent][0] == "REPEAT" and repeatNumber > 0:
                            global initialized
                            if initialized:
                                global repeatNumber
                                repeatNumber -= 1
                            else:
                                global repeatNumber
                                repeatNumber = Globals.globalEventList[currentEvent][2]
                                initialized = True
                            currentEvent = int(int(Globals.globalEventList[currentEvent][1])-1)

                    global currentEvent
                    currentEvent = currentEvent+1
                    int(currentEvent)

                else:

                    if Globals.globalEventList[currentEvent-1][0] == "STOP" and measure == int(Globals.globalEventList[currentEvent-1][5]):
                            print("Program Ended")
                            self._runProgram.label="Run Program"
                            playing = False
                            Globals.programRunning = False
                            break
                    else:

                        if count%subdivision != 0 or subdivision == 1:
                            player = quarterBeat.play()

                            try:
                                global changingTempo
                                if changingTempo == True and tempoChangeCount <= int(Globals.globalEventList[currentEvent][6]):
                                    global programmedBPM
                                    programmedBPM = int(programmedBPM)+int(tempoPerBeat)
                                    print(programmedBPM)
                                    global tempoChangeCount
                                    tempoChangeCount += 1
                                    print(tempoChangeCount)
                            except IndexError:
                                print("Program Ended")
                                self._runProgram.label="Run Program"
                                playing = False
                                Globals.programRunning = False
                                break

                        else:
                            player = offBeat.play()

                Metronome.busy_wait(self, metronomeTime)

                player.delete()
                count = int(count)+1


    def drawMetronome(self):
        # Create the Metronome GUI
        self._tempoSlider       = ControlSlider("Tempo", defaultValue=120, min=minTempo, max=maxTempo)
        self._togglePause       = ControlButton("Play/Pause", checkable=True)
        self._minusOne          = ControlButton("-")
        self._addOne            = ControlButton("+")

        self._togglePause.value = self.togglePauseAction
        self._minusOne.value    = self.minusOneAction
        self._addOne.value      = self.addOneAction

        global bpm
        bpm = self._tempoSlider.value

    def __init__(self):

        Globals.init()

        # Initialize the Metronome GUI
        BaseWidget.__init__(self, "AutoMetronome")

        # Create the Settings GUI

        # Metronome Tab
        self._togglePause       = ControlButton("Play/Pause", checkable=True)
        self._minusOne          = ControlButton("-")
        self._addOne            = ControlButton("+")

        self._togglePause.value = self.togglePauseAction
        self._minusOne.value    = self.minusOneAction
        self._addOne.value      = self.addOneAction

        # Settings Tab
        self._minTempoInput     = ControlText(label="Minimum Tempo", defaultValue="30")
        self._maxTempoInput     = ControlText(label="Maximum Tempo", defaultValue="255")
        self._timeSignatureNumeratorInput = ControlNumber(label="Time Signature:", defaultValue=4)
        self._timeSignatureDenominatorInput = ControlNumber(label="/",defaultValue=4)
        self._subdivisionInput  = ControlNumber("Subdivisions per Beat:", defaultValue=1)

        self._tempoDividerSet   = ControlCombo("Tempo Defined ")
        self._tempoDividerSet.addItem("In Full Value", value="quarter")
        self._tempoDividerSet.addItem("In Cut Time", value="half")
        self._tempoDividerSet.addItem("In One", value="one")
        self._tempoDividerSet.addItem("In Two", value="eighth")
        self._tempoDividerSet.addItem("By Dotted Eighth Note (for 6/8 or similar times)", value="eighth_dot")
        self._tempoDividerSet.addItem("By Dotted Quarter Note (for 6/8 or similar times)", value="quarter_dot")

        self._updateSettings    = ControlButton("Save")
        self._updateSettings.value = self.updateSettingsAction

        # Programming Tab

        self._runProgram        = ControlButton("Run Program")
        self._runProgram.value  = self.runProgramAction
        self._loadProgram       = ControlFile(label="Load Program")

        self._programmingPanel        = ControlDockWidget()

        programmingWindow = Programming()
        programmingWindow.parent = self
        self._programmingPanel.value = programmingWindow
        # self._programmingPanel.hide()

        # End of UI creation

        global minTempo
        global maxTempo
        minTempo = int(self._minTempoInput.value)
        maxTempo = int(self._maxTempoInput.value)

        global timeSignatureNumerator
        global timeSignatureDenominator
        timeSignatureNumerator = int(self._timeSignatureNumeratorInput.value)
        timeSignatureDenominator = int(self._timeSignatureDenominatorInput.value)

        global subdivision
        subdivision = float(self._subdivisionInput.value)

        global tempoDivider
        global bpmMultiplier
        tempoDivider = self._tempoDividerSet.value
        bpmMultiplier = 1

        self._metronomeStatusLabel = ControlLabel("Time Signature: "+str(timeSignatureNumerator)+"/"+str(timeSignatureDenominator))
        self._metronomeSubdivLabel = ControlLabel("Subdivision: "+str(subdivision))

        # Draw the metronome
        Metronome.drawMetronome(self)

        # Set layout
        self._formset = [ {
            'Metronome': [('_tempoSlider', '_minusOne','_addOne'), ('_metronomeStatusLabel', '_metronomeSubdivLabel'),'=','_togglePause'],
            'Settings': ['_minTempoInput', '_maxTempoInput',('_timeSignatureNumeratorInput', '_timeSignatureDenominatorInput'), '_subdivisionInput', '_tempoDividerSet','_updateSettings'],
            'Programming':['_runProgram', '_loadProgram'],
            'Vade Mecum':['Programming: \n The window is relatively self explanatory, \n but there are a few hidden details. If you name an Event \"STOP\", \n the program will automatically stop at the beginning of that measure.\n If you name an Event \"REPEAT\", you can put the Event number \n (first Event being \'1\') in the Beats column \n and the number of times to repeat in the BPM column. \n \n Saving/Loading: \n Saving a program happens automatically when you open a file \n in the Save Program window. There is no feedback \n to indicate this yet.']
        }]


    # Multithreaded slider process defined here
    def checkSlider(self):
        while(playing):
            global bpm
            global bpmMultiplier
            global metronomeTime
            global subdivision
            if bpm != self._tempoSlider.value*float(bpmMultiplier):
                bpm = self._tempoSlider.value*float(bpmMultiplier)
                metronomeTime = (60.0/bpm)/subdivision
                print("BPM updated to "+str(bpm))
            time.sleep(0.1)

    # define the Play/Pause Button action
    def togglePauseAction(self):
        global playing
        if playing == False:
            print("Playing at "+str(self._tempoSlider.value)+"bpm")
            playing = True

            global bpm
            bpm = self._tempoSlider.value

            # Start Metronome
            global metronomeSoundThread
            metronomeSoundThread = threading.Thread(name='metronomeSoundThread', target=Metronome.metronomeSound, args=(self,))
            metronomeSoundThread.setDaemon(True)
            metronomeSoundThread.start()

            # Start Slider polling
            global checkSliderThread
            checkSliderThread = threading.Thread(name='checkSliderThread', target=Metronome.checkSlider, args=(self,))
            checkSliderThread.setDaemon(True)
            checkSliderThread.start()

        else:
            print("Stopped at "+str(self._tempoSlider.value)+"bpm")
            playing = False


    # define the add/subtract bpm buttons
    def minusOneAction(self):
        self._tempoSlider.value -= 1
    def addOneAction(self):
        self._tempoSlider.value += 1

    # define the update settings button action
    def updateSettingsAction(self):
        #Save the min/max tempos
        global minTempo
        global maxTempo
        global timeSignatureNumerator
        global timeSignatureDenominator
        global subdivision
        global metronomeTime
        global bpm
        global bpmMultiplier
        global tempoDivider

        minTempo = int(float(self._minTempoInput.value))
        maxTempo = int(float(self._maxTempoInput.value))
        timeSignatureNumerator = int(float(self._timeSignatureNumeratorInput.value))
        timeSignatureDenominator = int(float(self._timeSignatureDenominatorInput.value))
        tempoDivider = self._tempoDividerSet.value

        # SKETCHY SUBDIVISION VALUES - CHECK HERE FOR GLITCHES
        # TODO: Bug testing!

        subdivision = int(float(self._subdivisionInput.value))
        metronomeTime = (60.0/bpm)/subdivision
        bpm = bpm*(timeSignatureDenominator/4)

        # SKETCHY NEW NOTE LENGTH DEFINITIONS

        if tempoDivider == "quarter":
            bpmMultiplier = 1
        elif tempoDivider == "half":
            bpmMultiplier = 2
        elif tempoDivider == "one":
            bpmMultiplier = float(1/float(timeSignatureNumerator))
            timeSignatureNumerator = 1
        elif tempoDivider == "eighth":
            bpmMultiplier = 0.5
            timeSignatureNumerator = timeSignatureNumerator/2
        elif tempoDivider == "eighth_dot":
            bpmMultiplier = float(0.25*(3.0/2.0)*(timeSignatureDenominator/4))
        elif tempoDivider == "quarter_dot":
            bpmMultiplier = float(0.5*(3.0/2.0)*(timeSignatureDenominator/4))
        else:
            print("bpmMultiplier not recognized")

        bpmMultiplier = bpmMultiplier*(timeSignatureDenominator/4)

        # End sketchy

        self._tempoSlider.min = minTempo
        self._tempoSlider.max = maxTempo

        self._metronomeStatusLabel.value ="Time Signature: "+str(timeSignatureNumerator)+"/"+str(timeSignatureDenominator)
        self._metronomeSubdivLabel.value = "Subdivision: "+str(subdivision)

    # More accurate sleep, thanks to StackOverflow 17499837. Takes CPU, but that is required to be accurate.
    def busy_wait(self, waitTime):
        current_time = time.time()
        while (time.time() < current_time+waitTime):
            pass

    def runProgramAction(self):
        
        global playing
        if Globals.programRunning and playing:
            print("Stopping Program")
            Globals.programRunning = False
            playing = False
            self._runProgram.label="Run Program"

        else:
            print("Running Program")
            Globals.programRunning = True
            playing = True

            # Start Metronome
            global metronomeSoundThread
            metronomeSoundThread = threading.Thread(name='metronomeSoundThread', target=Metronome.metronomeSound, args=(self,))
            metronomeSoundThread.setDaemon(True)
            metronomeSoundThread.start()

            self._runProgram.label="Stop Program"
    def _update_shown_axis(self):
        index = self._axis_list.selected_row_index
        if not index is None:
            axis = self._axis[index]
            if not axis is None:
                assert isinstance(axis, ControlAxis)

                # Get the hardware type from the name of the class
                self._axis_hw_type.value = type(axis).__name__

                # Update the minimum box
                if not self._min.visible:
                    self._min.visible = True
                self._min.label = "Minimum ({})".format(axis.get_units())
                self._events = False
                self._min.value = axis.get_min()
                self._events = True

                # Update the maximum box
                if not self._max.visible:
                    self._max.visible = True
                self._max.label = "Maximum ({})".format(axis.get_units())
                self._events = False
                self._max.value = axis.get_max()
                self._events = True

                # Update the norm_minimum box
                if not self._norm_min.visible:
                    self._norm_min.visible = True
                self._norm_min.label = "  0% ({})".format(axis.get_units())
                self._events = False
                self._norm_min.value = axis.get_norm_min()
                self._events = True

                # Update the norm_maximum box
                if not self._norm_max.visible:
                    self._norm_max.visible = True
                self._norm_max.label = "100% ({})".format(axis.get_units())
                self._events = False
                self._norm_max.value = axis.get_norm_max()
                self._events = True

                # Populate the special axis combo
                special_axis = ControlCombo(label="Special Axis")
                special_axis.add_item('', '')
                special_axis.add_item("X Axis", 'xaxis')
                special_axis.add_item("Y Axis", 'yaxis')

                if axis == self._xaxis:
                    special_axis.value = 'xaxis'
                elif axis == self._yaxis:
                    special_axis.value = 'yaxis'

                def axis_changed(_):
                    """
                    Called when axis changed
                    """
                    if special_axis.value == 'xaxis':
                        self._xaxis = axis
                        if self._yaxis == axis:
                            self._yaxis = None
                    elif special_axis.value == 'yaxis':
                        self._yaxis = axis
                        if self._xaxis == axis:
                            self._xaxis = None
                    else:
                        if self._xaxis == axis:
                            self._xaxis = None
                        if self._yaxis == axis:
                            self._yaxis = None

                    self._send_events()

                print("Making Special Combo")
                special_axis.current_index_changed_event = axis_changed

                self._events = False
                self._special_axis.value = None
                self._special_axis.value = special_axis
                self._events = True

                # Update the custom config GUI
                self._axis_custom.value = axis.get_custom_config()

                self._save_button.visible = True
            else:
                self._axis_hw_type.value = ''
                self._min.visible = False
                self._max.visible = False
                self._norm_min.visible = False
                self._norm_max.visible = False
                self._special_axis.value = None
                self._axis_custom.value = None
                self._save_button.visible = False
        else:
            self._axis_hw_type.value = ''
            self._min.visible = False
            self._max.visible = False
            self._norm_min.visible = False
            self._norm_max.visible = False
            self._special_axis.value = None
            self._axis_custom.value = None
            self._save_button.visible = False
Esempio n. 30
0
class AuxJog(BaseWidget):
    """
    A Widget to jog aux axis
    """

    _last_set_value = 0
    label = ""

    def __init__(self, axis):
        super().__init__("Aux Jog")

        assert isinstance(axis, ControlAxis)

        self._axis = axis

        self.label = axis.get_name()

        self._value_field = ControlText(label="Target",
                                        default=str(axis.get_value()))

        self._set_button = ControlButton(label="Go to target")
        self._set_button.value = self._update_value

        self._saved_point_field = ControlCombo(label="Saved Point")

        self._saved_point_button = ControlButton(label="Go to saved point")
        self._saved_point_button.value = self._update_saved_point

        self._current_field = ControlLabel(
            label="Current Value ({})".format(axis.get_units()))

        self.setFrameShape(QFrame.StyledPanel)
        self.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed))

        self.set_margin(10)

        self.formset = [("info:{0} ({1}):".format(axis.get_name(),
                                                  axis.get_units()), '', '',
                         '_current_field'), ('_value_field', '_set_button'),
                        ('_saved_point_field', '_saved_point_button')]

    def _update_value(self):
        value = self._value_field.value
        self._axis.goto_value(value)

    def _update_saved_point(self):
        self._axis.goto_value(self._saved_point_field.value)

    def update_events(self, events):
        #print("Aux Event:", events)
        if 'saved_points' in events:
            self._saved_point_field.clear()
            for key, value in events['saved_points'].items():
                self._saved_point_field += (key, key)

    def timer_update(self):
        self._current_field.value = "{0:.5f}".format(
            self._axis.get_current_value())

        if self._axis.get_string_value() != self._last_set_value:
            self._value_field.value = self._axis.get_string_value()
            self._last_set_value = self._axis.get_string_value()
Esempio n. 31
0
class ImportWindow(BaseWidget):

	def __init__(self, timeline=None):
		super(ImportWindow, self).__init__('Import file', parent_win=timeline)
		self.setContentsMargins(10, 10, 10, 10)
		self._timeline = timeline

		# Definition of the forms fields
		self._filetype = ControlCombo('Please select the type of file you would like to import:')
		self._importButton = ControlButton('Import')
		self._panel = ControlEmptyWidget('Panel')
		self._file = ControlFile('File to import')

		self._panel.value = self._file
		self._filetype.add_item('Events file', 0)
		self._filetype.add_item('Graph file', 1)
		self._filetype.add_item('Bonsai events file', 2)

		self._formset = [
			('_filetype', ' '),
			'_panel',
			(' ', '_importButton'), ' ']

		self._filetype.changed_event = self.__fileTypeChanged
		self._importButton.value = self.__importData

		from pyforms.gui.dialogs.csv_parser import CsvParserDialog
		self._graphCsvParserDlg = CsvParserDialog()
		self._graphCsvParserDlg.xField.label = "Value column"
		self._graphCsvParserDlg.yField.hide()
		self._graphCsvParserDlg.zField.hide()
		self._graphCsvParserDlg.loadButton.hide()

		self._bonsaiImportDlg = BonsaiImportFileDlg()

	def __fileTypeChanged(self):
		if self._filetype.value == 0:
			self._panel.value = self._file

		elif self._filetype.value == 1:
			self._panel.value = self._graphCsvParserDlg

		elif self._filetype.value == 2:
			self._panel.value = self._bonsaiImportDlg

	def __importData(self):
		if self._filetype.value == 0:
			separator = ','
			with open(self._file.value, 'rU') as csvfile:
				line = csvfile.readline()
				if ";" in line:
					separator = ';'
			with open(self._file.value, 'rU') as csvfile:
				csvfile = csv.reader(csvfile, delimiter=separator)
				self._timeline._time.import_csv(csvfile)

		elif self._filetype.value == 1:
			self._timeline._time.importchart_csv(self._graphCsvParserDlg)
			self._timeline.show_graphs_properties()

		elif self._filetype.value == 2:
			with open(self._bonsaiImportDlg._file.value, 'rU') as csvfile:
				values = []
				pointEventValues = []
				csvfile = csv.reader(csvfile, delimiter=' ')
				for row in csvfile:  # strip Start/End word from all events names which are not PointEven
					try:
						timestr = row[1].rstrip('0')
						cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S.%f")
					except:
						timestr = row[1]
						cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S")

					seconds = (cvttime - datetime.datetime(1900, 1, 1)).total_seconds()
					frame = int(round(self._bonsaiImportDlg._fps.value * seconds))

					if row[2] == "PointEvent":
						eventtype = row[0]
						pointEventValues.append([eventtype, frame, row[2]])
					else:
						if row[0].startswith('Start'):
							eventtype = row[0][len('Start'):]  # strip Start word from the beginning
						else:
							eventtype = row[0][len('End'):]  # strip End word from the beginning
						values.append([eventtype, frame, row[2]])

				values = sorted(values, key=lambda x: (x[0].capitalize(), x[1]))
				pointEventValues = sorted(pointEventValues, key=lambda x: (x[0].capitalize(), x[1]))
				ntracks = len(set([x[0] for x in values])) + 1

				# collapse
				events = []
				eventsTypes = {}  # Events names
				currentTrack = 0
				for index in range(0, len(pointEventValues)):
					pointEventValue = pointEventValues[index]
					eventsTypes[pointEventValue[0]] = currentTrack
					self._timeline.addPeriod([pointEventValue[1], pointEventValue[1] + 50, pointEventValue[0]], track=currentTrack)

				currentTrack = 1

				for index in range(0, len(values), 2):
					row0 = values[index]
					row1 = values[index + 1]

					if row0[0] not in eventsTypes:
						eventsTypes[row0[0]] = currentTrack
						track = currentTrack
						currentTrack += 1
					else:
						track = eventsTypes[row0[0]]

					self._timeline.addPeriod([row0[1], row1[1], row0[0]], track=track)

		self._timeline.repaint()
		self._timeline._time.repaint()
		self.close()  # pylint: disable=no-member


	def import_chart(self, filename, frame_col=0, val_col=1):
		self._filetype.value = 1            
		self._graphCsvParserDlg.filename    = filename
		self._graphCsvParserDlg.frameColumn = frame_col
		self._graphCsvParserDlg.xColumn     = val_col
Esempio n. 32
0
class ImportWindow(BaseWidget):
    def __init__(self, timeline=None):
        super(ImportWindow, self).__init__('Import file', parent_win=timeline)
        self.setContentsMargins(10, 10, 10, 10)
        self._timeline = timeline

        # Definition of the forms fields
        self._filetype = ControlCombo(
            'Please select the type of file you would like to import:')
        self._importButton = ControlButton('Import')
        self._panel = ControlEmptyWidget('Panel')
        self._file = ControlFile('File to import')

        self._panel.value = self._file
        self._filetype.add_item('Events file', 0)
        self._filetype.add_item('Graph file', 1)
        self._filetype.add_item('Bonsai events file', 2)
        self._filetype.add_item('Bonsai events file (old format)', 3)

        self._formset = [('_filetype', ' '), '_panel', (' ', '_importButton'),
                         ' ']

        self._filetype.changed_event = self.__fileTypeChanged
        self._importButton.value = self.__importData

        from pyforms.gui.dialogs.csv_parser import CsvParserDialog
        self._graphCsvParserDlg = CsvParserDialog()
        self._graphCsvParserDlg.xField.label = "Value column"
        self._graphCsvParserDlg.yField.hide()
        self._graphCsvParserDlg.zField.hide()
        self._graphCsvParserDlg.loadButton.hide()

        self._bonsai_import_dlg = BonsaiImportFileDlg()

    def __fileTypeChanged(self):
        if self._filetype.value == 0:
            self._panel.value = self._file

        elif self._filetype.value == 1:
            self._panel.value = self._graphCsvParserDlg

        elif self._filetype.value in [2, 3]:
            self._panel.value = self._bonsai_import_dlg

    def __importData(self):
        if self._filetype.value == 0:
            separator = ','
            with open(self._file.value, 'rU') as csvfile:
                line = csvfile.readline()
                if ";" in line:
                    separator = ';'
            with open(self._file.value, 'rU') as csvfile:
                csvfile = csv.reader(csvfile, delimiter=separator)
                self._timeline._time.import_csv(csvfile)

        elif self._filetype.value == 1:
            self._timeline._time.importchart_csv(self._graphCsvParserDlg)
            self._timeline.show_graphs_properties()

        elif self._filetype.value == 2:
            self.__import_bonsai_events()
        elif self._filetype.value == 3:
            self.__import_bonsai_events_oldformat()

        self._timeline.repaint()
        self._timeline._time.repaint()
        self.close()  # pylint: disable=no-member

    def import_chart(self, filename, frame_col=0, val_col=1):
        self._filetype.value = 1
        self._graphCsvParserDlg.filename = filename
        self._graphCsvParserDlg.frameColumn = frame_col
        self._graphCsvParserDlg.xColumn = val_col

    def __import_bonsai_events(self):

        with open(self._bonsai_import_dlg._file.value, 'rU') as csvfile:
            values = []
            pointEventValues = []
            csvfile = csv.reader(csvfile, delimiter=' ')
            for row in csvfile:  # strip Start/End word from all events names which are not PointEven

                try:
                    timestr = row[1].rstrip('0')
                    cvttime = datetime.datetime.strptime(
                        timestr, "%H:%M:%S.%f")
                except:
                    timestr = row[1]
                    try:
                        print(timestr)
                        cvttime = datetime.datetime.strptime(
                            timestr, "%H:%M:%S")
                    except:
                        timestr = timestr.replace('T', ' ')
                        print(timestr)
                        cvttime = dateutil.parser.parse(timestr)

                seconds = (cvttime -
                           datetime.datetime(1900, 1, 1)).total_seconds()
                frame = int(round(self._bonsai_import_dlg._fps.value *
                                  seconds))

                if row[2] == "PointEvent":
                    eventtype = row[0]
                    pointEventValues.append([eventtype, frame, row[2]])
                else:
                    if row[0].startswith('Start'):
                        eventtype = row[0][len(
                            'Start'):]  # strip Start word from the beginning
                    else:
                        eventtype = row[0][len(
                            'End'):]  # strip End word from the beginning
                    values.append([eventtype, frame, row[2]])

            values = sorted(values, key=lambda x: (x[0].capitalize(), x[1]))
            pointEventValues = sorted(pointEventValues,
                                      key=lambda x: (x[0].capitalize(), x[1]))
            ntracks = len(set([x[0] for x in values])) + 1

            # collapse
            events = []
            eventsTypes = {}  # Events names
            currentTrack = 0
            for index in range(0, len(pointEventValues)):
                pointEventValue = pointEventValues[index]
                eventsTypes[pointEventValue[0]] = currentTrack
                self._timeline.add_period([
                    pointEventValue[1], pointEventValue[1] + 50,
                    pointEventValue[0]
                ],
                                          row=currentTrack)

            currentTrack = 1

            for index in range(0, len(values), 2):
                row0 = values[index]
                row1 = values[index + 1]

                if row0[0] not in eventsTypes:
                    eventsTypes[row0[0]] = currentTrack
                    track = currentTrack
                    currentTrack += 1
                else:
                    track = eventsTypes[row0[0]]

                self._timeline.add_period([row0[1], row1[1], row0[0]],
                                          row=track)

    def __import_bonsai_events_oldformat(self):

        with open(self._bonsai_import_dlg._file.value, 'rU') as csvfile:
            windows_events = []
            points_events = []
            first_date = None

            for row in csvfile:
                row = row[:-1]  #remove the newline character

                if row.endswith('WindowClosing'):
                    split = row.rfind(' ')
                    #eventtype = row[-split:]
                    eventtype = 'end'
                    timestr = row[split - 33:split]
                    eventname = row[4:split - 33]
                elif row.endswith('PointEvent'):
                    split = row.rfind(' ')
                    eventtype = row[split + 1:]
                    timestr = row[split - 33:split]
                    eventname = row[:split - 33]
                else:
                    eventtype = 'start'
                    timestr = row[-33:]
                    eventname = row[6:-33]

                cvttime = dateutil.parser.parse(timestr.replace('T', ' '))
                cvttime = cvttime.replace(tzinfo=None)
                if first_date is None: first_date = cvttime

                seconds = (cvttime - first_date).total_seconds()
                frame = int(round(self._bonsai_import_dlg._fps.value *
                                  seconds))

                if eventtype == 'PointEvent':
                    points_events.append([eventtype, frame, eventname])
                else:
                    if eventtype == 'start':
                        windows_events.append([eventtype, frame, eventname])
                    elif eventtype == 'end':
                        windows_events.append([eventtype, frame, eventname])

            windows_events = sorted(windows_events,
                                    key=lambda x:
                                    (x[0][0].capitalize(), x[0][1]))
            points_events = sorted(points_events,
                                   key=lambda x: (x[0].capitalize(), x[1]))
            ntracks = len(set([x[0][1] for x in windows_events])) + 1

            # collapse
            events = []
            events_types = {}  # Events names
            current_track = 0
            for index in range(0, len(points_events)):
                eventtype, frame, eventname = points_events[index]
                events_types[eventname] = current_track
                self._timeline.add_period([frame, frame + 2, eventname],
                                          row=current_track)

            current_track = 1

            for i in range(0, len(windows_events), 2):
                start = windows_events[i]
                end = windows_events[i + 1]
                eventtype, frame_begin, eventname = start
                _, frame_end, _ = end

                if eventname not in events_types:
                    events_types[eventname] = current_track
                    track = current_track
                    current_track += 1
                else:
                    track = events_types[eventname]

                print('add', eventname, track, frame_begin, frame_end)
                self._timeline.add_period([frame_begin, frame_end, eventname],
                                          row=track)
class VehTrajAnalytics(BaseWidget):
    def __init__(self):

        super(VehTrajAnalytics, self).__init__('Vehicle Trajectory Analytics')

        #Definition of the forms fields
        self._firstname = ControlText('First name', 'Default value')
        self._middlename = ControlText('Middle name')
        self._lastname = ControlText('Lastname name')
        self._fullname = ControlText('Full name')
        self._button = ControlButton('Press this button')
        self._button2 = ControlButton('Press this button2')

        self._outputDir = ControlDir("Output Directory")
        self._inputFile = ControlFile("Input Trajectory File")

        self._load = ControlButton("Load")
        self._save = ControlButton("Save")

        self._vehicleId = ControlCombo("Vehicle id")
        self._time = ControlCombo("Time(sec)")
        self._positionX = ControlCombo("PositionX (feet)")
        self._positionY = ControlCombo("PositionY (feet)")

        # Instrumented vehicle trajectories
        self._radarRange = ControlCombo("Radar range (feet)")
        self._radarAngle = ControlCombo("Radar angle (degrees)")
        self._centerline = ControlFile("CenterlineFile")

        #all traffic stream
        self._lane = ControlCombo("Lane")
        self._vLength = ControlCombo("Vehicle Length")
        self._distanceAlong = ControlCombo("Distance Along Corridor")

        #Define the button action
        self._button.value = self.__buttonAction

        self.data = None
        self.outFolder = None

        self.formset = [[('_inputFile', '_load'), '_vehicleId', "_time",
                         '_positionX', "_positionY", "_distanceAlong"], "=", {
                             'All Vehicle Trajectories': ['_lane', '_vLength'],
                             'Instrumented Vehicle Trajectories':
                             ['_radarAngle', '_radarRange']
                         }, '=', ('_outputDir', '_save')]

        self._load.value = self.__loadAction
        self._save.value = self.__saveAction

    def __buttonAction(self):
        """Button action event"""
        self._fullname.value = self._firstname.value +" "+ self._middlename.value + \
        " "+ self._lastname.value

    def __loadAction(self):

        fileName = self._inputFile.value

        if fileName.endswith("hdf"):
            self.data = pd.read_hdf(fileName, 'trajectories')
            self.vt = VTAnalytics.readModelData(fileName,
                                                start_time=start_time,
                                                end_time=end_time)
        else:
            #self.data = pd.read_csv(fileName)
            self.vt = VTAnalytics.readNGISIMData(fileName,
                                                 start_time=start_time,
                                                 end_time=end_time)
            self.data = self.vt.df

        columns = list(self.data.columns)

        self.__initializeBoxes2(columns)

    def __saveAction(self):

        print('done reading the data')

        writer = pd.ExcelWriter(
            os.path.join(self._outputDir.value, 'tables.xlsx'))

        PAGE_SIZE = (1000, 792.0)
        pdfReport = PdfReport(
            os.path.join(self._outputDir.value, 'report.pdf'), PAGE_SIZE)

        fig, ax = plt.subplots(figsize=(10, 8), dpi=100)
        self.vt.plotSpeedVsDensity(fig, ax, max_density=280)
        fig.savefig(os.path.join(self._outputDir.value, "SpeedVsDensity.png"),
                    dpi=100)
        pdfReport.addChart2(
            os.path.join(self._outputDir.value, "SpeedVsDensity.png"),
            'SpeedVsDensity')

        fig, ax = plt.subplots(figsize=(10, 8), dpi=100)
        self.vt.plotLCR(fig, laneChangeType='enter')
        fig.savefig(os.path.join(self._outputDir.value, "LCR.png"), dpi=100)
        pdfReport.addChart2(os.path.join(self._outputDir.value, "LCR.png"),
                            "LaneChangeRate")

        fig, ax = plt.subplots(figsize=(10, 8), dpi=100)
        self.vt.plotSpeedVsDensityByLane(fig,
                                         plot_mean=True,
                                         dot_color='blue',
                                         alpha=0.4)
        out_fileName = os.path.join(self._outputDir.value,
                                    "SpeedVsDensityByLane.png")
        fig.savefig(out_fileName, dpi=100)
        pdfReport.addChart2(out_fileName, "SpeedVsDensityByLane")

        fig, ax = plt.subplots(figsize=(10, 8))
        spdDist = self.vt.plotSpeedDistribution(ax)
        out_fileName = os.path.join(self._outputDir.value,
                                    "SpeedDistribution.png")
        fig.savefig(out_fileName, dpi=100)
        pdfReport.addChart2(out_fileName, "SpeedDistribution")
        spdDist.to_excel(writer, 'SpeedDistribution')

        fig, ax = plt.subplots(figsize=(10, 8))
        accDist = self.vt.plotAccelerationDistribution(ax)
        out_fileName = os.path.join(self._outputDir.value,
                                    "AccelerationDistribution.png")
        fig.savefig(out_fileName, dpi=100)
        pdfReport.addChart2(out_fileName, "AccelerationDistribution")
        accDist.to_excel(writer, 'AcclerationDistribution')

        fig, ax = plt.subplots(figsize=(10, 8))
        jerk = self.vt.getAccelerationJerk()
        jerkDist = self.vt.plotJerkDistribution(jerk, ax)
        out_fileName = os.path.join(self._outputDir.value,
                                    "AccelerationJerkDistribution.png")
        fig.savefig(out_fileName, dpi=100)
        pdfReport.addChart2(out_fileName, "AccelerationJerkDistribution")
        jerkDist.to_excel(writer, 'JerkDistribution')

        armsDist = self.vt.getARMSDistribution()
        fig, ax = plt.subplots(figsize=(10, 8))
        self.vt.plotARMS(armsDist, ax)
        out_fileName = os.path.join(self._outputDir.value,
                                    "AccelerationRootMeanSquareError.png")
        fig.savefig(out_fileName, dpi=100)
        pdfReport.addChart2(out_fileName, "AccelerationRootMeanSquareError")
        armsDist.to_excel(writer, 'ARMS')

        writer.save()

        for i in range(1, 8):
            fig, ax = plt.subplots(figsize=(10, 8), dpi=100)
            self.vt.plotAllTrajectories(fig,
                                        ax,
                                        i,
                                        np.datetime64('2005-04-13 17:00:00'),
                                        np.datetime64('2005-04-13 17:10:00'),
                                        0,
                                        1000,
                                        point_size=0.5,
                                        title="All trajectories for lane %d" %
                                        i)
            out_fileName = os.path.join(self._outputDir.value,
                                        "All_trajectories_lane_%d.png" % i)
            fig.savefig(out_fileName, dpi=100)
            pdfReport.addChart2(out_fileName,
                                "All trajectories for lane %d" % i)

        pdfReport.write()

    def __saveActionOLD(self):

        fig, ax = plt.subplots(figsize=(10, 8))
        self.vt.plotSpeedVsDensity(fig, ax, max_density=280)
        fig.savefig(os.path.join(self._outputDir.value, "graph1.pdf"), dpi=100)

        fig, ax = plt.subplots(figsize=(10, 8))
        self.vt.plotLCR(fig, laneChangeType='enter')
        fig.savefig(os.path.join(self._outputDir.value, "graph2.pdf"), dpi=100)

        fig, ax = plt.subplots(figsize=(10, 8))
        self.vt.plotSpeedVsDensityByLane(fig,
                                         plot_mean=True,
                                         dot_color='blue',
                                         alpha=0.4)
        fig.savefig(os.path.join(self._outputDir.value, "graph3.pdf"), dpi=100)

        for i in range(1, 8):
            fig, ax = plt.subplots(figsize=(10, 8))
            self.vt.plotAllTrajectories(fig,
                                        ax,
                                        i,
                                        np.datetime64('2005-04-13 17:00:00'),
                                        np.datetime64('2005-04-13 17:10:00'),
                                        0,
                                        1000,
                                        point_size=0.5)
            fig.savefig(os.path.join(self._outputDir.value,
                                     "graph%d.pdf" % (3 + i)),
                        dpi=100)

        #file_list = [os.path.join(self._outputDir.value, "test.pdf"),
        # os.path.join(self._outputDir.value, "test2.pdf")]

        file_list = [
            os.path.join(self._outputDir.value, "graph%d.pdf" % i)
            for i in range(1, 5)
        ]

        out_file = os.path.join(self._outputDir.value, "trajReport.pdf")

        combinePdfFiles(file_list, out_file)

    def __initializeBoxes2(self, columns):

        for i, col in enumerate(columns):

            self._vehicleId.add_item(col, i)
            self._time.add_item(col, i)
            self._positionX.add_item(col, i)
            self._positionY.add_item(col, i)
            self._lane.add_item(col, i)
            self._vLength.add_item(col, i)
            self._radarRange.add_item(col, i)
            self._radarAngle.add_item(col, i)
            self._distanceAlong.add_item(col, i)

        #self.__initializeBoxes()

    def __initializeBoxes(self):

        self._vehicleId.add_item("One", '1')
        self._vehicleId.add_item("Two", '2')
        self._vehicleId.add_item("Three", '3')

        self._time.add_item("One", '1')
        self._time.add_item("Two", '2')
        self._time.add_item("Three", '3')

        self._positionX.add_item("One", '1')
        self._positionX.add_item("Two", '2')
        self._positionX.add_item("Three", '3')

        self._positionY.add_item("One", '1')
        self._positionY.add_item("Two", '2')
        self._positionY.add_item("Three", '3')

        self._lane.add_item("One", '1')
        self._lane.add_item("Two", '2')
        self._lane.add_item("Three", '3')

        self._vLength.add_item("One", '1')
        self._vLength.add_item("Two", '2')
        self._vLength.add_item("Three", '3')

    def __saveResults(self):

        fig, ax = plt.subplots(figsize=(15, 10))
        self.data.speed.hist(ax=ax,
                             bins=np.arange(0, 71, 1),
                             figsize=(15, 10),
                             width=0.8,
                             color='grey',
                             alpha=0.5)
        ax.set_title("Distribution of instantaneous speeds", fontsize=18)
        ax.set_xlabel("speed (mph)", fontsize=16)
        fig.tight_layout()
        fig.savefig(os.path.join(self.outFolder, 'test.png'))
    def __init__(self):

        super(VehTrajAnalytics, self).__init__('Vehicle Trajectory Analytics')

        #Definition of the forms fields
        self._firstname = ControlText('First name', 'Default value')
        self._middlename = ControlText('Middle name')
        self._lastname = ControlText('Lastname name')
        self._fullname = ControlText('Full name')
        self._button = ControlButton('Press this button')
        self._button2 = ControlButton('Press this button2')

        self._outputDir = ControlDir("Output Directory")
        self._inputFile = ControlFile("Input Trajectory File")

        self._load = ControlButton("Load")
        self._save = ControlButton("Save")

        self._vehicleId = ControlCombo("Vehicle id")
        self._time = ControlCombo("Time(sec)")
        self._positionX = ControlCombo("PositionX (feet)")
        self._positionY = ControlCombo("PositionY (feet)")

        # Instrumented vehicle trajectories
        self._radarRange = ControlCombo("Radar range (feet)")
        self._radarAngle = ControlCombo("Radar angle (degrees)")
        self._centerline = ControlFile("CenterlineFile")

        #all traffic stream
        self._lane = ControlCombo("Lane")
        self._vLength = ControlCombo("Vehicle Length")
        self._distanceAlong = ControlCombo("Distance Along Corridor")

        #Define the button action
        self._button.value = self.__buttonAction

        self.data = None
        self.outFolder = None

        self.formset = [[('_inputFile', '_load'), '_vehicleId', "_time",
                         '_positionX', "_positionY", "_distanceAlong"], "=", {
                             'All Vehicle Trajectories': ['_lane', '_vLength'],
                             'Instrumented Vehicle Trajectories':
                             ['_radarAngle', '_radarRange']
                         }, '=', ('_outputDir', '_save')]

        self._load.value = self.__loadAction
        self._save.value = self.__saveAction
class SensorTab(BaseWidget):
    """
    Tab for sensors
    Shows a drop down with all subclasses of Sensor
    imported anywhere into this program

    When one is selected, it creates an instance of that sensor
    and shows the custom config GUI for that Sensor.
    """

    _sensor = None
    _timer = QTimer()

    def __init__(self, update_function=None):
        super().__init__("Output Tab")

        # The update function will be called when the selected sensor changes
        # to fire the 'sensor' event
        self._update_function = update_function

        self._device_select = ControlCombo(label="Sensor")

        self._custom = ControlEmptyWidget()

        self._device_select.changed_event = self._on_device_change

        self._device_select.add_item('None', None)

        self._output = ControlList()

        self._live = ControlCheckBox(label="Live Output")
        self._live.changed_event = self._on_live

        for class_type in Sensor.__subclasses__():
            self._device_select.add_item(class_type.__name__, class_type)

    def update_events(self, events):
        """
        Updates the events
        """
        if isinstance(self._sensor, Sensor):
            self._sensor.update_events(events)

    def _on_device_change(self):
        device = self._device_select.value
        if callable(device):
            self._sensor = device()
            self._custom.value = self._sensor.get_custom_config()
        else:
            self._sensor = None
            self._custom.value = None
            #print("Not Subclass")

        if callable(self._update_function):
            self._update_function({'sensor': self._sensor})

    def _on_live(self):
        if self._live.value:
            if isinstance(self._sensor, Sensor):
                self._sensor.begin_live_data()
                self._output.horizontal_headers = self._sensor.get_live_headers(
                )
                self._timer.timeout.connect(self._update_sensor)
                self._timer.start(100)
        else:
            self._timer.stop()
            if isinstance(self._sensor, Sensor):
                self._sensor.stop_live_data()

    def _update_sensor(self):
        if isinstance(self._sensor, Sensor):
            self._output += self._sensor.get_live_data()
            self._output.tableWidget.scrollToBottom()
Esempio n. 36
0
    def __init__(self):
        super(MultipleBlobDetection, self).__init__(
            'Multiple Blob Detection')

        # Definition of the forms fields
        self._videofile = ControlFile('Video')
        self._outputfile = ControlText('Results output file')

        self._threshold_box = ControlCheckBox('Threshold')
        self._threshold = ControlSlider('Binary Threshold', 114, 0, 255)

        self._roi_x_min = ControlSlider('ROI x top', 0, 0, 1000)
        self._roi_x_max = ControlSlider('ROI x bottom', 1000, 0, 1000)

        self._roi_y_min = ControlSlider('ROI y left', 0, 0, 1000)
        self._roi_y_max = ControlSlider('ROI y right', 1000, 0, 1000)

        # self._blobsize = ControlSlider('Minimum blob size', 100, 100, 2000)
        self._player = ControlPlayer('Player')
        self._runbutton = ControlButton('Run')
        self._start_frame = ControlText('Start Frame')
        self._stop_frame = ControlText('Stop Frame')

        self._color_list = ControlCombo('Color channels')
        self._color_list.add_item('Red Image Channel', 2)
        self._color_list.add_item('Green Image Channel', 1)
        self._color_list.add_item('Blue Image Channel', 0)

        self._clahe = ControlCheckBox('CLAHE      ')
        self._dilate = ControlCheckBox('Morphological Dilation')
        self._dilate_type = ControlCombo('Dilation Kernel Type')
        self._dilate_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._dilate_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._dilate_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._dilate_size = ControlSlider('Dilation Kernel Size', 3, 1, 10)

        self._erode = ControlCheckBox('Morphological Erosion')
        self._erode_type = ControlCombo('Erode Kernel Type')
        self._erode_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._erode_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._erode_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._erode_size = ControlSlider('Erode Kernel Size', 5, 1, 10)

        self._open = ControlCheckBox('Morphological Opening')
        self._open_type = ControlCombo('Open Kernel Type')
        self._open_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._open_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._open_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._open_size = ControlSlider('Open Kernel Size', 19, 1, 40)

        self._close = ControlCheckBox('Morphological Closing')
        self._close_type = ControlCombo('Close Kernel Type')
        self._close_type.add_item('RECTANGLE', cv2.MORPH_RECT)
        self._close_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE)
        self._close_type.add_item('CROSS', cv2.MORPH_CROSS)
        self._close_size = ControlSlider('Close Kernel Size', 19, 1, 40)

        self._LoG = ControlCheckBox('LoG - Laplacian of Gaussian')
        self._LoG_size = ControlSlider('LoG Kernel Size', 30, 1, 60)

        self._progress_bar = ControlProgress('Progress Bar')

        # Define the function that will be called when a file is selected
        self._videofile.changed_event = self.__videoFileSelectionEvent
        # Define the event that will be called when the run button is processed
        self._runbutton.value = self.__runEvent
        # Define the event called before showing the image in the player
        self._player.process_frame_event = self.__processFrame

        # Define the organization of the Form Controls
        self.formset = [
            ('_videofile', '_outputfile'),
            ('_start_frame', '_stop_frame'),
            ('_color_list', '_clahe', '_roi_x_min', '_roi_y_min'),
            ('_threshold_box', '_threshold', '_roi_x_max', '_roi_y_max'),
            ('_dilate', '_erode', '_open', '_close'),
            ('_dilate_type', '_erode_type', '_open_type', '_close_type'),
            ('_dilate_size', '_erode_size', '_open_size', '_close_size'),
            ('_LoG', '_LoG_size'),
            '_runbutton',
            '_progress_bar',
            '_player'
        ]