def load_totals_data(self, initial_balances, expenditures_by_type,
                         current_balances):
        if expenditures_by_type is not None and expenditures_by_type != []:
            total_spending = 0
            for row in expenditures_by_type:
                total_spending += row[1]
            spending_text = TableWidget.format_as_currency(total_spending)
            self.totals_table.set_value(spending_text, 0, 1)
        else:
            self.totals_table.set_value("-", 0, 1)

        if initial_balances is not None and initial_balances != []:
            total_initial_balance = 0
            for balance in initial_balances:
                total_initial_balance += balance[2]
            initial_text = TableWidget.format_as_currency(
                total_initial_balance)
            self.totals_table.set_value(initial_text, 0, 0)
        else:
            self.totals_table.set_value("-", 0, 0)

        if current_balances is not None and current_balances != []:
            total_current_balance = 0
            for balance in current_balances:
                total_current_balance += balance[2]
            current_text = TableWidget.format_as_currency(
                total_current_balance)
            self.totals_table.set_value(current_text, 0, 2)
        else:
            self.totals_table.set_value("-", 0, 2)
 def _restore_windows_ui(self, windows):
     for window in windows:
         widget = TableWidget(self.db, window.title, window.sql_select,
                              self.edit_update_ui)
         sub_window = self.mdiArea.addSubWindow(widget)
         sub_window.setGeometry(window.x, window.y, window.width,
                                window.height)
         widget.splitter.setSizes(window.sizes)
         widget.show()
 def setup_balance_table(self):
     # invert_axis is True because the data will be added in cols
     self.balance_table = TableWidget(self, 2, self.field_count, table_name=self.table_widget_name,
                                      invert_axis=True, column_widths=default_field_col_widths,
                                      head_font=self.head_font, entry_font=self.entry_font,
                                      header_widths=default_header_widths)
     self.balance_table.add_listener(self)
     self.balance_table.set_header_values(['Source', 'Amount'])
     self.balance_table.grid(row=1, columnspan=2)
 def load_spending_by_category(self):
     self.category_table = TableWidget(self,
                                       2,
                                       self.field_count,
                                       head_font=default_table_head_font,
                                       entry_font=default_entry_font,
                                       entry_justify_list=["right", "left"],
                                       head_justify_list=["right", "left"])
     self.category_table.hide_config_buttons()
     self.category_table.set_header_values(['Category', 'Amount'])
     self.category_table.grid(row=0, column=2)
 def load_total_amounts(self):
     self.totals_table = TableWidget(
         self,
         3,
         1,
         entry_font=default_entry_font,
         entry_justify=["left"],
         head_justify_list=["right", "right", "right"],
         invert_axis=True)
     self.totals_table.hide_config_buttons()
     self.totals_table.set_header_values(
         ["Initial Total", "Expenditure Total", "Current Total"])
     self.totals_table.grid(row=0, column=0)
Exemple #6
0
 def setup_expenditure_table(self):
     # adds the expenditure table
     self.expenditure_table = TableWidget(
         self,
         3,
         self.field_count + 1,
         table_name="expenditures",
         invert_axis=False,
         column_widths=default_field_col_widths,
         head_font=self.head_font,
         entry_font=self.entry_font)
     self.expenditure_table.hide_config_buttons()
     self.expenditure_table.add_listener(self)
     self.expenditure_table.set_header_values(['Amount', 'Name', 'Type'])
     self.expenditure_table.grid(row=1, columnspan=2)
 def set_balances(self, balance_matrix: [[]]):
     # sets the values in the balances table given the balance matrix
     table = []
     for row_index in range(len(balance_matrix)):
         values = [balance_matrix[row_index][1],
                   TableWidget.format_as_currency(balance_matrix[row_index][2])]
         table.append(values)
     self.balance_table.load_table_data(table)
     self.expenditures_set = True
Exemple #8
0
 def maybe_show_item(self, item, _=None):
     if item.parent() is None:
         return  # Ignore top-level items
     kind = item.parent().text(0).lower()[:-1]
     name = item.text(0)
     sub_window = self.findSubWindow(name)
     if sub_window is None:
         if kind in {'table', 'view'}:
             sql = self.db.select_make(kind, name)
             widget = TableWidget(self.db, f'{name} ({kind})', sql,
                                  self.edit_update_ui)
             sub_window = self.mdiArea.addSubWindow(widget)
             widget.show()
         else:
             # TODO create a new QueryWidget or TriggerEditWidget etc.
             print('maybe_show_item', kind, name)  # TODO
     if sub_window is not None:
         self.mdiArea.setActiveSubWindow(sub_window)
Exemple #9
0
 def send_edit_to_database(self, table_name: str, row_index: int, values):
     # passes the row values to the listener to the DatabaseModel to be processed and stored in the database
     value_dict = {
         'amount': TableWidget.unformat_from_currency(values[0]),
         'name': values[1],
         'type': values[2]
     }
     self.table_edit_listener.send_edit_to_database(table_name, row_index,
                                                    value_dict)
Exemple #10
0
 def set_expenditures(self, expenditure_matrix: [[]]):
     # passes the label values to the table to be inserted into the labels
     self.expenditures_set = True
     table = []
     for row_index in range(len(expenditure_matrix)):
         values = [
             TableWidget.format_as_currency(
                 expenditure_matrix[row_index][1]),
             expenditure_matrix[row_index][2],
             expenditure_matrix[row_index][3]
         ]
         table.append(values)
     self.expenditure_table.load_table_data(table)
Exemple #11
0
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.resize(1624, 660)

        controlWidget = ControlWidget()
        monitorWidget = TableWidget()

        splitter = QSplitter()
        splitter.addWidget(controlWidget)
        splitter.addWidget(monitorWidget)
        splitter.setStretchFactor(0, 6)
        splitter.setStretchFactor(1, 10)

        self.setCentralWidget(splitter)
 def load_expenditure_data(self, expenditures_by_type: [[]]):
     if expenditures_by_type is not None and expenditures_by_type != []:
         labels = []
         values = []
         table = []
         for row_index in range(len(expenditures_by_type)):
             labels.append(expenditures_by_type[row_index][0])
             values.append(expenditures_by_type[row_index][1])
             table.append([
                 expenditures_by_type[row_index][0],
                 TableWidget.format_as_currency(
                     expenditures_by_type[row_index][1])
             ])
         self.category_table.load_table_data(table)
         self.pie_chart.construct_pie_chart(
             labels, values, text_col=self.pie_chart.label_text_col)
     else:
         self.category_table.clear_labels()
         self.pie_chart.construct_empty_chart()
Exemple #13
0
 def showEditBox(self):
     self.plotWin.editBox = QtGui.QDialog(self.plotWin, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
     self.plotWin.editBox.setWindowIcon(self.icons['BMDanalyseIcon']) 
     self.plotWin.editBox.setWindowTitle('BMDanalyse') 
     self.plotWin.editBox.setModal(True)
     # Add table
     layout = QtGui.QVBoxLayout()
     layout.setContentsMargins(10,10,10,10)
     layout.setSpacing(20)
     rows,cols = self.BMDchange.shape
     self.tableResults = TableWidget(rows,cols+1,self.plotWin.editBox)
     self.tableResults.verticalHeader().setVisible(True)
     # Set headers
     self.tableResults.setHorizontalHeaderItem(0,QtGui.QTableWidgetItem('Time'))
     for i in xrange(cols):
         header = QtGui.QTableWidgetItem(self.roiNames[i])
         self.tableResults.setHorizontalHeaderItem(i+1,header)
     # Add values to table
     self.fillEditBox()
     # Set layout
     layout.addWidget(self.tableResults)
     self.buttonsFrame  = QtGui.QFrame()
     self.buttonsLayout = QtGui.QHBoxLayout()
     self.buttonReset   = QtGui.QPushButton('Reset')
     self.buttonSave    = QtGui.QPushButton('Save')
     self.buttonClose   = QtGui.QPushButton('Cancel')
     self.buttonReset.setFixedWidth(50)
     self.buttonSave.setFixedWidth(50)
     self.buttonClose.setFixedWidth(50)
     self.buttonClose.clicked.connect(self.plotWin.editBox.close)
     self.buttonSave.clicked.connect(self.updateTableValues)
     self.buttonReset.clicked.connect(self.fillEditBox)
     self.buttonsLayout.addStretch(1)
     self.buttonsLayout.addWidget(self.buttonReset)
     self.buttonsLayout.addWidget(self.buttonSave)
     self.buttonsLayout.addWidget(self.buttonClose) 
     self.buttonsLayout.setContentsMargins(0,0,0,0) 
     self.buttonsFrame.setLayout(self.buttonsLayout)
     layout.addWidget(self.buttonsFrame)
     self.plotWin.editBox.setLayout(layout)
     self.plotWin.editBox.setMaximumSize(layout.sizeHint())
     self.plotWin.editBox.show()
Exemple #14
0
class SonicViewer(QtGui.QWidget):
	'''
	Has 3 plots stored in dict plots={'P':,'Sx':,'Sy':}
	has 3 modifuing parameter trees to operate data:
	Shift - shift the data along x axis
	Amplify
	'''
	mode = 'Contours'
	autoShift = {'P':True,'Sx':True,'Sy':True} # flag to match 0 and transmission time
	arrivalsPicked = False
	updateQTable = True # don't need 
	skipPlottingFAmpFlag = False
	skipPlottingFPhaseFlag = False
	def __init__(self,parent=None):
		self.parent = parent
		QtGui.QWidget.__init__(self,None,QtCore.Qt.WindowStaysOnTopHint)
		self.setupGUI()
		self.fWidget = TriplePlotWidget()
		self.phWidget = TriplePlotWidget()
		self.bWidget = BindingWidget(parents=[parent,self])
		self.isWidget = InterpretationSettingsWidget()
		self.data = {'P':{},'Sx':{},'Sy':{}}
		self.currentShifts = {'P':0,'Sx':0,'Sy':0}
		self.connectPlotButtons()
		self.gEdit = GradientEditorWidget()
		self.gw = self.gEdit.sgw
		self.fgw = self.gEdit.fgw
		self.pgw = self.gEdit.pgw
		# sel
		self.gw.restoreState(Gradients['hot'])
		self.fgw.restoreState(Gradients['hot'])
		self.pgw.restoreState(Gradients['hot'])
		self.allParameters = []
		self.yAxis = 'Track #'
		self.y = {}
		self.aTimes = {}
		# Connect everything
		self.showArrivalsButton.triggered.connect(self.parent.plotSonicData)
		self.pickArrivalsButton.triggered.connect(self.pickAllArrivals)
		self.invertYButton.triggered.connect(self.parent.plotSonicData)
		self.autoScaleButton.triggered.connect(self.autoScalePlots)
		self.editGradientsButton.triggered.connect(self.gEdit.show)
		self.gEdit.okButton.pressed.connect(self.parent.plotSonicData)
		self.showTableButton.triggered.connect(self.showTable)
		self.showForrierMagnitudeButton.triggered.connect(self.showFourrier)
		self.showForrierPhasesButton.triggered.connect(self.showPhases)
		# self.showArrivalsButton.triggered.connect(self.plot)
		self.waveFormButton.triggered.connect(lambda: self.setMode('WaveForms'))
		self.contourButton.triggered.connect(lambda: self.setMode('Contours'))
		self.moduliButton.triggered.connect(self.isWidget.show)
		self.isWidget.okButton.pressed.connect(self.runBindingWidget)
		self.filteringButton.triggered.connect(self.parent.plotSonicData)
		self.fWidget.sigRegionChanged.connect(self.plotFilteredData)
		# self.moduliButton.triggered.connect(self.bWidget.run)
		for wave in WaveTypes:
			self.params[wave].param('Arrival times').param('Mpoint').sigValueChanged.connect(self.recomputeArrivals)
			self.params[wave].param('Arrival times').param('BTA').sigValueChanged.connect(self.recomputeArrivals)
			self.params[wave].param('Arrival times').param('ATA').sigValueChanged.connect(self.recomputeArrivals)
			self.params[wave].param('Arrival times').param('DTA').sigValueChanged.connect(self.recomputeArrivals)
			self.plots[wave].vb.sigAltClick.connect(self.handPick)
	def handPick(self,sender,pos):
		if not self.handPickArrivalsButton.isChecked():
			return
		else: 
			# first find sender
			for wave in self.getActivePlots():
				if self.plots[wave].vb == sender:
					break
			# now wave is the type sent the signal
			# find closest sonic track to the y position
			closest = abs(self.y[wave] - pos.y()).argmin()
			self.aTimes[wave][closest] = pos.x()
			self.parent.plotSonicData()

		
	def plotFilteredData(self):
		self.skipPlottingFAmpFlag = True
		self.parent.plotSonicData()
	def runBindingWidget(self):
		testconf = self.isWidget.testconf
		capsconf = self.isWidget.capsconf
		if testconf == None: return 0
		dens = self.isWidget.dens
		length = self.isWidget.length
		atime = self.isWidget.atime
		self.bWidget.setConfig(testconf,capsconf,dens,length,atime)
		self.bWidget.run()
	def setData(self,data):
		'''
		data is a dictionary with keys: P,Sx,Sy
		'''
		for wave in WaveTypes:
			self.data[wave] = data[wave]
		self.createTable()
		self.getFourrierTransforms()
		self.arrivalsPicked = False
	def hasData(self):
		'''
		check if the viewer has data to work with
		'''
		for wave in WaveTypes:
			if len(self.data[wave])>0: return True
		return False
	def createTable(self):
		'''
		store all data in one 3D np-array
		1st dimension - time or amplitude
	    2nd dimension - number of file
	    3rd dimension - datapoints
		'''
		if not self.hasData(): return 0 # if no data pass
		print 'Building sonic matrix'
		self.table = {}
		for wave in WaveTypes:
		    self.table[wave] = get_table(self.data[wave])
		    self.y[wave] = np.arange(self.table[wave].shape[1])

	def showFourrier(self):
		self.fWidget.show()
		self.fWidget.activateWindow()
		self.parent.plotSonicData()
	def showPhases(self):
		self.phWidget.show()
		self.phWidget.activateWindow()
		self.parent.plotSonicData()
	def getFourrierTransforms(self):
		if not self.hasData(): return 0 # if no data pass
		print 'Building Fourrier matrix'
		self.fft = {} # power
		self.fftamp = {} # power
		self.fftph = {} # phase
		for wave in WaveTypes:
			x = self.table[wave][0,:,:]
			y = self.table[wave][1,:,:]
			N = y.shape[1]
			h = x[0,1] - x[0,0]
			# yf = np.fft.fft(y).real[:,:N/2]
			ft = np.fft.fft(y)
			fft = ft[:,:N/2]
			fft = np.fft.fft(y)[:,:N/2]
			yf = np.absolute(fft)
			yp = np.arctan2(fft.imag,fft.real)
			xf0 = np.fft.fftfreq(N,h)
			xf = xf0[:N/2]
			xf = np.tile(xf,y.shape[0])
			xf0 = np.tile(xf0,y.shape[0])
			xf = xf.reshape(yf.shape[0],yf.shape[1])
			xf0 = xf0.reshape(ft.shape[0],ft.shape[1])
			self.fft[wave] = np.array((xf0,ft))
			self.fftamp[wave] = np.array((xf,yf))
			self.fftph[wave] = np.array((xf,yp))


	def connectPlotButtons(self):
		for wave in WaveTypes:
			self.params[wave].param('Show').sigValueChanged.connect(self.changeLayout)

	def changeLayout(self):
		print 'changing layout'
		for wave in WaveTypes:
			try:
				self.sublayout.removeItem(self.plots[wave])
				self.fWidget.sublayout.removeItem(self.fWidget.plots[wave])
			except:
				pass
		for wave in self.getActivePlots():
			if wave:
				self.sublayout.addItem(self.plots[wave])
				self.fWidget.sublayout.addItem(self.fWidget.plots[wave])
				self.sublayout.nextRow()
				self.fWidget.sublayout.nextRow()
	def autoScalePlots(self):
		if self.autoScaleButton.isChecked():
			for wave in self.getActivePlots():
				self.plots[wave].enableAutoRange()
				self.fWidget.plots[wave].enableAutoRange()
				self.phWidget.plots[wave].enableAutoRange()
		else:
			for wave in self.getActivePlots():
				self.plots[wave].disableAutoRange()
				self.fWidget.plots[wave].disableAutoRange()
				self.phWidget.plots[wave].disableAutoRange()
	def getActivePlots(self):
		activePlots = []
		for wave in WaveTypes:
			val = self.params[wave].param('Show').value()
			if val: activePlots.append(wave)
		return activePlots
	def pickAllArrivals(self) :
		pBar = QtGui.QProgressDialog(None,QtCore.Qt.WindowStaysOnTopHint)
		pBar.setWindowTitle("Picking first arrivals")
		pBar.setAutoClose(True)
		pBar.show()
		pBar.activateWindow()
		progress = 0
		pBar.setValue(progress)
		for wave in WaveTypes:
			self.pickArrivals(wave)
			progress += 33
			pBar.setValue(progress)
		pBar.setValue(100)
		self.arrivalsPicked = True
		self.showArrivalsButton.setDisabled(False)
		self.moduliButton.setDisabled(False)
		self.handPickArrivalsButton.setDisabled(False)
		self.showArrivalsButton.trigger()

	def getInverseFFT(self):
		ifft = {}
		interval = self.fWidget.interval()
		for wave in WaveTypes:
			x = self.table[wave][0,:,:]
			xf = self.fft[wave][0,:,:]
			yf = copy(self.fft[wave][1,:,:])
			yf[abs(xf)<min(interval)] = 0
			yf[abs(xf)>max(interval)] = 0
			ift = np.fft.ifft(yf)
			ifft[wave] = np.array((x,ift.real))
		return ifft

	def plot(self,indices=None,yarray=None,yindices=None,
		amplify=None,yAxisName='Track #'):
		'''
		indices - number of sonic tracks to plot
		yarray - y values 
		yindices - indices of yarray to plot
		'''
		# print 1
		for wave in self.getActivePlots():
			plot = self.plots[wave]
			fplot = self.fWidget.plots[wave]
			phplot = self.phWidget.plots[wave]
			plot.clear();
			if self.skipPlottingFAmpFlag: pass
			else: 
				fplot.clear()
				fplot.getAxis('left').setLabel(yAxisName,**LabelStyle)
				fplot.getAxis('bottom').setLabel(fXAxisName,**LabelStyle)
				if self.autoScaleButton.isChecked():
					fplot.enableAutoRange(enable=True)
				else: fplot.disableAutoRange()
			if self.skipPlottingFPhaseFlag: pass
			else: 
				phplot.clear()
				phplot.getAxis('left').setLabel(yAxisName,**LabelStyle)
				phplot.getAxis('bottom').setLabel(fXAxisName,**LabelStyle)
				if self.autoScaleButton.isChecked():
					phplot.enableAutoRange(enable=True)
				else: phplot.disableAutoRange()

			plot.getAxis('left').setLabel(yAxisName,**LabelStyle)
			plot.getAxis('bottom').setLabel(xAxisName,**LabelStyle)
			if self.autoScaleButton.isChecked():
				plot.enableAutoRange(enable=True)
			else:
				plot.disableAutoRange()

		# Plot data in main sonic viewer
		if self.filteringButton.isChecked():
			self.fWidget.show()
			# self.fWidget.activateWindow()
			ifft = self.getInverseFFT()
			if self.mode == 'WaveForms':
				self.plotDataWaveForms(ifft,self,
					indices,amplify,yAxisName)
			elif self.mode == 'Contours':
				self.plotDataContours(ifft,
					self, self.fgw,
					indices,yarray,yindices,
					amplify,yAxisName)
		else:
			if self.mode == 'WaveForms':
				self.plotWaveForms(indices,amplify,yAxisName)
			elif self.mode == 'Contours':
				self.plotContours(indices,yarray,yindices,
				amplify,yAxisName)

		# Plot fourrier transform amplitude data
		if not self.skipPlottingFAmpFlag:
			if self.fWidget.isVisible():
				if self.filteringButton.isChecked():
					self.fWidget.addRegions()
				if self.mode == 'WaveForms':
					self.plotDataWaveForms(self.fftamp,self.fWidget,
						indices,amplify,yAxisName)
				elif self.mode == 'Contours':
					self.plotDataContours(self.fftamp,
						self.fWidget, self.fgw,
						indices,yarray,yindices,
						amplify,yAxisName)

		# Plot fourrier transform phase data
		if not self.skipPlottingFPhaseFlag:
			if self.phWidget.isVisible():
				if self.mode == 'WaveForms':
					self.plotDataWaveForms(self.fftph,self.pWidget,
						indices,amplify,yAxisName)
				elif self.mode == 'Contours':
					self.plotDataContours(self.fftph,
						self.phWidget, self.gw,
						indices,yarray,yindices,
						amplify,yAxisName)

		# Plot arrival times
		if self.showArrivalsButton.isChecked():
			self.plotArrivals(indices,yarray,yindices,
			amplify,yAxisName)

		# print 6
		self.skipPlottingFAmpFlag = False
		self.skipPlottingFPhaseFlag = False
		
	def plotWaveForms(self,indices=None, amplify=None,yAxisName=''):
		self.graphicPaths = {}
		if (amplify is None):
			amp=np.average(np.abs(np.diff(self.y['P'])))
		for wave in self.getActivePlots():
			plot = self.plots[wave]
			if self.invertYButton.isChecked(): plot.invertY(True)
			else: plot.invertY(False)
			if indices: sind = indices[wave]
			else: sind = np.arange(self.table[wave].shape[1])
			Nlines = len(self.y[wave])
			y = amp*self.table[wave][1,sind,:] + self.y[wave].reshape(Nlines,1)
			# self.params[wave].param('Amplify').setValue(amp)
			if indices:
				self.graphicPaths[wave] = MultiLine(self.table[wave][0,sind,:],y)
			else:
				self.graphicPaths[wave] = MultiLine(self.table[wave][0,:,:],y)
			try:
				plot.addItem(self.graphicPaths[wave])
			except: pass


	def plotDataWaveForms(self,
		data,widget,indices=None, amplify=None,yAxisName=''):
		paths = {}
		amp=np.average(np.abs(np.diff(self.y['P'])))/data['P'].max()
		for wave in self.getActivePlots():
			plot = widget.plots[wave]
			if self.invertYButton.isChecked(): plot.invertY(True)
			else: plot.invertY(False)
			if indices: sind = indices[wave]
			else: sind = np.arange(data[wave].shape[1])
			Nlines = len(self.y[wave])
			y = amp*data[wave][1,sind,:] + self.y[wave].reshape(Nlines,1)
			if indices:
				paths[wave] = MultiLine(data[wave][0,sind,:],y)
			else:
				paths[wave] = MultiLine(data[wave][0,:,:],y)
			try:
				plot.addItem(paths[wave])
			except: pass
	def plotDataContours(self,data,widget,gw,
		indices=None,yarray=None,yindices=None,
		amplify=None,yAxisName=''):
		images = {}
		k = 0
		for wave in self.getActivePlots():
			plot = widget.plots[wave]
			if self.invertYButton.isChecked(): plot.invertY(True)
			else: plot.invertY(False)
			images[wave] = pg.ImageItem()
			if indices:
				z = data[wave][1,indices[wave],:].T
			else:
				z = data[wave][1,:,:].T
			if k == 0: lut = gw.getLookupTable(z.shape[0], alpha=None)
			images[wave].setImage(z)
			plot.addItem(images[wave])
			x = data[wave][0,0,:]
			shiftX0 = x[0]
			scaleX = (x[-1] - x[0])/x.shape[0]
			y = self.y[wave]
			ymax = y.max()
			ymin = y.min()
			shiftY0 = ymin
			scaleY = float(ymax - ymin)/y.shape[0]

			images[wave].translate(shiftX0,shiftY0)
			images[wave].scale(scaleX,scaleY)
			# set Colors
			images[wave].setLookupTable(lut, update=True)
			k += 1

	def plotContours(self,indices=None,yarray=None,yindices=None,
		amplify=None,yAxisName=''):
		self.images = {}
		k = 0
		for wave in self.getActivePlots():
			plot = self.plots[wave]
			if self.invertYButton.isChecked(): plot.invertY(True)
			else: plot.invertY(False)
			self.images[wave] = pg.ImageItem()
			if indices:
				z = self.table[wave][1,indices[wave],:].T
			else:
				z = self.table[wave][1,:,:].T
			if k == 0: lut = self.gw.getLookupTable(z.shape[0], alpha=None)
			self.images[wave].setImage(z)
			plot.addItem(self.images[wave])
			# scale and shift image
			x = self.table[wave][0,0,:]
			shiftX0 = x[0]
			scaleX = (x[-1] - x[0])/x.shape[0]

			y = self.y[wave]
			ymax = y.max()
			ymin = y.min()
			shiftY0 = ymin
			scaleY = float(ymax - ymin)/y.shape[0]

			self.images[wave].translate(shiftX0,shiftY0)
			self.images[wave].scale(scaleX,scaleY)
			# set Colors
			self.images[wave].setLookupTable(lut, update=True)
			k += 1

	def plotArrivals(self,indices=None,yarray=None,yindices=None,
		amplify=None,yAxisName='Track #'):
		try: 
			self.QTable.cellChanged.disconnect(self.editArrivals)
		except: pass
		tableLabels = get_list(yAxisName,WaveTypes)
		self.QTable.setHorizontalHeaderLabels(tableLabels)
		for wave in self.getActivePlots():
			k = WaveTypes.index(wave)
			if yarray is None:
				x = self.aTimes[wave]
				y = np.arange(self.aTimes[wave].shape[0])
			else: 
				ind = yindices[wave]
				sind = indices[wave]
				y = yarray[ind]
				x = self.aTimes[wave][sind]
			if self.updateQTable:
				self.QTable.setColumn(y,k)
				self.QTable.setColumn(x,k+3)
			else: self.QTable.close() # otherwise it stalls
			plt = self.plots[wave]
			pen = pg.mkPen(color=(72,209,204), width=2)
			plt.plot(x,y,pen=pen)
		self.updateQTable = True
		self.QTable.cellChanged.connect(self.editArrivals)

	def setYAxisParameters(self,parameters):
		# we use setLimits because of weird implementation
		# in pyqtgraph
		self.allParameters = parameters
		self.yAxisMenu.clear()
		self.yAxisButtons = {}
		self.yAxisButtons['Track #'] = QtGui.QAction('Track #',self,checkable=True)
		self.yAxisButtons['Track #'].setActionGroup(self.yAxisGroup)
		self.yAxisMenu.addAction(self.yAxisButtons['Track #'])
		for p in parameters:
			if self.mode == 'Contours' and p!='Time': continue
			self.yAxisButtons[p] = QtGui.QAction(p,self,checkable=True)
			self.yAxisButtons[p].setActionGroup(self.yAxisGroup)
			self.yAxisMenu.addAction(self.yAxisButtons[p])
			pass
		try: 
			print 'Setting y axis to: Time'
			self.yAxisButtons['Time'].setChecked(True)
			self.yAxis = 'Time'
		except: print 'setting was not successful'

	def setMode(self,mode):
		'''
		takes string arguments: WaveForms and Contours
		'''
		self.mode = mode
		if mode == 'WaveForms':
			print 'Setting mode to Wave Forms'
			# self.modeMenu.setDefaultAction(self.waveFormButton)
		elif mode == 'Contours':
			print 'Setting mode to Contours'
			# self.modeMenu.setDefaultAction(self.contourButton)
		self.setYAxisParameters(self.allParameters)

	def setupGUI(self):
		self.setWindowTitle("Sonic Viewer")
		pg.setConfigOption('background', (255,255,255))
		pg.setConfigOption('foreground',(0,0,0))
		self.layout = QtGui.QVBoxLayout()
		self.layout.setContentsMargins(0,0,0,0)
		self.layout.setSpacing(0)
		self.setLayout(self.layout)
		## setting up the menu bar
		self.menuBar = QtGui.QMenuBar()
		self.layout.setMenuBar(self.menuBar)
		self.viewMenu = self.menuBar.addMenu('View')
		self.modeMenu = self.menuBar.addMenu('Mode')
		self.transformMenu = self.menuBar.addMenu('Transform')
		self.intMenu = self.menuBar.addMenu('Interpretation')
		# VIEW MENU
		self.autoScaleButton = QtGui.QAction('Auto scale',self,checkable=True)
		self.autoScaleButton.setChecked(True)
		self.showArrivalsButton = QtGui.QAction('Arrivals',self,checkable=True)
		self.showArrivalsButton.setDisabled(True)
		self.showTableButton = QtGui.QAction('Table',self)
		self.yAxisMenu = self.viewMenu.addMenu('y axis')
		self.editGradientsButton = QtGui.QAction('Edit Gradients',self)
		self.invertYButton = QtGui.QAction('Invert y axis',self,checkable=True)
		
		self.viewMenu.addAction(self.autoScaleButton)
		self.viewMenu.addAction(self.showArrivalsButton)
		self.viewMenu.addAction(self.showTableButton)
		self.viewMenu.addAction(self.editGradientsButton)
		self.viewMenu.addAction(self.invertYButton)
		
		# MODE MENU
		self.modeGroup = QtGui.QActionGroup(self)
		self.waveFormButton = QtGui.QAction('Wave Forms',self,checkable=True)
		self.contourButton = QtGui.QAction('Contours',self,checkable=True)
		self.waveFormButton.setActionGroup(self.modeGroup)
		self.contourButton.setActionGroup(self.modeGroup)
		self.contourButton.setChecked(True)

		self.modeMenu.addAction(self.waveFormButton)
		self.modeMenu.addAction(self.contourButton)
		# INTERPRETATION MENU
		self.pickArrivalsButton = QtGui.QAction('Pick arrivals',self)
		self.handPickArrivalsButton = QtGui.QAction('Hand pick',self,checkable=True)
		self.moduliButton = QtGui.QAction('Elastic moduli',self)
		self.moduliButton.setDisabled(True)
		self.handPickArrivalsButton.setDisabled(True)

		self.intMenu.addAction(self.pickArrivalsButton)
		self.intMenu.addAction(self.handPickArrivalsButton)
		self.intMenu.addAction(self.moduliButton)
		# TRANSFORM MENU
		self.showForrierMagnitudeButton = QtGui.QAction('Fourrier magnitude',self)
		self.showForrierPhasesButton = QtGui.QAction('Fourrier phases',self)
		self.filteringButton = QtGui.QAction('Frequency filtering',self,checkable=True)
		self.transformMenu.addAction(self.showForrierMagnitudeButton)
		self.transformMenu.addAction(self.showForrierPhasesButton)
		self.transformMenu.addAction(self.filteringButton)
		# dict to store actions for y Axis
		self.yAxisButtons = {}
		self.yAxisGroup = QtGui.QActionGroup(self)
		self.yAxisButtons['Track #'] = QtGui.QAction('Track #',self,checkable=True)
		self.yAxisButtons['Track #'].setActionGroup(self.yAxisGroup)
		self.yAxisMenu.addAction(self.yAxisButtons['Track #'])
		self.yAxisButtons['Track #'].setChecked(True)

		# for wave in WaveTypes:
		# split main widget into plotting area and parameters area
		self.splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
		self.splitter.setOrientation(QtCore.Qt.Horizontal)
		self.layout.addWidget(self.splitter)
		# split parameter area into 3 for each wave
		self.treeSplitter = QtGui.QSplitter()
		self.treeSplitter.setOrientation(QtCore.Qt.Vertical)
		self.splitter.addWidget(self.treeSplitter)
		# create parameter trees
		self.trees={}
		for wave in WaveTypes:
			self.trees[wave] = ParameterTree(showHeader=False)
			self.treeSplitter.addWidget(self.trees[wave])
		# create layout for the plotting area
		self.sublayout = pg.GraphicsLayoutWidget()
		self.splitter.addWidget(self.sublayout)
		self.params = {}
		self.plots = {}
		for wave in WaveTypes:
			# create parameter instances
			self.params[wave] = Parameter.create(name=wave + ' wave',
				type='group',children=Parameters)
			self.trees[wave].setParameters(self.params[wave],showTop=True)
			# fill plotting area with 3 plots
			# self.plots[wave] = self.sublayout.addPlot()
			self.plots[wave] = self.sublayout.addPlot(viewBox=ViewBox())
			setup_plot(self.plots[wave])
			self.sublayout.nextRow()

		self.params['Sx'].param('Arrival times').param('BTA').setValue(36)
		self.params['Sx'].param('Arrival times').param('ATA').setValue(5)
		self.params['Sx'].param('Arrival times').param('DTA').setValue(20)
		self.params['Sy'].param('Arrival times').param('BTA').setValue(100)
		self.params['Sy'].param('Arrival times').param('ATA').setValue(5)
		self.params['Sy'].param('Arrival times').param('DTA').setValue(30)
		# create table widget to show arrival times
		self.QTable = TableWidget(['Number P','Number Sx','Number Sy','P','Sx','Sy'])
		# self.splitter.addWidget(self.QTable)
		self.QTable.setColumnCount(6)
		self.QTable.hide()

		self.splitter.setSizes([int(self.width()*0.30),
                                    int(self.width()*0.35),
                                    int(self.width()*0.35)
                                ])
		self.splitter.setStretchFactor(0, 0)
		self.splitter.setStretchFactor(1, 1)
		self.splitter.setStretchFactor(2, 0)

	def pickArrivals(self,wave):
		print 'Computing arrival times for %s wave'%(wave)
		win = [0,0,0]
		mpoint = self.params[wave].param('Arrival times').param('Mpoint').value()
		win[0] = self.params[wave].param('Arrival times').param('BTA').value()
		win[1] = self.params[wave].param('Arrival times').param('ATA').value()
		win[2] = self.params[wave].param('Arrival times').param('DTA').value()
		x = self.table[wave][0,:,:]
		y = self.table[wave][1,:,:]
		h = x[0,1] - x[0,0]
		r = multi_window(y,win) 
		rx = np.arange(r.shape[1])*h + x[0,win[0]]
		mind = abs(rx-mpoint).argmin() #index of middle point
		sInd = r[:,:mind].argmax(axis=1) # sender indices
		sTimes = rx[sInd] # sender times
		rInd = r[:,mind:].argmax(axis=1) # receiver indices
		rTimes = rx[mind+rInd]
		self.aTimes[wave] = rTimes - sTimes
		# shift initial data so
		if self.autoShift[wave]:
			shift = np.mean(sTimes)
			self.table[wave][0,:,:] -= shift
			self.autoShift[wave] = False


	def editArrivals(self):
		data = self.QTable.getValues()
		indices = self.parent.trsIndices
		if self.yAxis == 'Track #':
			for wave in WaveTypes:
				indices[wave] = np.arange(len(self.parent.sTimes[wave]))
			pass
		self.aTimes['P'][indices['P']] = data[:,3]
		self.aTimes['Sx'][indices['Sx']] = data[:,4]
		self.aTimes['Sy'][indices['Sy']] = data[:,5]
		self.updateQTable = False
		self.parent.plotSonicData()


	def recomputeArrivals(self):
		parent = self.sender().parent().parent().name()
		wave = parent.split()[0]
		self.pickArrivals(wave)
		self.parent.plotSonicData()

	def showTable(self):
		# show = self.showTableButton.isChecked()
		self.QTable.show()
		self.QTable.activateWindow()
	def closeEvent(self,event):
		QtGui.QWidget.closeEvent(self,event)
		self.fWidget.close()
		self.phWidget.close()
		self.QTable.close()
		self.bWidget.close()
Exemple #15
0
class ExpenditureWidget(tkinter.Frame, TableEditListener):
    # is a widget that displays the expenditures in the database

    def __init__(self, parent, **optional_arguments):
        # initializes the frame and sub frames
        tkinter.Frame.__init__(self, parent)
        self.colors = None
        self.expenditures_set = False
        self.table_edit_listener: TableEditListener = None
        self.field_count = default_field_count

        # setup the default parameters then process the optional arguments
        self.title_font = default_title_font
        self.head_font = default_table_head_font
        self.entry_font = default_entry_font
        self.title_text = default_title_text
        self.process_optional_arguments(optional_arguments)

        # setup the title label
        self.head_label = None
        self.setup_title_label()

        # setup the edit button
        self.edit_button = None
        self.done_button = None
        self.setup_edit_button()

        # setup the expenditure table
        self.expenditure_table = None
        self.setup_expenditure_table()

    def add_listener(self, listener: TableEditListener):
        self.table_edit_listener = listener

    def process_optional_arguments(self, optional_arguments):
        # processes the optional arguments passed to the constructor
        if 'title_font' in optional_arguments:
            self.title_font = optional_arguments['title_font']
        if 'head_font' in optional_arguments:
            self.head_font = optional_arguments['head_font']
        if 'entry_font' in optional_arguments:
            self.entry_font = optional_arguments['entry_font']
        if 'name' in optional_arguments:
            self.title_text = optional_arguments['name']

    def setup_title_label(self):
        # adds a title label above the table
        self.head_label = tkinter.Label(self)
        self.head_label.config(text=self.title_text, font=self.title_font)
        self.head_label.grid(row=0, column=0, sticky="E")

    def setup_expenditure_table(self):
        # adds the expenditure table
        self.expenditure_table = TableWidget(
            self,
            3,
            self.field_count + 1,
            table_name="expenditures",
            invert_axis=False,
            column_widths=default_field_col_widths,
            head_font=self.head_font,
            entry_font=self.entry_font)
        self.expenditure_table.hide_config_buttons()
        self.expenditure_table.add_listener(self)
        self.expenditure_table.set_header_values(['Amount', 'Name', 'Type'])
        self.expenditure_table.grid(row=1, columnspan=2)

    def setup_edit_button(self):
        self.edit_button = tkinter.Button(self,
                                          text="Edit",
                                          command=lambda: self.edit_pressed())
        self.done_button = tkinter.Button(self,
                                          text="Done",
                                          command=lambda: self.done_pressed())
        self.edit_button.grid(row=0, column=1, sticky="W")

    def edit_pressed(self):
        if self.expenditures_set:
            self.expenditure_table.show_config_buttons()
            self.edit_button.grid_forget()
            self.done_button.grid(row=0, column=1, sticky="W")

    def done_pressed(self):
        self.expenditure_table.hide_config_buttons()
        self.done_button.grid_forget()
        self.edit_button.grid(row=0, column=1, sticky="W")

    def set_expenditures(self, expenditure_matrix: [[]]):
        # passes the label values to the table to be inserted into the labels
        self.expenditures_set = True
        table = []
        for row_index in range(len(expenditure_matrix)):
            values = [
                TableWidget.format_as_currency(
                    expenditure_matrix[row_index][1]),
                expenditure_matrix[row_index][2],
                expenditure_matrix[row_index][3]
            ]
            table.append(values)
        self.expenditure_table.load_table_data(table)

    def send_edit_to_database(self, table_name: str, row_index: int, values):
        # passes the row values to the listener to the DatabaseModel to be processed and stored in the database
        value_dict = {
            'amount': TableWidget.unformat_from_currency(values[0]),
            'name': values[1],
            'type': values[2]
        }
        self.table_edit_listener.send_edit_to_database(table_name, row_index,
                                                       value_dict)

    def set_colors(self, color_dict: {str: str}):
        self.colors = color_dict
        self.update_colors()

    def update_colors(self):
        if self.colors is not None:
            self.config(bg=self.colors['bg_col'])
            self.head_label.config(bg=self.colors['bg_col'],
                                   fg=self.colors['text_col'])
            self.expenditure_table.set_colors(self.colors)
            self.edit_button.config(
                fg=self.colors['button_col']['button_text_col'],
                highlightbackground=self.colors['button_col']['button_bg_col'],
                activeforeground=self.colors['button_col']
                ['button_pressed_text'],
                activebackground=self.colors['button_col']
                ['button_pressed_bg'])
            self.done_button.config(
                fg=self.colors['button_col']['button_text_col'],
                highlightbackground=self.colors['button_col']['button_bg_col'],
                activeforeground=self.colors['button_col']
                ['button_pressed_text'],
                activebackground=self.colors['button_col']
                ['button_pressed_bg'])
Exemple #16
0
    def on_finished(self):

        fileName = self.lineEdit.text()

        for i in range(1, self.tableWidget.columnCount()):
            self.headTitle.append(self.tableWidget.item(0, i).text())

        id = self.currentId()
        if id == 4 and fileName != "":

            position = self.father.tab.currentIndex()

            root = self.father.tree.topLevelItem(position - 1)

            self.startrow = int(self.le1.text())

            selectedList = self.father.tree.selectedItems()
            for i in range(0, len(selectedList)):
                selectedList[i].setSelected(0)
            #  tree_record
            title = 'File Data'
            s = 0
            while title in self.father.tree_record[root.text(0)]:
                s += 1
                title = 'File Data' + str(s)
            self.father.tree_record[root.text(0)][title] = {'type': 'FileData'}

            child = QTreeWidgetItem(root)
            child.setText(0, title)
            root.setExpanded(1)
            child.setSelected(1)

            data = []
            suffixList = fileName.split('.')
            suffix = suffixList[-1]
            if suffix != 'xls' and suffix != 'xlsx':
                filename = open(fileName)
                line1s = filename.readlines()
                for line in line1s[self.startrow - 1:]:
                    if line.rstrip() == '':
                        continue
                    temp = line.rstrip().split(',')
                    data.append(temp)
            if suffix == 'xls' or suffix == 'xlsx':
                data = xlrd.open_workbook(fileName)
                table = data.sheets()[0]
                for i in range(self.startrow - 1, table.nrows):
                    datatemp = []
                    for j in range(0, table.ncols):
                        datatemp.append(str(table.cell(i, j).value))
                    data.append(datatemp)
            self.tableWidget = TableWidget(self.father, data, self.headTitle,
                                           0, 0)
            sub = QMdiSubWindow()
            sub.setWindowIcon(QIcon(".\\image\\logo.png"))
            sub.setWidget(self.tableWidget)
            sub.setWindowTitle(title)
            sub.resize(750, 750)
            self.father.tab.widget(position).addSubWindow(sub)
            sub.show()
            self.father.tab.widget(position).setActiveSubWindow(sub)
Exemple #17
0
class Wizard(QWizard):
    def __init__(self, parent):
        super(Wizard, self).__init__(parent)
        self.setWindowTitle("File-Choosing Wizard")
        self.setWindowIcon(QIcon(".\\image\\logo.png"))
        self.setGeometry(600, 250, 350, 350)
        self.father = parent
        self.linenumber = 0

        firstPage = QWizardPage()
        firstPage.setSubTitle("welcome")
        firstPage.setPixmap(QWizard.WatermarkPixmap,
                            QPixmap(".\\image\\image.jpg"))
        label = QLabel()
        label.setText(
            "This wizard will guide you to select\n and preview the documents. \n \nTips: If you need inversion function, \nplease change the column names to Vxx, Vxy,\n Vxz, Vyy, Vyz, Vzz on the last page. \n If you are ready, please click Next."
        )
        label.setAlignment(Qt.AlignCenter)
        layout1 = QVBoxLayout()
        layout1.addWidget(label)
        firstPage.setLayout(layout1)

        secondPage = QWizardPage()
        secondPage.setSubTitle("Choose File")
        self.lineEdit = QLineEdit()
        self.button = QPushButton("Choose File", secondPage)
        layout = QHBoxLayout()
        layout.addWidget(self.lineEdit)
        layout.addWidget(self.button)
        layout3 = QVBoxLayout()
        layout3.addStretch(5)
        layout3.addLayout(layout)
        layout3.addStretch(5)
        layout3.setAlignment(layout, Qt.AlignCenter)
        secondPage.setLayout(layout3)

        thirdPage = QWizardPage()
        thirdPage.setSubTitle("preview & choose")
        #self.tw = QTableWidget()
        self.te = QTextEdit()
        self.text1 = QLabel("Data Start Line:")
        self.le1 = QLineEdit()

        layout21 = QHBoxLayout()
        layout21.addStretch(1)
        layout21.addWidget(self.text1, 1)
        layout21.addWidget(self.le1, 1)
        layout21.addStretch(1)

        layout2 = QVBoxLayout()
        layout2.addWidget(self.te, 3)
        layout2.addLayout(layout21, 1)
        thirdPage.setLayout(layout2)

        forthPage = QWizardPage()
        forthPage.setSubTitle("Fill in the Coordinate Name")
        tip = QLabel(self)
        tip.setText("Double-click the header(s) to name the column(s)!")
        tip.setAlignment(Qt.AlignCenter)
        self.tableWidget = QTableWidget()
        layout4 = QVBoxLayout()
        layout4.addWidget(tip, 1)
        layout4.addWidget(self.tableWidget, 9)
        forthPage.setLayout(layout4)

        self.startrow = 0
        self.headTitle = ["ZERO"]
        self.uplimit = 0

        self.setWizardStyle(QWizard.ModernStyle)
        self.setPage(1, firstPage)
        self.setPage(2, secondPage)
        self.setPage(3, thirdPage)
        self.setPage(4, forthPage)
        self.setStartId(1)
        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)
        self.button.clicked.connect(self.chooseFile)
        self.currentIdChanged.connect(self.on_currentIdChanged)
        self.finished.connect(self.on_finished)

    def isFloot(self, s):
        try:
            s = float(s)
        except TypeError:
            return False
        except ValueError:
            return False
        else:
            return True

    def chooseFile(self):
        name = QFileDialog.getOpenFileName(self, 'Open File', './',
                                           '*.txt *.xls')
        self.lineEdit.setText(str(name[0]))

    def validateCurrentPage(self):
        fileName = self.lineEdit.text()
        id = self.currentId()
        if id == 2:
            if fileName == "":
                QMessageBox.information(self, "Attention",
                                        "Please Choose File")
                return 0
            with open(fileName, 'r') as fw:
                lines = fw.readlines()
                h = len(lines)
                for i in range(0, h):
                    line = lines[i].rstrip().split(',')
                    if self.isFloot(line[0]) == 1:
                        self.le1.setText(str(i + 1))
                        break
        if id == 3:
            if self.le1.text() == "":
                QMessageBox.information(self, "Attention",
                                        "Please Fill in Data Start Line")
                return 0
            else:
                try:
                    temp = int(self.le1.text())
                except ValueError:
                    QMessageBox.information(self, "Attention",
                                            "Data Start Line isn't a integer")
                    return 0
                if temp < 1 or temp > self.uplimit:
                    return 0
        if id == 4:
            headTemp = []
            for i in range(1, self.tableWidget.columnCount()):
                headTemp.append(self.tableWidget.item(0, i).text())
            flagX = 0
            flagY = 0
            for i in range(0, len(headTemp)):
                if headTemp[i] == 'X' or headTemp[i] == 'x':
                    flagX = 1
                if headTemp[i] == 'Y' or headTemp[i] == 'y':
                    flagY = 1
            if flagX == 0 or flagY == 0:
                QMessageBox.information(self, "Attention",
                                        "No X, Y Axes Selected.")
                return 0
        return 1

    def on_currentIdChanged(self):
        fileName = self.lineEdit.text()
        id = self.currentId()
        suffixList = fileName.split('.')
        suffix = suffixList[-1]
        if id == 3 and fileName != "":
            if suffix != 'xls' and suffix != 'xlsx':
                filename = open(fileName)
                line1s = filename.readlines()
                self.uplimit = len(line1s)
                aa = ""
                count = 1
                for line in line1s:
                    aa = aa + str(count) + "  " + line + "\n"
                    count += 1
                td = QTextDocument(aa)
                self.te.setDocument(td)
            if suffix == 'xls' or suffix == 'xlsx':
                data = xlrd.open_workbook(fileName)
                table = data.sheets()[0]
                self.uplimit = table.nrows
                aa = ""
                for i in range(0, table.nrows):
                    aa = aa + str(i + 1) + "  "
                    for j in range(0, table.ncols):
                        aa = aa + str(table.cell(i, j).value) + "\t"
                    aa = aa + "\n"
                td = QTextDocument(aa)
                self.te.setDocument(td)
        if id == 4 and self.le1.text() != "":

            fileName = self.lineEdit.text()
            data = []
            if suffix != 'xls' and suffix != 'xlsx':
                filename = open(fileName)
                line1s = filename.readlines()
                for line in line1s[int(self.le1.text()) - 1:]:
                    if line.rstrip() == '':
                        continue
                    temp = line.rstrip().split(',')
                    for i in range(0, len(temp)):
                        if temp[i] == "":
                            QMessageBox.information(
                                self, "Attention",
                                "File Exceptions.Back to the Previous Page.")
                            self.back()
                            self.back()
                            return
                    data.append(temp)
            if suffix == 'xls' or suffix == 'xlsx':
                file = xlrd.open_workbook(fileName)
                table = file.sheets()[0]
                for i in range(int(self.le1.text()) - 1, table.nrows):
                    datatemp = []
                    for j in range(0, table.ncols):
                        if str(table.cell(i, j).value) == "":
                            QMessageBox.information(
                                self, "Attention",
                                "File Exceptions. Back to the Previous Page.")
                            self.back()
                            self.back()
                            return
                        datatemp.append(str(table.cell(i, j).value))
                    data.append(datatemp)
            tempcount = len(data[0])
            for i in range(1, len(data)):
                if tempcount != len(data[i]):
                    QMessageBox.information(
                        self, "Attention",
                        "File Exceptions. Back to the Previous Page.")
                    self.back()
                    self.back()
                    return
            self.tableWidget.setColumnCount(len(data[0]) + 1)
            self.tableWidget.setRowCount(len(data) + 1)
            self.tableWidget.horizontalHeader().setVisible(0)
            self.tableWidget.verticalHeader().setVisible(0)
            self.linenumber = len(data[0]) + 1

            temp_header = []
            flag = 0
            with open(fileName, 'r') as f:
                for i in range(0, int(self.le1.text()) - 1):
                    t = f.readline().rstrip('\n')
                    temp_header = t.rstrip().split(',')

                    if len(temp_header) == len(data[0]):
                        flag = 1
                        for i in range(1, len(data[0]) + 1):
                            self.tableWidget.setItem(
                                0, i, QTableWidgetItem(temp_header[i - 1]))
            if flag == 0:
                header = ['Vxx', 'Vxy', 'Vxz', 'Vyy', 'Vyz', 'Vzz', 'x', 'y']
                if (len(data[0]) + 1 > 8):
                    for i in range(0, len(data[0]) - 7):
                        header.append('V' + str(i))
                for i in range(1, len(data[0]) + 1):
                    self.tableWidget.setItem(0, i,
                                             QTableWidgetItem(header[i - 1]))
                self.tableWidget.setItem(0,
                                         len(data[0]) - 1,
                                         QTableWidgetItem('x'))
                self.tableWidget.setItem(0, len(data[0]),
                                         QTableWidgetItem('y'))
            for i in range(1, len(data) + 1):
                self.tableWidget.setItem(i, 0, QTableWidgetItem(str(i)))
                for j in range(1, len(data[0]) + 1):
                    self.tableWidget.setItem(
                        i, j, QTableWidgetItem(data[i - 1][j - 1]))

    def on_finished(self):

        fileName = self.lineEdit.text()

        for i in range(1, self.tableWidget.columnCount()):
            self.headTitle.append(self.tableWidget.item(0, i).text())

        id = self.currentId()
        if id == 4 and fileName != "":

            position = self.father.tab.currentIndex()

            root = self.father.tree.topLevelItem(position - 1)

            self.startrow = int(self.le1.text())

            selectedList = self.father.tree.selectedItems()
            for i in range(0, len(selectedList)):
                selectedList[i].setSelected(0)
            #  tree_record
            title = 'File Data'
            s = 0
            while title in self.father.tree_record[root.text(0)]:
                s += 1
                title = 'File Data' + str(s)
            self.father.tree_record[root.text(0)][title] = {'type': 'FileData'}

            child = QTreeWidgetItem(root)
            child.setText(0, title)
            root.setExpanded(1)
            child.setSelected(1)

            data = []
            suffixList = fileName.split('.')
            suffix = suffixList[-1]
            if suffix != 'xls' and suffix != 'xlsx':
                filename = open(fileName)
                line1s = filename.readlines()
                for line in line1s[self.startrow - 1:]:
                    if line.rstrip() == '':
                        continue
                    temp = line.rstrip().split(',')
                    data.append(temp)
            if suffix == 'xls' or suffix == 'xlsx':
                data = xlrd.open_workbook(fileName)
                table = data.sheets()[0]
                for i in range(self.startrow - 1, table.nrows):
                    datatemp = []
                    for j in range(0, table.ncols):
                        datatemp.append(str(table.cell(i, j).value))
                    data.append(datatemp)
            self.tableWidget = TableWidget(self.father, data, self.headTitle,
                                           0, 0)
            sub = QMdiSubWindow()
            sub.setWindowIcon(QIcon(".\\image\\logo.png"))
            sub.setWidget(self.tableWidget)
            sub.setWindowTitle(title)
            sub.resize(750, 750)
            self.father.tab.widget(position).addSubWindow(sub)
            sub.show()
            self.father.tab.widget(position).setActiveSubWindow(sub)
Exemple #18
0
    def __init__(self, parent):
        super(Wizard, self).__init__(parent)
        self.setWindowTitle("File-Choosing Wizard")
        self.setWindowIcon(QIcon(".\\image\\logo.png"))
        self.setGeometry(600, 250, 350, 350)
        self.father = parent
        self.linenumber = 0

        firstPage = QWizardPage()
        firstPage.setSubTitle("welcome")
        firstPage.setPixmap(QWizard.WatermarkPixmap,
                            QPixmap(".\\image\\image.jpg"))
        label = QLabel()
        label.setText(
            "This wizard will guide you to select\n and preview the documents. \n \nTips: If you need inversion function, \nplease change the column names to Vxx, Vxy,\n Vxz, Vyy, Vyz, Vzz on the last page. \n If you are ready, please click Next."
        )
        label.setAlignment(Qt.AlignCenter)
        layout1 = QVBoxLayout()
        layout1.addWidget(label)
        firstPage.setLayout(layout1)

        secondPage = QWizardPage()
        secondPage.setSubTitle("Choose File")
        self.lineEdit = QLineEdit()
        self.button = QPushButton("Choose File", secondPage)
        layout = QHBoxLayout()
        layout.addWidget(self.lineEdit)
        layout.addWidget(self.button)
        layout3 = QVBoxLayout()
        layout3.addStretch(5)
        layout3.addLayout(layout)
        layout3.addStretch(5)
        layout3.setAlignment(layout, Qt.AlignCenter)
        secondPage.setLayout(layout3)

        thirdPage = QWizardPage()
        thirdPage.setSubTitle("preview & choose")
        #self.tw = QTableWidget()
        self.te = QTextEdit()
        self.text1 = QLabel("Data Start Line:")
        self.le1 = QLineEdit()

        layout21 = QHBoxLayout()
        layout21.addStretch(1)
        layout21.addWidget(self.text1, 1)
        layout21.addWidget(self.le1, 1)
        layout21.addStretch(1)

        layout2 = QVBoxLayout()
        layout2.addWidget(self.te, 3)
        layout2.addLayout(layout21, 1)
        thirdPage.setLayout(layout2)

        forthPage = QWizardPage()
        forthPage.setSubTitle("Fill in the Coordinate Name")
        tip = QLabel(self)
        tip.setText("Double-click the header(s) to name the column(s)!")
        tip.setAlignment(Qt.AlignCenter)
        self.tableWidget = QTableWidget()
        layout4 = QVBoxLayout()
        layout4.addWidget(tip, 1)
        layout4.addWidget(self.tableWidget, 9)
        forthPage.setLayout(layout4)

        self.startrow = 0
        self.headTitle = ["ZERO"]
        self.uplimit = 0

        self.setWizardStyle(QWizard.ModernStyle)
        self.setPage(1, firstPage)
        self.setPage(2, secondPage)
        self.setPage(3, thirdPage)
        self.setPage(4, forthPage)
        self.setStartId(1)
        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)
        self.button.clicked.connect(self.chooseFile)
        self.currentIdChanged.connect(self.on_currentIdChanged)
        self.finished.connect(self.on_finished)
class BalanceWidget(tkinter.Frame):
    # is a widget that tells the user the balance and the sum

    def __init__(self, parent, **optional_arguments):
        # initialized the frame and sub frames
        tkinter.Frame.__init__(self, parent)
        self.colors = None
        self.table_edit_listener: TableEditListener = None
        self.field_count = default_field_count
        self.expenditures_set = False

        # set up and process the optional arguments
        self.title_font = default_title_font
        self.head_font = default_table_head_font
        self.entry_font = default_entry_font
        self.title_text = default_title_text
        self.table_widget_name = None
        self.process_optional_arguments(optional_arguments)

        # sets up the title label
        self.head_label: tkinter.Label = None
        self.setup_title_label()

        # set up the edit button
        self.edit_button = None
        self.done_button = None
        self.setup_edit_button()

        # sets up the balance table
        self.balance_table: TableWidget = None
        self.setup_balance_table()
        self.balance_table.hide_config_buttons()

    def add_listener(self, listener):
        self.table_edit_listener = listener

    def process_optional_arguments(self, optional_arguments):
        # processes optional arguments passed to the Balance Widget
        # store the label fonts
        if 'title_font' in optional_arguments:
            self.title_font = optional_arguments['title_font']
        if 'head_font' in optional_arguments:
            self.head_font = optional_arguments['head_font']
        if 'entry_font' in optional_arguments:
            self.entry_font = optional_arguments['entry_font']
        # stores the name
        if 'name' in optional_arguments:
            self.title_text = optional_arguments['name']
            if self.title_text == "Initial Balance":
                self.table_widget_name = "initialBalances"
            elif self.title_text == "Current Balance":
                self.table_widget_name = "currentBalances"

    def setup_title_label(self):
        # adds a title label above the table
        self.head_label = tkinter.Label(self)
        self.head_label.config(text=self.title_text, font=self.title_font)
        self.head_label.grid(row=0, column=0, sticky="E")

    def setup_edit_button(self):
        self.edit_button = tkinter.Button(self, text="Edit", command=lambda: self.edit_pressed())
        self.done_button = tkinter.Button(self, text="Done", command=lambda: self.done_pressed())
        self.edit_button.grid(row=0, column=1, sticky="W")

    def edit_pressed(self):
        if self.expenditures_set:
            self.balance_table.show_config_buttons()
            self.edit_button.grid_forget()
            self.done_button.grid(row=0, column=1, sticky="W")

    def done_pressed(self):
        self.balance_table.hide_config_buttons()
        self.done_button.grid_forget()
        self.edit_button.grid(row=0, column=1, sticky="W")

    def send_edit_to_database(self, table_name: str, row_index: int, values):
        # passes the row values to the listener to the DatabaseModel to be processed and stored in the database
        value_dict = {'amount': TableWidget.unformat_from_currency(values[1]), 'source': values[0]}
        self.table_edit_listener.send_edit_to_database(table_name, row_index, value_dict)

    def setup_balance_table(self):
        # invert_axis is True because the data will be added in cols
        self.balance_table = TableWidget(self, 2, self.field_count, table_name=self.table_widget_name,
                                         invert_axis=True, column_widths=default_field_col_widths,
                                         head_font=self.head_font, entry_font=self.entry_font,
                                         header_widths=default_header_widths)
        self.balance_table.add_listener(self)
        self.balance_table.set_header_values(['Source', 'Amount'])
        self.balance_table.grid(row=1, columnspan=2)

    def set_balances(self, balance_matrix: [[]]):
        # sets the values in the balances table given the balance matrix
        table = []
        for row_index in range(len(balance_matrix)):
            values = [balance_matrix[row_index][1],
                      TableWidget.format_as_currency(balance_matrix[row_index][2])]
            table.append(values)
        self.balance_table.load_table_data(table)
        self.expenditures_set = True

    def set_colors(self, color_dict: {str: str}):
        self.colors = color_dict
        self.update_colors()

    def update_colors(self):
        if self.colors is not None:
            self.config(bg=self.colors['bg_col'])
            self.head_label.config(bg=self.colors['bg_col'], fg=self.colors['text_col'])
            self.balance_table.set_colors(self.colors)
            self.edit_button.config(fg=self.colors['button_col']['button_text_col'],
                                    highlightbackground=self.colors['button_col']['button_bg_col'],
                                    activeforeground=self.colors['button_col']['button_pressed_text'],
                                    activebackground=self.colors['button_col']['button_pressed_bg'])
            self.done_button.config(fg=self.colors['button_col']['button_text_col'],
                                    highlightbackground=self.colors['button_col']['button_bg_col'],
                                    activeforeground=self.colors['button_col']['button_pressed_text'],
                                    activebackground=self.colors['button_col']['button_pressed_bg'])
class DataVisualizer(tkinter.LabelFrame):
    def __init__(self, parent, **optional_arguments):
        tkinter.LabelFrame.__init__(self,
                                    parent,
                                    text=optional_arguments['text'])
        self.colors = None

        # setup default parameters and then process optional arguments
        self.field_count = default_field_count
        self.process_optional_arguments(optional_arguments)

        # setup the table showing initial balance, current balance, and expenditure totals
        self.totals_table: TableWidget = None
        self.load_total_amounts()

        # sets up a separator between the two tables
        separator = Separator(self)
        separator.grid(row=0, column=1, sticky="NS")

        # setup the table showing spending by category
        self.category_table: TableWidget = None
        self.load_spending_by_category()

        # setup the pie chart
        self.pie_chart = PieChart(self)
        self.pie_chart.grid(row=1, columnspan=3)

        self.load_table_data(None, None, None)

    def process_optional_arguments(self, optional_arguments):
        if 'field_count' in optional_arguments.keys():
            self.field_count = optional_arguments['field_count']

    def load_spending_by_category(self):
        self.category_table = TableWidget(self,
                                          2,
                                          self.field_count,
                                          head_font=default_table_head_font,
                                          entry_font=default_entry_font,
                                          entry_justify_list=["right", "left"],
                                          head_justify_list=["right", "left"])
        self.category_table.hide_config_buttons()
        self.category_table.set_header_values(['Category', 'Amount'])
        self.category_table.grid(row=0, column=2)

    def load_total_amounts(self):
        self.totals_table = TableWidget(
            self,
            3,
            1,
            entry_font=default_entry_font,
            entry_justify=["left"],
            head_justify_list=["right", "right", "right"],
            invert_axis=True)
        self.totals_table.hide_config_buttons()
        self.totals_table.set_header_values(
            ["Initial Total", "Expenditure Total", "Current Total"])
        self.totals_table.grid(row=0, column=0)

    def load_table_data(self, expenditures_by_type: [[]], initial_balances,
                        current_balances):
        self.load_expenditure_data(expenditures_by_type)
        self.load_totals_data(initial_balances, expenditures_by_type,
                              current_balances)
        self.update_colors()

    def load_expenditure_data(self, expenditures_by_type: [[]]):
        if expenditures_by_type is not None and expenditures_by_type != []:
            labels = []
            values = []
            table = []
            for row_index in range(len(expenditures_by_type)):
                labels.append(expenditures_by_type[row_index][0])
                values.append(expenditures_by_type[row_index][1])
                table.append([
                    expenditures_by_type[row_index][0],
                    TableWidget.format_as_currency(
                        expenditures_by_type[row_index][1])
                ])
            self.category_table.load_table_data(table)
            self.pie_chart.construct_pie_chart(
                labels, values, text_col=self.pie_chart.label_text_col)
        else:
            self.category_table.clear_labels()
            self.pie_chart.construct_empty_chart()

    def load_totals_data(self, initial_balances, expenditures_by_type,
                         current_balances):
        if expenditures_by_type is not None and expenditures_by_type != []:
            total_spending = 0
            for row in expenditures_by_type:
                total_spending += row[1]
            spending_text = TableWidget.format_as_currency(total_spending)
            self.totals_table.set_value(spending_text, 0, 1)
        else:
            self.totals_table.set_value("-", 0, 1)

        if initial_balances is not None and initial_balances != []:
            total_initial_balance = 0
            for balance in initial_balances:
                total_initial_balance += balance[2]
            initial_text = TableWidget.format_as_currency(
                total_initial_balance)
            self.totals_table.set_value(initial_text, 0, 0)
        else:
            self.totals_table.set_value("-", 0, 0)

        if current_balances is not None and current_balances != []:
            total_current_balance = 0
            for balance in current_balances:
                total_current_balance += balance[2]
            current_text = TableWidget.format_as_currency(
                total_current_balance)
            self.totals_table.set_value(current_text, 0, 2)
        else:
            self.totals_table.set_value("-", 0, 2)

    def set_colors(self, color_dict: {str: str}):
        self.colors = color_dict
        self.update_colors()

    def update_colors(self):
        if self.colors is not None:
            self.config(bg=self.colors['bg_col'], fg=self.colors['text_col'])
            self.pie_chart.set_colors(self.colors['pie_chart_colors'])
            self.category_table.set_colors(
                self.colors['category_table_colors'])
            self.totals_table.set_colors(self.colors['totals_table_colors'])
Exemple #21
0
class MainWindow(QtGui.QMainWindow):

    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent) 
        self.loadIcons()   
        self.setupUserInterface() 
        self.setupSignals()    
        self.__version__ = __version__
        # Initialise variables
        self.imageFiles = {}
        self.timeData   = None
        self.plotWin    = None
        self.imageWin   = None
        self.BMDchange  = None
        self.roiNames   = None  
        
    def loadIcons(self):
        """ Load icons """
        self.icons = dict([
            ('BMDanalyseIcon', QtGui.QIcon(os.path.join(absDirPath,"icons","logo.png"))),
            ('imageAddIcon',   QtGui.QIcon(os.path.join(absDirPath,"icons","file_add.png"))),
            ('imageRemIcon',   QtGui.QIcon(os.path.join(absDirPath,"icons","file_delete2.png"))),
            ('imageDownIcon',  QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-up-2.png"))),
            ('imageUpIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-down-2.png"))),
            ('imagePrevIcon',  QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-left.png"))),
            ('imageNextIcon',  QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-right.png"))),          
            ('roiAddIcon',     QtGui.QIcon(os.path.join(absDirPath,"icons","green-add3.png"))),
            ('roiRectIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","rectangularIcon.png"))),
            ('roiPolyIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","polygonIcon.png"))),
            ('roiRemIcon',     QtGui.QIcon(os.path.join(absDirPath,"icons","red_delete.png"))),
            ('roiSaveIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","filesave.png"))),
            ('roiCopyIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","file_copy.png"))),
            ('roiLoadIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","opened-folder.png")))])
        
    def setupUserInterface(self):
        """ Initialise the User Interface """
        # Left frame
        leftFrame = QtGui.QFrame()
        leftFrameLayout = QtGui.QHBoxLayout() 
        leftFrame.setLayout(leftFrameLayout)
        leftFrame.setLineWidth(0)
        leftFrame.setFrameStyle(QtGui.QFrame.Panel)
        leftFrameLayout.setContentsMargins(0,0,5,0)
        # Left frame contents     
        self.viewMain = GraphicsLayoutWidget()  # A GraphicsLayout within a GraphicsView 
        leftFrameLayout.addWidget(self.viewMain)
        self.viewMain.setMinimumSize(200,200)
        self.vb = MultiRoiViewBox(lockAspect=True,enableMenu=True)
        self.viewMain.addItem(self.vb)
        self.vb.disableAutoRange()
        # Right frame
        self.sidePanel = SidePanel(self) 
        # UI window (containing left and right frames)
        UIwindow         = QtGui.QWidget(self)
        UIwindowLayout   = QtGui.QHBoxLayout()
        UIwindowSplitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
        UIwindowLayout.addWidget(UIwindowSplitter)
        UIwindow.setLayout(UIwindowLayout)
        self.setCentralWidget(UIwindow)
        UIwindowSplitter.addWidget(leftFrame)
        UIwindowSplitter.addWidget(self.sidePanel)  
        # Application window
        self.setWindowTitle('BMDanalyse')
        self.setWindowIcon(self.icons['BMDanalyseIcon'])
        self.setMinimumSize(600,500)
        self.resize(self.minimumSize())
        # Window menus       
        self.createMenus()     
        self.createActions() 

    def createMenus(self):
        # Menus 
        menubar          = self.menuBar()
        self.fileMenu    = menubar.addMenu('&File')
        self.imageMenu   = menubar.addMenu('&Images')
        self.roiMenu     = menubar.addMenu('&ROIs')
        self.submenu     = self.roiMenu.addMenu(self.icons['roiAddIcon'],"Add ROI")
        self.analyseMenu = menubar.addMenu('&Analysis')
        self.aboutMenu   = menubar.addMenu('A&bout')
        
    def createActions(self):    
        # Actions for File menu
        self.exitAct     = QtGui.QAction("&Quit", self, shortcut="Ctrl+Q",statusTip="Exit the application")
        self.exitAct.triggered[()].connect(self.close)
        self.fileMenu.addAction(self.exitAct)
        # Actions for Images menu
        self.loadImageAct   = QtGui.QAction(self.icons['imageAddIcon'], "&Load image(s)",        self, shortcut="Ctrl+L")
        self.removeImageAct = QtGui.QAction(self.icons['imageRemIcon'], "&Remove current image", self, shortcut="Ctrl+X")  
        imageMenuActions  = [self.loadImageAct,self.removeImageAct]
        imageMenuActFuncs = [self.loadImages,self.removeImage]
        for i in xrange(len(imageMenuActions)):
            action   = imageMenuActions[i]
            function = imageMenuActFuncs[i]
            action.triggered[()].connect(function)
        self.imageMenu.addAction(self.loadImageAct)
        self.imageMenu.addAction(self.removeImageAct)
        # Actions for ROI menu
        self.addROIRectAct = QtGui.QAction("Rectangular",self.submenu)
        self.addROIPolyAct = QtGui.QAction("Polygon",self.submenu)
        self.addROIRectAct.triggered[()].connect(self.vb.addROI)
        self.addROIPolyAct.triggered[()].connect(self.vb.addPolyRoiRequest) 
        self.submenu.addAction(self.addROIRectAct)
        self.submenu.addAction(self.addROIPolyAct)    
        self.addROIRectAct.setIcon(self.icons['roiRectIcon'])
        self.addROIPolyAct.setIcon(self.icons['roiPolyIcon'])
        self.addROIRectAct.setShortcut("Ctrl+Shift+R")
        self.addROIPolyAct.setShortcut("Ctrl+Shift+P")  
        self.loadRoiAct = QtGui.QAction(self.icons['roiLoadIcon'], "L&oad ROI",   self, shortcut="Ctrl+O")                          
        self.copyRoiAct = QtGui.QAction(self.icons['roiCopyIcon'], "&Copy ROI",   self, shortcut="Ctrl+C")     
        self.saveRoiAct = QtGui.QAction(self.icons['roiSaveIcon'], "&Save ROI",   self, shortcut="Ctrl+S") 
        self.remRoiAct  = QtGui.QAction(self.icons['roiRemIcon'] , "&Remove ROI", self, shortcut="Ctrl+D")
        roiMenuActions  = [self.loadRoiAct,self.copyRoiAct,self.saveRoiAct,self.remRoiAct]
        roiMenuActFuncs = [self.vb.loadROI,self.vb.copyROI,self.vb.saveROI,self.vb.removeROI]        
        for i in xrange(len(roiMenuActions)):
            action   = roiMenuActions[i]
            function = roiMenuActFuncs[i]
            action.triggered[()].connect(function)
            self.roiMenu.addAction(action)
        # Actions for Analyse menu
        self.roiAnalysisAct = QtGui.QAction("&ROI analysis", self.viewMain, shortcut="Ctrl+R",triggered=self.getBMD)
        self.imgAnalysisAct = QtGui.QAction("&Image analysis", self.viewMain, shortcut="Ctrl+I",triggered=self.imageAnalysis)
        self.analyseMenu.addAction(self.roiAnalysisAct) 
        self.analyseMenu.addAction(self.imgAnalysisAct)
        # Actions for 
        self.aboutAct = QtGui.QAction("&About", self.viewMain, shortcut='F1', triggered=self.onAbout)
        self.aboutMenu.addAction(self.aboutAct)
        
    def setupSignals(self):
        """ Setup signals """
        self.sidePanel.imageFileList.itemSelectionChanged.connect(self.getImageToDisplay)
        self.sidePanel.buttImageAdd.clicked.connect(self.loadImages)
        self.sidePanel.buttImageRem.clicked.connect(self.removeImage)
        self.sidePanel.buttImageUp.clicked.connect(self.sidePanel.moveImageUp)
        self.sidePanel.buttImageDown.clicked.connect(self.sidePanel.moveImageDown) 
        
        self.sidePanel.roiMenu.button1.clicked[()].connect(self.vb.addROI)
        self.sidePanel.roiMenu.button2.clicked[()].connect(self.vb.addPolyRoiRequest)           

        self.sidePanel.buttRoiCopy.clicked[()].connect(self.vb.copyROI)
        self.sidePanel.buttRoiRem.clicked.connect(self.vb.removeROI)        
        self.sidePanel.buttRoiLoad.clicked.connect(self.vb.loadROI)
        self.sidePanel.buttRoiSave.clicked.connect(self.vb.saveROI)
    
        self.sidePanel.buttRoiAnalysis.clicked.connect(self.getBMD)
        self.sidePanel.buttImgAnalysis.clicked.connect(self.imageAnalysis)
        
    def onAbout(self):
        """ About BMDanalyse message"""
        author  ='Michael Hogg'
        date    ='2016'        
        version = self.__version__
            
        QtGui.QMessageBox.about(self, 'About BMDanalyse', 
            """
            <b>BMDanalyse</b>
            <p>A simple program for the analysis of a time series of Bone Mineral Density (BMD) images.</p>
            <p>Used to evaluate the bone gain / loss in a number of regions of interest (ROIs) over time, 
            typically due to bone remodelling as a result of stress shielding around an orthopaedic implant.</p>
            <p><table border="0" width="150">
            <tr>
            <td>Author:</td>
            <td>%s</td>
            </tr>
            <tr>
            <td>Version:</td>
            <td>%s</td>
            </tr>
            <tr>
            <td>Date:</td>
            <td>%s</td>
            </tr>            
            </table></p>
            """ % (author,version,date))
    
    def loadImages(self):
        """ Load an image to be analysed """
        newImages = {}
        fileNames = QtGui.QFileDialog.getOpenFileNames(self, self.tr("Load images"),QtCore.QDir.currentPath())
        # Fix for PySide. PySide doesn't support QStringList types. PyQt4 getOpenFileNames returns a QStringList, whereas PySide
        # returns a type (the first entry being the list of filenames).
        if isinstance(fileNames,types.TupleType): fileNames = fileNames[0]
        if hasattr(QtCore,'QStringList') and isinstance(fileNames, QtCore.QStringList): fileNames = [str(i) for i in fileNames]
        if len(fileNames)>0:
            for fileName in fileNames:
                if fileName!='':
                    img    = Image.open(str(fileName))
                    imgarr = np.array(img.convert('L'))  # Convert to 8-bit
                    imgarr = imgarr.swapaxes(0,1)
                    imgarr = imgarr[:,::-1]                
                    newImages[fileName] = imgarr
            # Add filenames to list widget. Only add new filenames. If filename exists aready, then
            # it will not be added, but data will be updated
            for fileName in sorted(newImages.keys()):
                if not self.imageFiles.has_key(fileName):
                    self.sidePanel.addImageToList(fileName)
                self.imageFiles[fileName] = newImages[fileName]
            # Show image in Main window
            self.vb.enableAutoRange()
            if self.sidePanel.imageFileList.currentRow()==-1: 
                self.sidePanel.imageFileList.setCurrentRow(0)
            self.showImage(str(self.sidePanel.imageFileList.currentItem().text()))
            self.vb.disableAutoRange()            
            
    def removeImage(self):
        """ Remove image from sidePanel imageFileList """
        # Return if there is no image to remove
        if self.vb.img is None: return
        # Get current image in sidePanel imageFileList and remove from list
        currentRow = self.sidePanel.imageFileList.currentRow()
        image      = self.sidePanel.imageFileList.takeItem(currentRow)
        imageName  = str(image.text())
        # Delete key and value from dictionary 
        if imageName!='': del self.imageFiles[imageName]
        # Get image item in imageFileList to replace deleted image
        if self.sidePanel.imageFileList.count()==0:
            self.vb.enableAutoRange()
            self.vb.removeItem(self.vb.img)
            self.vb.showImage(None)
            self.vb.disableAutoRange()
        else: 
            currentRow = self.sidePanel.imageFileList.currentRow()
            imageName  = str(self.sidePanel.imageFileList.item(currentRow).text())
            self.showImage(imageName)   

    def showImage(self,imageFilename):
        """ Shows image in main view """
        self.arr = self.imageFiles[imageFilename]
        self.vb.showImage(self.arr)
    
    def getImageToDisplay(self):
        """ Get current item in file list and display in main view"""
        try:    imageFilename = str(self.sidePanel.imageFileList.currentItem().text())
        except: pass
        else:   self.showImage(imageFilename)  

    def getBMD(self):
        """ Get change in BMD over time (e.g. for each image) for all ROIs. 
            
            Revised function that converts the list of images into a 3D array
            and then uses the relative position of the ROIs to the current
            image, self.vb.img, to get the average BMD value e.g. it doesn't use
            setImage to change the image in the view. This requires that all
            images are the same size and in the same position.
        """
        # Return if there is no image or rois in view
        if self.vb.img is None or len(self.vb.rois)==0: return               
        # Collect all images into a 3D array
        imageFilenames = self.sidePanel.getListOfImages()
        images    = [self.imageFiles[str(name.text())] for name in imageFilenames]
        imageData = np.dstack(images) # Doesn't work correctly if images are not all the same shape
        numImages = len(images)           
        # Get BMD across image stack for each ROI
        numROIs = len(self.vb.rois)
        BMD     = np.zeros((numImages,numROIs),dtype=float) 
        self.roiNames = []   
        for i in xrange(numROIs):
            roi = self.vb.rois[i]
            self.roiNames.append(roi.name)
            arrRegion   = roi.getArrayRegion(imageData,self.vb.img, axes=(0,1))
            avgROIvalue = arrRegion.mean(axis=0).mean(axis=0)
            BMD[:,i]    = avgROIvalue
        # Calculate the BMD change (percentage of original)
        tol = 1.0e-06
        for i in xrange(numROIs):
            if abs(BMD[0,i])<tol: 
                BMD[:,i] = 100.
            else: 
                BMD[:,i] = BMD[:,i] / BMD[0,i] * 100.
        self.BMDchange = BMD-100.
        if self.timeData is None or self.timeData.size!=numImages:
            self.timeData = np.arange(numImages,dtype=float)
        # Plot results  
        self.showResults()
        
    def imageAnalysis(self):
        # Generate images of BMD change
        if self.vb.img is None: return
        self.showImageWin()
        
    def sliderValueChanged(self,value):
        self.imageWin.sliderLabel.setText('BMD change: >= %d %s' % (value,'%'))
        self.setLookupTable(value)
        self.imageWin.vb.img2.setLookupTable(self.lut)
        self.imageWin.vb.img2.setLevels([0,255])
        
    def setLookupTable(self,val):
        lut = []
        for i in range(256):
            if   i > 127+val:
                lut.append(matplotlib.cm.jet(255))
            elif i < 127-val:    
                lut.append(matplotlib.cm.jet(0))
            else:
                lut.append((0.0,0.0,0.0,0.0)) 
        lut = np.array(lut)*255
        self.lut = np.array(lut,dtype=np.ubyte)
     
    def createImageWin(self):
        self.buttMinimumSize = QtCore.QSize(70,36)
        self.iconSize = QtCore.QSize(24,24)
        if self.imageWin==None:
            self.imageWin = QtGui.QDialog(self, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |  \
                                          QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint)
            self.imageWin.setWindowTitle('BMDanalyse')
            self.imageWin.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.imageWin.setMinimumSize(250,500)
            self.imageWin.resize(self.imageWin.minimumSize()) 
            # Create viewBox  
            self.imageWin.glw = GraphicsLayoutWidget()  # A GraphicsLayout within a GraphicsView 
            self.imageWin.vb  = ImageAnalysisViewBox(lockAspect=True,enableMenu=True)
            self.imageWin.vb.disableAutoRange()
            self.imageWin.glw.addItem(self.imageWin.vb) 
            arr = self.imageFiles.values()[0]
            self.imageWin.vb.img1 = ImageItem(arr,autoRange=False,autoLevels=False)
            self.imageWin.vb.addItem(self.imageWin.vb.img1)      
            self.imageWin.vb.img2 = ImageItem(None,autoRange=False,autoLevels=False)
            self.imageWin.vb.addItem(self.imageWin.vb.img2)
            self.imageWin.vb.autoRange()
            lut = [ [ int(255*val) for val in matplotlib.cm.gray(i)[:3] ] for i in xrange(256) ]
            lut = np.array(lut,dtype=np.ubyte)         
            self.imageWin.vb.img1.setLookupTable(lut)
            # Label to show index of current image label
            self.imageCurrCont = QtGui.QFrame()
            self.imageCurrCont.setLineWidth(2)
            self.imageCurrCont.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised)
            self.imageCurrCont.setMinimumWidth(70)
            self.imageWin.currLabel = QtGui.QLabel("")
            self.imageWin.currLabel.setAlignment(QtCore.Qt.AlignHCenter)            
            imageCurrContLayout = QtGui.QHBoxLayout()
            imageCurrContLayout.addWidget(self.imageWin.currLabel)
            self.imageCurrCont.setLayout(imageCurrContLayout)  
            # Create buttons to select images
            self.imageWin.buttCont = QtGui.QWidget()
            self.imageWin.buttPrev = QtGui.QPushButton(self.icons['imagePrevIcon'],"")
            self.imageWin.buttNext = QtGui.QPushButton(self.icons['imageNextIcon'],"")
            self.buttLayout = QtGui.QHBoxLayout()
            self.buttLayout.addStretch(1)
            self.buttLayout.addWidget(self.imageWin.buttPrev)
            self.buttLayout.addWidget(self.imageCurrCont)
            self.buttLayout.addWidget(self.imageWin.buttNext)
            self.buttLayout.addStretch(1)
            self.imageWin.buttCont.setLayout(self.buttLayout)
            self.imageWin.buttPrev.setMinimumSize(self.buttMinimumSize)
            self.imageWin.buttNext.setMinimumSize(self.buttMinimumSize)
            self.imageWin.buttPrev.setIconSize(self.iconSize) 
            self.imageWin.buttNext.setIconSize(self.iconSize)
            self.buttLayout.setContentsMargins(0,5,0,5)
            self.imageWin.buttPrev.clicked.connect(self.prevImage)
            self.imageWin.buttNext.clicked.connect(self.nextImage)
            # Create slider    
            self.imageWin.sliderCon = QtGui.QWidget()
            self.imageWin.slider = QtGui.QSlider(self)
            self.imageWin.slider.setOrientation(QtCore.Qt.Horizontal)
            self.imageWin.slider.setMinimum(1)
            self.imageWin.slider.setMaximum(100)
            self.imageWin.slider.setMinimumWidth(100)
            self.imageWin.slider.valueChanged.connect(self.sliderValueChanged)
            self.imageWin.sliderLabel = QtGui.QLabel('1')
            self.imageWin.sliderLabel.setMinimumWidth(120)
            self.sliderLayout = QtGui.QHBoxLayout()
            self.sliderLayout.addStretch(1)
            self.sliderLayout.addWidget(self.imageWin.sliderLabel)
            self.sliderLayout.addWidget(self.imageWin.slider)
            self.sliderLayout.addStretch(1)
            self.imageWin.sliderCon.setLayout(self.sliderLayout)
            self.sliderLayout.setContentsMargins(0,0,0,5)
            # Format image window
            self.imageWinLayout = QtGui.QVBoxLayout()
            self.imageWinLayout.addWidget(self.imageWin.glw)
            self.imageWinLayout.addWidget(self.imageWin.buttCont)
            self.imageWinLayout.addWidget(self.imageWin.sliderCon)
            self.imageWin.setLayout(self.imageWinLayout)
            self.imageWin.imagesRGB = None
        # Show
        self.imageWin.show()
        self.imageWin.slider.setValue(10)
        self.sliderValueChanged(10)
        self.imageWinIndex = 0
        
    def prevImage(self):
        minIndex  = 0
        currIndex = self.imageWinIndex 
        prevIndex = currIndex - 1 
        self.imageWinIndex = max(prevIndex,minIndex)    
        self.updateImageWin()
        
    def nextImage(self):
        numImages = len(self.imageFiles)
        maxIndex  = numImages - 1
        currIndex = self.imageWinIndex
        nextIndex = currIndex + 1 
        self.imageWinIndex = min(nextIndex,maxIndex)
        self.updateImageWin()
        
    def updateImageWin(self):
        imageFilenames = self.sidePanel.getListOfImages()
        imageName      = imageFilenames[self.imageWinIndex]
        self.imageWin.vb.img1.setImage(self.imageFiles[str(imageName.text())],autoLevels=False) 
        self.imageWin.vb.img2.setImage(self.imageWin.imagesRGB[self.imageWinIndex],autoLevels=False) 
        self.imageWin.currLabel.setText("%i / %i" % (self.imageWinIndex+1,len(imageFilenames)))
        
    def showImageWin(self):
        self.createImageWin()
        self.imagesBMDpercentChange()
        self.updateImageWin()

    def imagesBMDpercentChange(self):
        # Get image arrays and convert to an array of floats
        imageFilenames = self.sidePanel.getListOfImages()
        images         = [ self.imageFiles[str(name.text())] for name in imageFilenames ]
        imagesConv = []
        for img in images: 
            image = img.copy()
            image[np.where(image==0)] = 1
            image = image.astype(np.float)
            imagesConv.append(image)
        # Calculate percentage change and set with limits -100% to +100%
        imagesPercCh = []
        imageInitial = imagesConv[0]
        for image in imagesConv:
            imagePercCh = (image-imageInitial)/imageInitial*100.
            imagePercCh[np.where(imagePercCh> 100.)] =  100.
            imagePercCh[np.where(imagePercCh<-100.)] = -100.
            imagesPercCh.append(imagePercCh)
        numImages  = len(imagesPercCh)
        self.imageWin.imagesRGB = []    
        for i in xrange(numImages):
            image = imagesPercCh[i]
            sx,sy = image.shape 
            imageRGB = image*(255/200.)+(255/2.)
            self.imageWin.imagesRGB.append(imageRGB)
        
    def BMDtoCSVfile(self):
        """ Write BMD change to csv file """
        fileName = QtGui.QFileDialog.getSaveFileName(None,self.tr("Export to CSV"),QtCore.QDir.currentPath(),self.tr("CSV (*.csv)"))
        # Fix for PyQt/PySide compatibility. PyQt returns a QString, whereas PySide returns a tuple (first entry is filename as string)        
        if isinstance(fileName,types.TupleType): fileName = fileName[0]
        if hasattr(QtCore,'QString') and isinstance(fileName, QtCore.QString): fileName = str(fileName)            
        if not fileName=='':                     
            textFile  = open(fileName,'w')
            numFrames, numROIs = self.BMDchange.shape    
            roiNames = self.roiNames
            header  = "%10s," % 'Time'
            header += ((numROIs-1)*'%10s,'+'%10s\n') % tuple(roiNames)
            textFile.write(header)
            for i in xrange(numFrames):
                textFile.write('%10.1f,' % self.timeData[i])
                for j in xrange(numROIs):
                    if j<numROIs-1: fmt = '%10.3f,'
                    else:           fmt = '%10.3f\n'
                    textFile.write(fmt % self.BMDchange[i,j])
            textFile.close()       

    def showResults(self,):
        """ Plots BMD change using matplotlib """
        # Create plot window       
        if self.plotWin==None:
            self.plotWin = QtGui.QDialog(self, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |  \
                                         QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint)
            self.plotWin.setWindowTitle('BMDanalyse')
            self.plotWin.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.plotWin.setMinimumSize(600,500)
            self.plotWin.resize(self.minimumSize()) 
            # Create Matplotlib widget
            self.mplw = MatplotlibWidget(size=(5,6))
            self.fig  = self.mplw.getFigure()
            self.editDataButton  = QtGui.QPushButton('Edit plot')
            self.exportCSVButton = QtGui.QPushButton('Export data')
            self.mplw.toolbar.addWidget(self.editDataButton)
            self.mplw.toolbar.addWidget(self.exportCSVButton)
            self.editDataButton.clicked.connect(self.showEditBox)
            self.exportCSVButton.clicked.connect(self.BMDtoCSVfile)
            # Format plot window
            self.plotWinLayout = QtGui.QVBoxLayout()
            self.plotWinLayout.addWidget(self.mplw)
            self.plotWin.setLayout(self.plotWinLayout)
        self.createFigure()
        self.plotWin.show()
        self.mplw.draw()
        
    def createFigure(self):
        """ Creates plot of results """
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.clear()
        self.fig.subplots_adjust(bottom=0.15,top=0.85,left=0.15,right=0.925)
        numFrames, numROIs = self.BMDchange.shape
        t = self.timeData
        # Plot data
        for i in xrange(numROIs):
            roiname = self.roiNames[i]
            self.ax1.plot(t,self.BMDchange[:,i],'-o',label=roiname,linewidth=2.0)
        kwargs = dict(y=1.05)  # Or kwargs = {'y':1.05}
        self.ax1.set_title('Change in Bone Mineral Density over time',fontsize=14,fontweight='roman',**kwargs)
        self.ax1.set_xlabel('Time',fontsize=10)
        self.ax1.set_ylabel('Change in BMD (%)',fontsize=10)
        self.ax1.legend(loc=0)
        matplotlib.pyplot.setp(self.ax1.get_xmajorticklabels(),  fontsize=10)
        matplotlib.pyplot.setp(self.ax1.get_ymajorticklabels(),  fontsize=10)
        matplotlib.pyplot.setp(self.ax1.get_legend().get_texts(),fontsize=10)  
        self.ax1.grid()  

    def fillEditBox(self):
        rows,cols = self.BMDchange.shape
        for i in xrange(rows):
            itmValue = '%.2f' % self.timeData[i]
            itm      = QtGui.QTableWidgetItem(itmValue)
            self.tableResults.setItem(i,0,itm)
            for j in xrange(cols):
                itmValue = '%.2f' % self.BMDchange[i,j]
                itm = QtGui.QTableWidgetItem(itmValue)
                self.tableResults.setItem(i,j+1,itm)

    def showEditBox(self):
        self.plotWin.editBox = QtGui.QDialog(self.plotWin, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
        self.plotWin.editBox.setWindowIcon(self.icons['BMDanalyseIcon']) 
        self.plotWin.editBox.setWindowTitle('BMDanalyse') 
        self.plotWin.editBox.setModal(True)
        # Add table
        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(10,10,10,10)
        layout.setSpacing(20)
        rows,cols = self.BMDchange.shape
        self.tableResults = TableWidget(rows,cols+1,self.plotWin.editBox)
        self.tableResults.verticalHeader().setVisible(True)
        # Set headers
        self.tableResults.setHorizontalHeaderItem(0,QtGui.QTableWidgetItem('Time'))
        for i in xrange(cols):
            header = QtGui.QTableWidgetItem(self.roiNames[i])
            self.tableResults.setHorizontalHeaderItem(i+1,header)
        # Add values to table
        self.fillEditBox()
        # Set layout
        layout.addWidget(self.tableResults)
        self.buttonsFrame  = QtGui.QFrame()
        self.buttonsLayout = QtGui.QHBoxLayout()
        self.buttonReset   = QtGui.QPushButton('Reset')
        self.buttonSave    = QtGui.QPushButton('Save')
        self.buttonClose   = QtGui.QPushButton('Cancel')
        self.buttonReset.setFixedWidth(50)
        self.buttonSave.setFixedWidth(50)
        self.buttonClose.setFixedWidth(50)
        self.buttonClose.clicked.connect(self.plotWin.editBox.close)
        self.buttonSave.clicked.connect(self.updateTableValues)
        self.buttonReset.clicked.connect(self.fillEditBox)
        self.buttonsLayout.addStretch(1)
        self.buttonsLayout.addWidget(self.buttonReset)
        self.buttonsLayout.addWidget(self.buttonSave)
        self.buttonsLayout.addWidget(self.buttonClose) 
        self.buttonsLayout.setContentsMargins(0,0,0,0) 
        self.buttonsFrame.setLayout(self.buttonsLayout)
        layout.addWidget(self.buttonsFrame)
        self.plotWin.editBox.setLayout(layout)
        self.plotWin.editBox.setMaximumSize(layout.sizeHint())
        self.plotWin.editBox.show()
        
    def updateTableValues(self):        
        # Create temporary arrays
        timeData  = self.timeData.copy()
        BMDchange = self.BMDchange.copy() 
        # Put the values from the tables into the temporary arrays
        rows = self.tableResults.rowCount()
        cols = self.tableResults.columnCount()
        for r in xrange(rows):
            for c in xrange(cols):
                item      = self.tableResults.item(r,c)
                itemValue = float(item.text())
                if c==0:
                    timeData[r] = itemValue 
                else: 
                    BMDchange[r,c-1] = itemValue
        # Check that time values are in increasing order. If so, then update arrays
        if any(np.diff(timeData)<=0):
            self.errorMessage = QtGui.QMessageBox()
            self.errorMessage.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.errorMessage.setWindowTitle('BMDanalyse')
            self.errorMessage.setText('Input error: Time values should be in order of increasing value')
            self.errorMessage.setIcon(QtGui.QMessageBox.Warning)           
            self.errorMessage.open()         
        else:         
            self.timeData  = timeData
            self.BMDchange = BMDchange
            self.createFigure()
            self.mplw.draw()
            self.plotWin.editBox.close()
Exemple #22
0
    def on_finished(self):
        self.xlow = float(self.xle1.text())
        self.xhigh = float(self.xle2.text())
        self.dx = float(self.xle3.text())
        self.ylow = float(self.yle1.text())
        self.yhigh = float(self.yle2.text())
        self.dy = float(self.yle3.text())

        if len(self.data) == 0: return

        xlow = float(self.xle1.text())
        xhigh = float(self.xle2.text())
        xdistance = float(self.xle3.text())
        ylow = float(self.yle1.text())
        yhigh = float(self.yle2.text())
        ydistance = float(self.yle3.text())
        model_Number = int(self.lineEdit.text())
        Observation_height = float(self.le3.text())

        mw = ModelWidget(self)
        mwTitle = self.le1.text()
        mwColorBarTitle = self.le2.text()
        if mwTitle == "": mwTitle = "Forwarding Model"
        mw.mpl.setTitle(mwTitle)
        densityData = []
        c = []
        b = []
        a = []
        flag = 0
        zmax = 0

        for i in range(0, len(self.data)):
            if self.data[i][0] == "Cube":
                density = float(self.data[i][4])
                densityData.append(density)

        self.densityMax = max(densityData)
        self.densityMin = min(densityData)
        if self.densityMax == self.densityMin:
            self.densityMax += 1
        mw.mpl.setRange(self.densityMin, self.densityMax)

        for i in range(0, len(self.data)):
            if self.data[i][0] == "Cube":
                flag = 1
                xlim = self.data[i][1].split(',')
                if len(xlim) == 1:
                    xlim = self.data[i][1].split(',')
                ylim = self.data[i][2].split(',')
                if len(ylim) == 1:
                    ylim = self.data[i][2].split(',')
                zlim = self.data[i][3].split(',')
                if len(zlim) == 1:
                    zlim = self.data[i][3].split(',')
                density = float(self.data[i][4])
                tem = []
                tem.append(float(zlim[0]))
                tem.append(float(zlim[1]))
                c.append(tem)
                tem1 = []
                tem1.append(float(ylim[0]))
                tem1.append(float(ylim[1]))
                b.append(tem1)
                tem2 = []
                tem2.append(float(xlim[0]))
                tem2.append(float(xlim[1]))
                a.append(tem2)
                if zmax < float(zlim[1]):
                    k = int(float(zlim[1]) / 1000)
                    yu = float(zlim[1]) - k * 1000
                    if yu > 0:
                        zmax = (k + 1) * 1000
                    else:
                        zmax = k * 1000
                mw.mpl.paintCube(xlim, ylim, zlim, density,
                                 xlow - xdistance / 2, xhigh + xdistance / 2,
                                 ylow - ydistance / 2, yhigh + ydistance / 2,
                                 zmax, 1, 1)
        self.zmax = zmax

        if mwColorBarTitle == "":
            mwColorBarTitle = "density(g/cm^3)"
        mw.mpl.setColorbar(mwColorBarTitle)

        frontView = QAction("X-Z Profile", self)
        sideView = QAction("Y-Z Profile", self)
        downView = QAction("X-Y Profile", self)
        mw.mpl.menu.addAction(frontView)
        mw.mpl.menu.addAction(sideView)
        mw.mpl.menu.addAction(downView)

        x = []
        y = []
        nx = int((xhigh - xlow) / xdistance) + 1
        ny = int((yhigh - ylow) / ydistance) + 1
        point_count = nx * ny
        for i in range(0, nx):
            x.append(xlow + i * xdistance)
        for i in range(0, ny):
            y.append(ylow + i * ydistance)

        mx = [0 for x in range(0, 2 * model_Number)]
        my = [0 for x in range(0, 2 * model_Number)]
        mz = [0 for x in range(0, 2 * model_Number)]
        for i in range(0, len(self.data)):
            if self.data[i][0] == "Cube":
                flag = 1
                xlim = self.data[i][1].split(',')
                if len(xlim) == 1:
                    xlim = self.data[i][1].split(',')
                ylim = self.data[i][2].split(',')
                if len(ylim) == 1:
                    ylim = self.data[i][2].split(',')
                zlim = self.data[i][3].split(',')
                if len(zlim) == 1:
                    zlim = self.data[i][3].split(',')
                mx[i] = float(xlim[0])
                mx[i + model_Number] = float(xlim[1])
                my[i] = float(ylim[0])
                my[i + model_Number] = float(ylim[1])
                mz[i] = float(zlim[0])
                mz[i + model_Number] = float(zlim[1])

        NX = c_int(nx)
        NY = c_int(ny)
        POINT_COUNT = c_int(point_count)
        MODEL_NUMBER = c_int(model_Number)
        XLOW = c_double(xlow)
        XDISTANCE = c_double(xdistance)
        XHIGH = c_double(xhigh)
        YLOW = c_double(ylow)
        YDISTANCE = c_double(ydistance)
        YHIGH = c_double(yhigh)
        OBSERVATION_HEIGHT = c_double(Observation_height)
        X = POINTER(c_double)((c_double * len(x))(*x))
        Y = POINTER(c_double)((c_double * len(y))(*y))
        MX = POINTER(c_double)((c_double * len(mx))(*mx))
        MY = POINTER(c_double)((c_double * len(my))(*my))
        MZ = POINTER(c_double)((c_double * len(mz))(*mz))
        DENSITYDATA = POINTER(c_double)(
            (c_double * len(densityData))(*densityData))
        ll = cdll.LoadLibrary
        Objdll = ll("./Forwarding_DLL.dll")
        func = Objdll.Forwarding
        func.argtypes = (c_int, c_int,c_int,c_int, c_double,c_double,c_double,c_double,c_double, c_double,  c_double, \
        POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double))
        func.restype = POINTER(c_double)

        data_result = []
        data_result = Objdll.Forwarding(NX, NY, POINT_COUNT, MODEL_NUMBER, XLOW, XDISTANCE, XHIGH, YLOW, YDISTANCE,\
        YHIGH, OBSERVATION_HEIGHT, X, Y, MX, MY, MZ, DENSITYDATA)

        F_Data = []
        for i in range(0, len(y)):
            for j in range(0, len(x)):
                temp = []
                for k in range(0, 7):
                    temp.append(
                        float(data_result[k * point_count + j + i * len(x)]))
                temp.append(x[j])
                temp.append(y[i])
                F_Data.append(temp)

        headTitle = ['0', 'V', 'X', 'Y']
        if flag == 1:
            headTitle = [
                '0', 'Vxx', 'Vxy', 'Vxz', 'Vyy', 'Vyz', 'Vzz', 'Vz', 'X', 'Y'
            ]
        tableWidget = TableWidget(self.father, F_Data, headTitle, 0, 0)
        tableWidget.forwardingInformation = tableWidget.forwardingInformation + "X-Range:" + str(
            xlow) + "m-" + str(xhigh) + "m  dx" + str(xdistance) + "m\n"
        tableWidget.forwardingInformation = tableWidget.forwardingInformation + "Y-Range:" + str(
            ylow) + "m-" + str(yhigh) + "m  dy" + str(ydistance) + "m\n"
        tableWidget.forwardingInformation = tableWidget.forwardingInformation + "Observation height:" + str(
            Observation_height) + "m\n"
        tableWidget.forwardingInformation = tableWidget.forwardingInformation + self.information

        position = self.father.tab.currentIndex()
        root = self.father.tree.topLevelItem(position - 1)
        s = root.text(0)
        title = 'Data'
        num = 0
        while title in self.father.tree_record[s]:
            num += 1
            title = 'Data' + str(num)
        frontView.triggered.connect(lambda: self.dialog(1, title))
        sideView.triggered.connect(lambda: self.dialog(2, title))
        downView.triggered.connect(lambda: self.dialog(3, title))
        sub = QMdiSubWindow()
        sub.setWindowIcon(QIcon(".\\image\\logo.png"))
        sub.setWidget(tableWidget)
        sub.setWindowTitle(title)
        sub.resize(750, 750)
        self.father.tab.widget(position).addSubWindow(sub)
        self.father.tab.widget(position).setActiveSubWindow(sub)
        sub.show()
        selectedList = self.father.tree.selectedItems()
        for i in range(0, len(selectedList)):
            selectedList[i].setSelected(0)
        self.father.tree_record[s][title] = {}
        self.father.tree_record[s][title]={'Number_of_Model':str(self.lineEdit.text()), \
        'Model_Title':str(mwTitle), 'ColorBar_Title':str(mwColorBarTitle),'Observation_height':str(self.le3.text()), \
        'xlow':str(self.xle1.text()), 'xhigh':str(self.xle2.text()), 'xdistance':str(self.xle3.text()), \
        'ylow':str(self.yle1.text()), 'yhigh':str(self.yle2.text()), 'ydistance':str(self.xle3.text()), \
        'ForwardingModel':mw, 'ForwardingModelFlag':0, 'type':'ForwardingData', 'densityMax':self.densityMax, \
        'densityMin':self.densityMin}
        for i in range(0, int(self.lineEdit.text())):
            name_temp = 'Number_' + str(i + 1)
            self.father.tree_record[s][title][name_temp] = {}
            for j in range(0, len(self.data[i])):
                self.father.tree_record[s][title][name_temp][str(j)] = str(
                    self.data[i][j])
        child1 = QTreeWidgetItem(root)
        child1.setText(0, title)
        child1.setSelected(1)
        root.setExpanded(1)
        return
Exemple #23
0
	def setupGUI(self):
		self.setWindowTitle("Sonic Viewer")
		pg.setConfigOption('background', (255,255,255))
		pg.setConfigOption('foreground',(0,0,0))
		self.layout = QtGui.QVBoxLayout()
		self.layout.setContentsMargins(0,0,0,0)
		self.layout.setSpacing(0)
		self.setLayout(self.layout)
		## setting up the menu bar
		self.menuBar = QtGui.QMenuBar()
		self.layout.setMenuBar(self.menuBar)
		self.viewMenu = self.menuBar.addMenu('View')
		self.modeMenu = self.menuBar.addMenu('Mode')
		self.transformMenu = self.menuBar.addMenu('Transform')
		self.intMenu = self.menuBar.addMenu('Interpretation')
		# VIEW MENU
		self.autoScaleButton = QtGui.QAction('Auto scale',self,checkable=True)
		self.autoScaleButton.setChecked(True)
		self.showArrivalsButton = QtGui.QAction('Arrivals',self,checkable=True)
		self.showArrivalsButton.setDisabled(True)
		self.showTableButton = QtGui.QAction('Table',self)
		self.yAxisMenu = self.viewMenu.addMenu('y axis')
		self.editGradientsButton = QtGui.QAction('Edit Gradients',self)
		self.invertYButton = QtGui.QAction('Invert y axis',self,checkable=True)
		
		self.viewMenu.addAction(self.autoScaleButton)
		self.viewMenu.addAction(self.showArrivalsButton)
		self.viewMenu.addAction(self.showTableButton)
		self.viewMenu.addAction(self.editGradientsButton)
		self.viewMenu.addAction(self.invertYButton)
		
		# MODE MENU
		self.modeGroup = QtGui.QActionGroup(self)
		self.waveFormButton = QtGui.QAction('Wave Forms',self,checkable=True)
		self.contourButton = QtGui.QAction('Contours',self,checkable=True)
		self.waveFormButton.setActionGroup(self.modeGroup)
		self.contourButton.setActionGroup(self.modeGroup)
		self.contourButton.setChecked(True)

		self.modeMenu.addAction(self.waveFormButton)
		self.modeMenu.addAction(self.contourButton)
		# INTERPRETATION MENU
		self.pickArrivalsButton = QtGui.QAction('Pick arrivals',self)
		self.handPickArrivalsButton = QtGui.QAction('Hand pick',self,checkable=True)
		self.moduliButton = QtGui.QAction('Elastic moduli',self)
		self.moduliButton.setDisabled(True)
		self.handPickArrivalsButton.setDisabled(True)

		self.intMenu.addAction(self.pickArrivalsButton)
		self.intMenu.addAction(self.handPickArrivalsButton)
		self.intMenu.addAction(self.moduliButton)
		# TRANSFORM MENU
		self.showForrierMagnitudeButton = QtGui.QAction('Fourrier magnitude',self)
		self.showForrierPhasesButton = QtGui.QAction('Fourrier phases',self)
		self.filteringButton = QtGui.QAction('Frequency filtering',self,checkable=True)
		self.transformMenu.addAction(self.showForrierMagnitudeButton)
		self.transformMenu.addAction(self.showForrierPhasesButton)
		self.transformMenu.addAction(self.filteringButton)
		# dict to store actions for y Axis
		self.yAxisButtons = {}
		self.yAxisGroup = QtGui.QActionGroup(self)
		self.yAxisButtons['Track #'] = QtGui.QAction('Track #',self,checkable=True)
		self.yAxisButtons['Track #'].setActionGroup(self.yAxisGroup)
		self.yAxisMenu.addAction(self.yAxisButtons['Track #'])
		self.yAxisButtons['Track #'].setChecked(True)

		# for wave in WaveTypes:
		# split main widget into plotting area and parameters area
		self.splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
		self.splitter.setOrientation(QtCore.Qt.Horizontal)
		self.layout.addWidget(self.splitter)
		# split parameter area into 3 for each wave
		self.treeSplitter = QtGui.QSplitter()
		self.treeSplitter.setOrientation(QtCore.Qt.Vertical)
		self.splitter.addWidget(self.treeSplitter)
		# create parameter trees
		self.trees={}
		for wave in WaveTypes:
			self.trees[wave] = ParameterTree(showHeader=False)
			self.treeSplitter.addWidget(self.trees[wave])
		# create layout for the plotting area
		self.sublayout = pg.GraphicsLayoutWidget()
		self.splitter.addWidget(self.sublayout)
		self.params = {}
		self.plots = {}
		for wave in WaveTypes:
			# create parameter instances
			self.params[wave] = Parameter.create(name=wave + ' wave',
				type='group',children=Parameters)
			self.trees[wave].setParameters(self.params[wave],showTop=True)
			# fill plotting area with 3 plots
			# self.plots[wave] = self.sublayout.addPlot()
			self.plots[wave] = self.sublayout.addPlot(viewBox=ViewBox())
			setup_plot(self.plots[wave])
			self.sublayout.nextRow()

		self.params['Sx'].param('Arrival times').param('BTA').setValue(36)
		self.params['Sx'].param('Arrival times').param('ATA').setValue(5)
		self.params['Sx'].param('Arrival times').param('DTA').setValue(20)
		self.params['Sy'].param('Arrival times').param('BTA').setValue(100)
		self.params['Sy'].param('Arrival times').param('ATA').setValue(5)
		self.params['Sy'].param('Arrival times').param('DTA').setValue(30)
		# create table widget to show arrival times
		self.QTable = TableWidget(['Number P','Number Sx','Number Sy','P','Sx','Sy'])
		# self.splitter.addWidget(self.QTable)
		self.QTable.setColumnCount(6)
		self.QTable.hide()

		self.splitter.setSizes([int(self.width()*0.30),
                                    int(self.width()*0.35),
                                    int(self.width()*0.35)
                                ])
		self.splitter.setStretchFactor(0, 0)
		self.splitter.setStretchFactor(1, 1)
		self.splitter.setStretchFactor(2, 0)