def deleteLater(self, *args): self.delete() return FigureCanvasQTAgg.deleteLater(self, *args)
class GuiProgram(Ui_sweepergui): cols = 0 sweep_id = 0 full_data = [] negative_current = False log_sweep = True stop = True decade_combo_values = ['5', '10', '25', '50'] def __init__(self, dialog): Ui_sweepergui.__init__(self) self.setupUi(dialog) # Connect "add" button with a custom function (addInputTextToListbox) self.exportButton.clicked.connect(self.export_data) self.startBtn.clicked.connect(self.startFunc) self.logRadioButton.clicked.connect(self.switch_linear) self.linRadioButton.clicked.connect(self.switch_linear) # Populate comboBox self.decadeComboBox.clear() self.decadeComboBox.addItems(self.decade_combo_values) self.decadeComboBox.setCurrentIndex(1) # Try to load last parameters from Pickle self.load_parameters() # Připojení k instrumentu #self.inst = Instrument('GPIB0::17::INSTR', visa_location='C:\WINDOWS\SysWOW64\\visa32.dll') self.inst = Instrument('GPIB0::17::INSTR', virtual=False) def artSleep(self, sleepTime): """ Čeká čas sleepTime v sekundách, zatím ale každých 50 milisekund řeší akce, o které se někdo pokoušel v GUI. """ stop_time = QtCore.QTime() stop_time.restart() while stop_time.elapsed() < sleepTime * 1000: QtWidgets.QApplication.processEvents(QtCore.QEventLoop.AllEvents, 50) def plot_figure(self): fig1 = Figure() ax1f1 = fig1.add_subplot(111) ax1f1.plot(np.random.rand(5)) self.rmmpl() self.addmpl(fig1) def plot_data(self, data): fig1 = Figure() ax1f1 = fig1.add_subplot(111) ax1f1.set_xlabel('I [A]') ax1f1.set_ylabel('U [V]') ax1f1.set_title('Sweep ID: ' + self.sweep_id) for d in data: x, y = d ax1f1.plot(x, y, color='red') if self.log_sweep: ax1f1.set_xscale('log') else: ax1f1.set_xscale('linear') self.rmmpl() self.addmpl(fig1) def addmpl(self, fig): self.canvas = FigureCanvas(fig) self.mplvl.addWidget(self.canvas) self.canvas.draw() self.toolbar = NavigationToolbar(self.canvas, self.mplwindow, coordinates=True) self.mplvl.addWidget(self.toolbar) def rmmpl(self, ): self.mplvl.removeWidget(self.canvas) self.canvas.close() self.canvas.deleteLater() self.mplvl.removeWidget(self.toolbar) self.toolbar.close() self.toolbar.deleteLater() def save_parameters(self): parameters_dict = { 'sw_min': str(self.startEdit.text()), 'sw_max': str(self.endEdit.text()), 'step': str(self.stepEdit.text()), 'delay': int(self.delaySpinBox.value()), 'decade': int(self.decadeComboBox.currentIndex()), 'n': int(self.pocetMereniBox.value()), 'log_sweep': self.logRadioButton.isChecked(), 'lin_sweep': self.linRadioButton.isChecked(), 'sense_local': self.senseLocalRadioButton.isChecked(), 'sense_remote': self.senseRemoteRadioButton.isChecked(), 'col_source': self.sourceCheckBox.checkState(), 'col_delay': self.delayCheckBox.checkState(), 'col_measure': self.measureCheckBox.checkState(), 'col_time': self.timeCheckBox.checkState(), 'stabilize_time': self.stableSpinBox.value(), 'sleep_time': self.sleepSpinBox.value() } # For pickle, the file needs to be opened in binary mode, hence the "wb" with open("last_parameters.pickle", "wb") as params_file: pickle.dump(parameters_dict, params_file) def load_parameters(self): try: # For pickle, the file needs to be opened in binary mode, hence the "wb" with open("last_parameters.pickle", "rb") as params_file: parameters_dict = pickle.load(params_file) self.startEdit.setText(parameters_dict['sw_min']) self.endEdit.setText(parameters_dict['sw_max']) self.stepEdit.setText(parameters_dict['step']) self.delaySpinBox.setValue(parameters_dict['delay']) self.decadeComboBox.setCurrentIndex(parameters_dict['decade']) self.pocetMereniBox.setValue(parameters_dict['n']) self.logRadioButton.setChecked(parameters_dict['log_sweep']) self.linRadioButton.setChecked(parameters_dict['lin_sweep']) self.senseLocalRadioButton.setChecked( parameters_dict['sense_local']) self.senseRemoteRadioButton.setChecked( parameters_dict['sense_remote']) self.sourceCheckBox.setChecked(parameters_dict['col_source']) self.delayCheckBox.setChecked(parameters_dict['col_delay']) self.measureCheckBox.setChecked(parameters_dict['col_measure']) self.timeCheckBox.setChecked(parameters_dict['col_time']) self.stableSpinBox.setValue(parameters_dict['stabilize_time']) self.sleepSpinBox.setValue(parameters_dict['sleep_time']) self.switch_linear() print("Nacteni poslednich parametru uspesne! :)") except: print("Nacteni poslednich parametru selhalo. :(") def validateInput(self, sw_min, sw_max, decade, delay, log_sweep, step): # Unit testing :P try: a = float(sw_min) a = float(sw_max) if not log_sweep: a = float(step) except: return False # Code if log_sweep: if (float(sw_min) > 0 and float(sw_max) > 0 and float(sw_min) != float(sw_max)): return True else: return False else: # lin sweep if (float(sw_min) != float(sw_max) and abs(float(sw_max) - float(sw_min)) > float(step)): return True else: return False def stopFunc(self): print('ABORT! Attempted to STOP sweep!') self.inst.operate(False) self.stop = True def startFunc(self): ''' Posbírá z GUI parametry a odpovídajícím způsobem přeloží.''' # vypnout ruční brzdu self.stop = False # aktuální čas pro ID self.sweep_id = '{0:%Y-%m-%d_%H-%M-%S}'.format(datetime.datetime.now()) sw_min = str(self.startEdit.text()) sw_max = str(self.endEdit.text()) step = str(self.stepEdit.text()) delay = str(self.delaySpinBox.value()) decade = str(self.decadeComboBox.currentIndex()) n = self.pocetMereniBox.value() self.bigProgBar.setValue(0) self.bigProgBar.setMaximum(n) self.littleProgBar.setValue(0) log_sweep = self.logRadioButton.isChecked() lin_sweep = self.linRadioButton.isChecked() self.log_sweep = log_sweep sense_local = self.senseLocalRadioButton.isChecked() sense_remote = self.senseRemoteRadioButton.isChecked() self.sense_local = sense_local col_source = self.sourceCheckBox.checkState() col_delay = self.delayCheckBox.checkState() col_measure = self.measureCheckBox.checkState() col_time = self.timeCheckBox.checkState() self.cols = 0 if col_source: self.cols += 1 if col_delay: self.cols += 2 if col_measure: self.cols += 4 if col_time: self.cols += 8 if self.validateInput(sw_min, sw_max, decade, delay, log_sweep, step): self.save_parameters() self.measure(sw_min, sw_max, decade, delay, log_sweep, step, n) else: print('Input failed validation.') self.show_notification('failed_validation') def show_notification(self, code): if code == 'failed_validation': msg = QtWidgets.QMessageBox() msg.setIcon(QtWidgets.QMessageBox.Warning) msg.setText("Chybné parametry sweepu.") msg.setInformativeText("") msg.setWindowTitle("Sweeper - varování") msg.setDetailedText("TODO") msg.exec_() def measure(self, sw_min, sw_max, decade, delay, log_sweep, step, n): ''' Spustí měření s již validovanými parametry. ''' # Disable UI self.enable_ui(False) # Declare Export not done on this sweep self.exportButton.setText('Export') # Local or Remote sense? if self.sense_local: print("Zapinam Sense - LOCAL.") self.inst.write("O0X") else: print("Zapinam Sense - REMOTE.") self.inst.write("O1X") # Úvodní stabilizace stabilize_time = self.stableSpinBox.value() print("Uvodni stabilizace v DC modu - {} s.".format(stabilize_time)) self.stabilize(sw_min, stabilize_time) # Nastavení sweepu self.inst.set_source_and_function('I', 'Sweep') # Nastavení formátu dat self.inst.write("G" + str(self.cols) + ",2,2X") if self.log_sweep: self.inst.write("Q2," + sw_min + "," + sw_max + "," + decade + ",0," + delay + "X") else: self.inst.write("Q1," + sw_min + "," + sw_max + "," + step + ",0," + delay + "X") data = [] self.full_data = [] n_hotovych_mereni = 0 for mereni in range(n): if self.stop: break output = self.run_sweep() if output: sweep_results = misc.nice_format(output, cols=self.cols) data.append(misc.unpack(sweep_results, cols=self.cols)) self.full_data.append(sweep_results) print('Ukladam docasna data...') self.dump_data() n_hotovych_mereni += 1 self.bigProgBar.setValue(n_hotovych_mereni) self.plot_data(data) if n_hotovych_mereni != n: sleep_time = self.sleepSpinBox.value() print("Pauza mezi sweepy - {} s.".format(sleep_time)) self.artSleep(sleep_time) else: print("Output was empty. Interrupted measurement?") self.inst.operate(False) self.enable_ui(True) #self.plot_data(data) def run_sweep(self): ''' Provede jeden sweep, který už musí být definovaný ve stroji. Na konci 3 vteřiny spí, aby se mělo napětí čas ustálit před dalším měřením. Vrací string se všemi hodnotami sweepu. ''' print('\nSpoustim sweep...') self.inst.write("U8X") out = self.inst.read() print('U8X -> ' + out) out = out.replace('\r', '').replace('\n', '') print("Out: {}".format(out)) sweep_defined_size = int(out[-4:]) print('Pocet bodu ve sweepu: ' + str(sweep_defined_size)) self.littleProgBar.setValue(0) self.inst.trigger() # Immediate trigger sweep_done = False while not sweep_done: if self.stop: break self.artSleep(0.2) self.inst.write("U11X") status = self.inst.read() if (status == 'SMS' + str(sweep_defined_size).zfill(4) + '\r\n'): sweep_done = True else: status_edit = status.replace('\r', '').replace('\n', '') try: progress = int(status_edit[-4:]) self.littleProgBar.setValue( int(progress / sweep_defined_size * 100)) except: print('Invalid progress!') print('Jeden sweep hotov.') self.littleProgBar.setValue(100) if self.stop: return "" else: return self.inst.read() def stabilize(self, bias, stabilize_time): # Počáteční stabilizace self.inst.set_source_and_function('I', 'DC') self.inst.write("B" + bias + ",0,20X") self.inst.operate(True) self.inst.trigger() self.artSleep(stabilize_time) def switch_linear(self): log_sweep = self.logRadioButton.isChecked() lin_sweep = self.linRadioButton.isChecked() if log_sweep: self.stepEdit.setEnabled(False) self.decadeComboBox.setEnabled(True) else: self.decadeComboBox.setEnabled(False) self.stepEdit.setEnabled(True) def enable_ui(self, status): ui_elements = [ self.startEdit, self.endEdit, self.stepEdit, self.delaySpinBox, self.decadeComboBox, self.pocetMereniBox, self.logRadioButton, self.linRadioButton, self.senseLocalRadioButton, self.senseRemoteRadioButton, self.sourceCheckBox, self.delayCheckBox, self.measureCheckBox, self.timeCheckBox, self.stableSpinBox, self.sleepSpinBox, ] for element in ui_elements: element.setEnabled(status) if status: self.switch_linear() if status: self.startBtn.clicked.disconnect() self.startBtn.clicked.connect(self.startFunc) self.startBtn.setText("Start") else: self.startBtn.clicked.disconnect() self.startBtn.clicked.connect(self.stopFunc) self.startBtn.setText("Abort") self.exportButton.setText('Export') def get_export_data(self): output = "" output += '# ======== Sweep ID: ' + self.sweep_id + ' ========' + '\n' output += '# ======== ' + str(len( self.full_data)) + ' sweeps' + ' ========' + '\n' output += self.get_measurement_parameters() for data in self.full_data: output += '# ======== SWEEP START ========\n' output += data.replace(',', ' ') output += '# ======== SWEEP END ========\n\n' return output def dump_data(self): save_file_name = 'C:\Repa\k237\sweeper\data_temp.txt' try: with open(save_file_name, "w", encoding="utf-8") as text_file: text = self.get_export_data() text_file.write(text) except: print("Nouzovy dump se nepovedl.") def export_data(self): """ Exportuje data pomocí ukládacího dialogu Qt. V případě chybného zadání souboru nic neudělá a postěžuje si do konzole. """ proposed_name = self.sweep_id # Qt Dialog na výběr souboru k uložení save_file_name, _ = QtWidgets.QFileDialog.getSaveFileName( None, 'Exportovat výsledky měření', 'C:\Repa\k237\data\sweep_' + proposed_name + '.txt', 'Text Files (*.txt);;All Files (*)') # Vlastní uložení souboru try: with open(save_file_name, "w", encoding="utf-8") as text_file: text = self.get_export_data() text_file.write(text) # Update GUI self.exportButton.setText('Export ✔') except: print("Export neuspesny. Data pravdepodobne nejsou ulozena!") # Update GUI self.exportButton.setText('Export ✗') def get_measurement_parameters(self): out = '' out += "# Sweep ID: {}\n".format(self.sweep_id) if self.log_sweep: out += "# Log sweep:\n" out += "# Rozsah (min, max) [A]: {}, {}\n".format( self.startEdit.text(), self.endEdit.text()) out += "# Bodů na dekádu [-]: {}\n".format( self.decade_combo_values[self.decadeComboBox.currentIndex()]) else: out += "# Linear sweep\n" out += "# Rozsah (min, max, points) [A]: {}, {}, {}\n".format( self.startEdit.text(), self.endEdit.text(), self.stepEdit.text()) out += "# Delay [ms]: {}\n".format(self.delaySpinBox.value()) out += "# Počet charakteristik [-]: {}\n".format( self.pocetMereniBox.value()) if self.sense_local: out += "# Sense: local\n" else: out += "# Sense: remote\n" out += "# Sloupce (Source, Measure, Delay, Time): {} {} {} {}\n".format( int(self.sourceCheckBox.checkState() / 2), int(self.measureCheckBox.checkState() / 2), int(self.delayCheckBox.checkState() / 2), int(self.timeCheckBox.checkState() / 2)) out += "# Uvodní DC stabilizace [s]: {}\n".format( self.stableSpinBox.value()) out += "# Stabilizace [s]: {}\n".format(self.sleepSpinBox.value()) return out
def deleteLater(self, *args): self.delete() return FigureCanvasQTAgg.deleteLater(self, *args)
class GuiProgram(Ui_sweepergui): cols = 0 sweep_id = 'mereni' full_data = [] negative_current = False log_sweep = True stop = True decade_combo_values = ['5', '10', '25', '50'] save_directory = False save_filename = False def __init__(self, dialog): Ui_sweepergui.__init__(self) self.setupUi(dialog) # Connect "add" button with a custom function (addInputTextToListbox) self.exportButton.clicked.connect(self.export_data) self.startBtn.clicked.connect(self.startFunc) self.logRadioButton.clicked.connect(self.switch_linear) self.linRadioButton.clicked.connect(self.switch_linear) self.dynamicDelayRadio.clicked.connect(self.switch_dynamic_delay) self.constantDelayRadio.clicked.connect(self.switch_dynamic_delay) # Populate comboBox self.decadeComboBox.clear() self.decadeComboBox.addItems(self.decade_combo_values) self.decadeComboBox.setCurrentIndex(1) self.exportButton.setEnabled(False) # Try to load last parameters from Pickle self.load_parameters() self.save_directory = os.path.dirname(os.path.abspath(__file__)) # Připojení k instrumentu #self.inst = Instrument('GPIB0::17::INSTR', visa_location='C:\WINDOWS\SysWOW64\\visa32.dll') self.inst = Instrument('GPIB0::17::INSTR', virtual=True) def make_pretty(self): self.littleProgBar.setValue(84) self.littleProgBar.setMaximum(100) self.bigProgBar.setMaximum(5) self.bigProgBar.setValue(3) self.startBtn.setText('Stop') self.ax.clear() # Clear contents of current axis # Plot cosmetics self.ax.set_xlabel('Current $I$ (nA)') self.ax.set_ylabel('Voltage $U$ (V)') self.ax.set_title( 'Sweep ID: 2018-04-21_11:22:37 $n$-ZnO/$p$-GaN sample #692') data = [] dd = np.loadtxt('demo_data/01.txt') for i in range(int(len(dd.T) / 2)): data.append((dd[:, 2 * i] * 1e6, dd[:, 2 * i + 1])) color_1 = '#0066FF' color_3 = '#6600CC' color_2 = '#FF0000' self.ax.plot(data[2][0], data[2][1], color=color_2) self.ax.plot(data[3][0], data[3][1], '--', color=color_2) self.ax.plot(data[4][0], data[4][1], color=color_3) self.ax.plot(data[5][0], data[5][1], '--', color=color_3) self.ax.plot(data[0][0], data[0][1], color=color_1) self.ax.plot(data[1][0], data[1][1], '--', color=color_1) #plt.tight_layout() # --- PLOTTING ----------------------------------------------------------- # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ def plot_data(self, data): ''' Plots the provided data onto the figure in the GUI. ''' original_xlim = self.ax.get_xlim() original_ylim = self.ax.get_ylim() self.ax.clear() # Clear contents of current axis # Plot cosmetics self.ax.set_xlabel('I [A]') self.ax.set_ylabel('U [V]') self.ax.set_title('Sweep ID: ' + self.sweep_id) for i in range(len(data)): x, y = data[i] if i == len(data) - 1: color = '#0066FF' elif i == len(data) - 2: color = '#6600CC' else: color = '#FF0000' if self.chkLoop.checkState(): half = int(len(x) / 2) end = len(x) self.ax.plot(x[0:half], y[0:half], color=color) self.ax.plot(x[half:end], y[half:end], '--', color=color) else: self.ax.plot(x, y, color=color) if self.log_sweep: self.ax.set_xscale('log') else: self.ax.set_xscale('linear') if i != 0 and self.chkLockRange.checkState(): self.ax.set_xlim(original_xlim) self.ax.set_ylim(original_ylim) self.canvas.get_default_filename = self.get_default_filename self.canvas.draw() # Propagate changes to GUI def clear_plot(self): self.ax.clear() # Clear contents of current axis self.canvas.draw() # Propagate changes to GUI def put_figure_into_gui(self, fig, ax): ''' Creates a figure and places it inside the GUI container. ''' # Figure self.fig = fig self.ax = ax # Canvas self.canvas = FigureCanvas(self.fig) self.mplvl.addWidget(self.canvas) self.canvas.draw() # Toolbar self.toolbar = NavigationToolbar(self.canvas, self.mplwindow, coordinates=True) self.mplvl.addWidget(self.toolbar) def remove_figure_from_gui(self, ): ''' Deletes the figure from the GUI. ''' # Canvas self.mplvl.removeWidget(self.canvas) self.canvas.close() self.canvas.deleteLater() # this prevents memory leaks # Toolbar self.mplvl.removeWidget(self.toolbar) self.toolbar.close() self.toolbar.deleteLater() # this prevent memory leaks def get_default_filename(self): """ Return a string, which includes extension, suitable for use as a default filename. """ default_basename = self.save_filename or "sweep_{}".format( self.sweep_id) or 'image' default_filetype = self.canvas.get_default_filetype() default_filename = default_basename + '.' + default_filetype save_dir = os.path.expanduser( matplotlib.rcParams.get('savefig.directory', '')) # ensure non-existing filename in save dir i = 1 while os.path.isfile(os.path.join(save_dir, default_filename)): # attach numerical count to basename default_filename = '{0}_({1}).{2}'.format(default_basename, i, default_filetype) i += 1 return default_filename # --- GUI collecting and starting MEASUREMENTS --------------------------- # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ def validateInput(self, sw_min, sw_max, decade, delay, log_sweep, step): # Unit testing :P try: a = float(sw_min) a = float(sw_max) if not log_sweep: a = float(step) except: return False, "Některé parametry se nedají převést na čísla." # Code if log_sweep: if (float(sw_min) > 0 and float(sw_max) > 0 and float(sw_min) != float(sw_max)): return True, "OK" else: return False, "Kraje intervalu jsou stejné nebo je alespoň jeden záp**ný." else: # lin sweep if (float(sw_min) != float(sw_max) and abs(float(sw_max) - float(sw_min)) > float(step)): # step fits into (start, stop) interval and start != stop test_array = np.arange(float(sw_max), float(sw_min), float(step)) if self.chkLoop.checkState() and len(test_array) * 2 > 1000: return False, "Počet bodů ve sweepu je {} > 1000. \nBuffer by přetekl, zvolte jemnější krok, menší rozsah nebo vypněte obousměrnost měření.".format( 2 * len(test_array)) elif len(test_array) > 1000: return False, "Počet bodů ve sweepu je {} > 1000. \nBuffer by přetekl, zvolte jemnější krok nebo menší rozsah.".format( len(test_array)) else: return True, "OK" else: return False, "Kraje intervalu se rovnají, nebo je krok větší než rozsah." def stopFunc(self): print('ABORT! Attempted to STOP sweep!') self.inst.operate(False) self.stop = True def startFunc(self): ''' Posbírá z GUI parametry a odpovídajícím způsobem přeloží.''' # vypnout ruční brzdu self.stop = False # aktuální čas pro ID self.sweep_id = '{0:%Y-%m-%d_%H-%M-%S}'.format(datetime.datetime.now()) self.save_filename = False sense_local = self.senseLocalRadioButton.isChecked() sense_remote = self.senseRemoteRadioButton.isChecked() self.sense_local = sense_local sw_min = str(self.startEdit.text()) sw_max = str(self.endEdit.text()) step = str(self.stepEdit.text()) # Pokud je zapojený zesilovač if not self.sense_local: sw_min = str(float(sw_min) * 1e3) sw_max = str(float(sw_max) * 1e3) step = str(float(step) * 1e3) # TODO: this should be made more logical... self.custom_capacity_used = self.dynamicDelayRadio.isChecked() if self.custom_capacity_used: self.custom_capacity = int(self.capacitySpinBox.value()) delay = str(self.delaySpinBox.value()) decade = str(self.decadeComboBox.currentIndex()) n = self.pocetMereniBox.value() self.bigProgBar.setValue(0) self.bigProgBar.setMaximum(n) self.littleProgBar.setValue(0) log_sweep = self.logRadioButton.isChecked() lin_sweep = self.linRadioButton.isChecked() self.log_sweep = log_sweep col_source = self.sourceCheckBox.checkState() col_delay = self.delayCheckBox.checkState() col_measure = self.measureCheckBox.checkState() col_time = self.timeCheckBox.checkState() self.cols = 0 if col_source: self.cols += 1 if col_delay: self.cols += 2 if col_measure: self.cols += 4 if col_time: self.cols += 8 input_valid, err = self.validateInput(sw_min, sw_max, decade, delay, log_sweep, step) if self.chkAutorange.checkState(): sweep_range = '0' else: sweep_range = str( misc.get_range_number(float(sw_min), float(sw_max))) print("!! Using sweep range: {}".format(sweep_range)) if sweep_range == '0': print( 'POZOR: Manualni nastaveni range selhalo, prilis vysoke proudy?' ) if input_valid: self.save_parameters() self.measure(sw_min, sw_max, decade, delay, log_sweep, step, n, sweep_range) else: self.show_notification(err) # --- ACTUAL MEASUREMENTS ------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ def measure(self, sw_min, sw_max, decade, delay, log_sweep, step, n, sweep_range): ''' Spustí měření s již validovanými parametry. ''' # Disable UI self.enable_ui(False) # Smaže aktuální graf self.clear_plot() # Declare Export not done on this sweep self.exportButton.setText('Export') # Local or Remote sense? if self.sense_local: print("Zapinam Sense - LOCAL.") self.inst.write("O0X") else: print("Zapinam Sense - REMOTE.") self.inst.write("O1X") # Úvodní stabilizace stabilize_time = self.stableSpinBox.value() print("Uvodni stabilizace v DC modu - {} s.".format(stabilize_time)) self.stabilize(sw_min, stabilize_time) # Nastavení sweepu self.inst.set_source_and_function('I', 'Sweep') # Nastavení formátu dat self.inst.write("G" + str(self.cols) + ",2,2X") if self.log_sweep: self.inst.write("Q2," + sw_min + "," + sw_max + "," + decade + "," + sweep_range + "," + delay + "X") if self.chkLoop.checkState(): self.inst.write("Q8," + sw_max + "," + sw_min + "," + decade + "," + sweep_range + "," + delay + "X") else: self.inst.write("Q1," + sw_min + "," + sw_max + "," + step + "," + sweep_range + "," + delay + "X") if self.chkLoop.checkState(): self.inst.write("Q7," + sw_max + "," + sw_min + "," + step + "," + sweep_range + "," + delay + "X") # Manual modification of delays for each value if self.custom_capacity_used: if self.chkLoop.checkState(): delay_arr = delays.delays_round(float(sw_min), float(sw_max), int(decade), self.custom_capacity) else: delay_arr = delays.delays_up(float(sw_min), float(sw_max), int(decade), self.custom_capacity) self.inst.set_custom_delays(delay_arr) data = [] self.full_data = [] self.np_data = [] n_hotovych_mereni = 0 for mereni in range(n): if self.stop: break output = self.run_sweep() if output: if not self.sense_local: output = misc.shift_data(output, cols=self.cols, shift=-3) sweep_results = misc.nice_format(output, cols=self.cols) unpacked_results = misc.unpack(sweep_results, cols=self.cols) data.append(unpacked_results) self.full_data.append(sweep_results) self.np_data = misc.pack_data(self.np_data, unpacked_results) print('Ukladam docasna data...') self.dump_data() n_hotovych_mereni += 1 self.bigProgBar.setValue(n_hotovych_mereni) self.plot_data(data) if n_hotovych_mereni != n: sleep_time = self.sleepSpinBox.value() print("Pauza mezi sweepy - {} s.".format(sleep_time)) self.artSleep(sleep_time) else: print("Output byl prazdny. Prerusene mereni?") self.inst.operate(False) self.enable_ui(True) def run_sweep(self): ''' Provede jeden sweep, který už musí být definovaný ve stroji. Na konci 3 vteřiny spí, aby se mělo napětí čas ustálit před dalším měřením. Vrací string se všemi hodnotami sweepu. ''' print('\nSpoustim sweep...') self.inst.write("U8X") out = self.inst.read() print('U8X -> ' + out) out = out.replace('\r', '').replace('\n', '') print("Out: {}".format(out)) sweep_defined_size = int(out[-4:]) print('Pocet bodu ve sweepu: ' + str(sweep_defined_size)) self.littleProgBar.setValue(0) self.inst.trigger() # Immediate trigger sweep_done = False while not sweep_done: if self.stop: break self.artSleep(0.2) self.inst.write("U11X") status = self.inst.read() if (status == 'SMS' + str(sweep_defined_size).zfill(4) + '\r\n'): sweep_done = True else: status_edit = status.replace('\r', '').replace('\n', '') try: progress = int(status_edit[-4:]) self.littleProgBar.setValue( int(progress / sweep_defined_size * 100)) except: print('Invalid progress!') print('Jeden sweep hotov.') self.littleProgBar.setValue(100) if self.stop: return "" else: return self.inst.read() def stabilize(self, bias, stabilize_time): # Počáteční stabilizace self.inst.set_source_and_function('I', 'DC') self.inst.write("B" + bias + ",0,20X") self.inst.operate(True) self.inst.trigger() self.artSleep(stabilize_time) # --- EXPORT and DATA operations ----------------------------------------- # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ def dump_data(self): save_file_name = 'C:\Repa\k237\data_temp.txt' try: np.savetxt(save_file_name, self.np_data, fmt='%.4e', header=self.get_measurement_parameters() + "\nPOZOR, prubezne ukladana data mohou byt nekompletni", delimiter='\t') except: print("Nouzovy dump se nepovedl.") def export_data(self): """ Exportuje data pomocí ukládacího dialogu Qt. V případě chybného zadání souboru nic neudělá a postěžuje si do konzole. """ proposed_name = self.save_filename or 'sweep_' + self.sweep_id # Qt Dialog na výběr souboru k uložení save_file_name, _ = QtWidgets.QFileDialog.getSaveFileName( None, 'Exportovat výsledky měření', #'C:\Repa\k237\data\sweep_' + proposed_name + '.txt', os.path.join(self.save_directory, proposed_name + '.txt'), 'Text Files (*.txt);;All Files (*)') # Vlastní uložení souboru try: np.savetxt(save_file_name, self.np_data, fmt='%.4e', header=self.get_measurement_parameters(), delimiter='\t') # Update GUI self.exportButton.setText('Export ✔') self.save_directory = os.path.dirname(save_file_name) self.save_filename = os.path.splitext( os.path.basename(save_file_name))[0] except: print("Export neuspesny. Data pravdepodobne nejsou ulozena!") # Update GUI self.exportButton.setText('Export ✗') def get_measurement_parameters(self): out = '' out += "Sweep ID: {}\n".format(self.sweep_id) if self.log_sweep: out += "Log sweep:\n" out += "Rozsah (min, max) [A]: {}, {}\n".format( self.startEdit.text(), self.endEdit.text()) out += "Bodu na dekadu [-]: {}\n".format( self.decade_combo_values[self.decadeComboBox.currentIndex()]) else: out += "Linear sweep\n" out += "Rozsah (min, max, points) [A]: {}, {}, {}\n".format( self.startEdit.text(), self.endEdit.text(), self.stepEdit.text()) out += "Delay [ms]: {}\n".format(self.delaySpinBox.value()) out += "Pocet charakteristik [-]: {}\n".format( self.pocetMereniBox.value()) if self.sense_local: out += "Sense: local\n" else: out += "Sense: remote\n" out += "Sloupce (Source, Measure, Delay, Time): {} {} {} {}\n".format( int(self.sourceCheckBox.checkState() / 2), int(self.measureCheckBox.checkState() / 2), int(self.delayCheckBox.checkState() / 2), int(self.timeCheckBox.checkState() / 2)) out += "Uvodni DC stabilizace [s]: {}\n".format( self.stableSpinBox.value()) out += "Stabilizace [s]: {}\n".format(self.sleepSpinBox.value()) out += "\nI[A] (x)\tU[V .e-3] (y1, y2, ...) " return out # --- GUI parameters and ENABLE/DISABLE ---------------------------------- # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ def save_parameters(self): parameters_dict = { 'sw_min': str(self.startEdit.text()), 'sw_max': str(self.endEdit.text()), 'step': str(self.stepEdit.text()), 'delay': int(self.delaySpinBox.value()), 'decade': int(self.decadeComboBox.currentIndex()), 'n': int(self.pocetMereniBox.value()), 'log_sweep': self.logRadioButton.isChecked(), 'lin_sweep': self.linRadioButton.isChecked(), 'sense_local': self.senseLocalRadioButton.isChecked(), 'sense_remote': self.senseRemoteRadioButton.isChecked(), 'col_source': self.sourceCheckBox.checkState(), 'col_delay': self.delayCheckBox.checkState(), 'col_measure': self.measureCheckBox.checkState(), 'col_time': self.timeCheckBox.checkState(), 'stabilize_time': self.stableSpinBox.value(), 'sleep_time': self.sleepSpinBox.value(), 'chk_loop': self.chkLoop.checkState(), 'chk_lock_range': self.chkLockRange.checkState(), 'chk_autorange': self.chkAutorange.checkState(), } # For pickle, the file needs to be opened in binary mode, hence the "wb" with open("last_parameters.pickle", "wb") as params_file: pickle.dump(parameters_dict, params_file) def load_parameters(self): try: # For pickle, the file needs to be opened in binary mode, hence the "wb" with open("last_parameters.pickle", "rb") as params_file: parameters_dict = pickle.load(params_file) self.startEdit.setText(parameters_dict['sw_min']) self.endEdit.setText(parameters_dict['sw_max']) self.stepEdit.setText(parameters_dict['step']) self.delaySpinBox.setValue(parameters_dict['delay']) self.decadeComboBox.setCurrentIndex(parameters_dict['decade']) self.pocetMereniBox.setValue(parameters_dict['n']) self.logRadioButton.setChecked(parameters_dict['log_sweep']) self.linRadioButton.setChecked(parameters_dict['lin_sweep']) self.senseLocalRadioButton.setChecked( parameters_dict['sense_local']) self.senseRemoteRadioButton.setChecked( parameters_dict['sense_remote']) self.sourceCheckBox.setChecked(parameters_dict['col_source']) self.delayCheckBox.setChecked(parameters_dict['col_delay']) self.measureCheckBox.setChecked(parameters_dict['col_measure']) self.timeCheckBox.setChecked(parameters_dict['col_time']) self.stableSpinBox.setValue(parameters_dict['stabilize_time']) self.sleepSpinBox.setValue(parameters_dict['sleep_time']) self.chkLoop.setChecked(parameters_dict['chk_loop']) self.chkLockRange.setChecked(parameters_dict['chk_lock_range']) self.chkAutorange.setChecked(parameters_dict['chk_autorange']) self.switch_linear() self.switch_dynamic_delay() print("Nacteni poslednich parametru uspesne! :)") except: print("Nacteni poslednich parametru selhalo. :(") def switch_linear(self): log_sweep = self.logRadioButton.isChecked() lin_sweep = self.linRadioButton.isChecked() if log_sweep: self.stepEdit.setEnabled(False) self.decadeComboBox.setEnabled(True) else: self.decadeComboBox.setEnabled(False) self.stepEdit.setEnabled(True) def switch_dynamic_delay(self): const_delay = self.constantDelayRadio.isChecked() dynamic_delay = self.dynamicDelayRadio.isChecked() if const_delay: self.capacitySpinBox.setEnabled(False) self.delaySpinBox.setEnabled(True) else: self.delaySpinBox.setEnabled(False) self.capacitySpinBox.setEnabled(True) def enable_ui(self, status): ui_elements = [ self.startEdit, self.endEdit, self.stepEdit, self.delaySpinBox, self.decadeComboBox, self.pocetMereniBox, self.logRadioButton, self.linRadioButton, self.senseLocalRadioButton, self.senseRemoteRadioButton, self.sourceCheckBox, self.delayCheckBox, self.measureCheckBox, self.timeCheckBox, self.stableSpinBox, self.sleepSpinBox, self.chkLoop, self.chkAutorange, self.exportButton, ] for element in ui_elements: element.setEnabled(status) if status: self.switch_linear() self.switch_dynamic_delay() if status: self.startBtn.clicked.disconnect() self.startBtn.clicked.connect(self.startFunc) self.startBtn.setText("Start") self.exportButton.setFocus() else: self.startBtn.clicked.disconnect() self.startBtn.clicked.connect(self.stopFunc) self.startBtn.setText("Abort") self.startBtn.setFocus() self.exportButton.setText('Export') def artSleep(self, sleepTime): """ Čeká čas sleepTime v sekundách, zatím ale každých 50 milisekund řeší akce, o které se někdo pokoušel v GUI. """ stop_time = QtCore.QTime() stop_time.restart() while stop_time.elapsed() < sleepTime * 1000: QtWidgets.QApplication.processEvents(QtCore.QEventLoop.AllEvents, 50) def show_notification(self, err): msg = QtWidgets.QMessageBox() msg.setIcon(QtWidgets.QMessageBox.Warning) msg.setText("Chybné parametry sweepu.") msg.setInformativeText(err) msg.setWindowTitle("Sweeper - varování") msg.exec_()
class Ui_MainWindow(object): def openOverview(self): #Connects to the SQL Server self.window = QtWidgets.QMainWindow() self.ui = Ui_MainWindow() self.ui.setupUi(self.window) MainWindow.close() self.window.show() return def setupUi(self, MainWindow): self.conn = mysql.connector.connect( host="myrds1.cijcu6ghykxh.ap-southeast-1.rds.amazonaws.com", user="******", passwd="admin123", database="myrds1") MainWindow.setObjectName("MainWindow") MainWindow.resize(831, 666) MainWindow.setToolTipDuration(0) MainWindow.setFixedSize(831, 666) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.line = QtWidgets.QFrame(self.centralwidget) self.line.setGeometry(QtCore.QRect(0, 90, 891, 16)) self.line.setFrameShape(QtWidgets.QFrame.HLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.line_2 = QtWidgets.QFrame(self.centralwidget) self.line_2.setGeometry(QtCore.QRect(210, 0, 20, 641)) self.line_2.setFrameShape(QtWidgets.QFrame.VLine) self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) self.line_2.setObjectName("line_2") self.total_cases = QtWidgets.QLabel(self.centralwidget) self.total_cases.setEnabled(True) self.total_cases.setGeometry(QtCore.QRect(260, 140, 531, 51)) font = QtGui.QFont() font.setFamily("Montserrat") font.setPointSize(17) font.setBold(False) font.setItalic(False) font.setWeight(50) self.total_cases.setFont(font) self.total_cases.setAutoFillBackground(False) self.total_cases.setAlignment(QtCore.Qt.AlignCenter) self.total_cases.setObjectName("total_cases") self.total_death = QtWidgets.QLabel(self.centralwidget) self.total_death.setGeometry(QtCore.QRect(410, 290, 231, 61)) font = QtGui.QFont() font.setFamily("Montserrat") font.setPointSize(17) font.setBold(False) font.setWeight(50) self.total_death.setFont(font) self.total_death.setAlignment(QtCore.Qt.AlignCenter) self.total_death.setObjectName("total_death") self.total_recovered = QtWidgets.QLabel(self.centralwidget) self.total_recovered.setGeometry(QtCore.QRect(380, 440, 291, 61)) font = QtGui.QFont() font.setFamily("Montserrat") font.setPointSize(17) font.setBold(False) font.setWeight(50) self.total_recovered.setFont(font) self.total_recovered.setAlignment(QtCore.Qt.AlignCenter) self.total_recovered.setObjectName("total_recovered") self.title_status = QtWidgets.QLabel(self.centralwidget) self.title_status.setGeometry(QtCore.QRect(260, 10, 571, 81)) font = QtGui.QFont() font.setFamily("PT Sans Caption") font.setPointSize(23) font.setBold(True) font.setWeight(75) self.title_status.setFont(font) self.title_status.setObjectName("title_status") ### GUI for the Overview Layout. ### self.cases_textBrowser = QtWidgets.QLabel(self.centralwidget) self.cases_textBrowser.setGeometry(QtCore.QRect(390, 190, 261, 61)) self.cases_textBrowser.setObjectName("cases_textBrowser") self.cases_textBrowser.setStyleSheet( "QLabel { background-color : white; color : black; }") self.cases_textBrowser.setAlignment(QtCore.Qt.AlignCenter) self.death_textBrowser = QtWidgets.QLabel(self.centralwidget) self.death_textBrowser.setGeometry(QtCore.QRect(390, 340, 261, 61)) self.death_textBrowser.setObjectName("death_textBrowser") self.death_textBrowser.setStyleSheet( "QLabel { background-color : white; color : black; }") self.death_textBrowser.setAlignment(QtCore.Qt.AlignCenter) self.recoverd_textBrowser = QtWidgets.QLabel(self.centralwidget) self.recoverd_textBrowser.setGeometry(QtCore.QRect(390, 490, 261, 61)) self.recoverd_textBrowser.setObjectName("recoverd_textBrowser") self.recoverd_textBrowser.setStyleSheet( "QLabel { background-color : white; color : black; }") self.recoverd_textBrowser.setAlignment(QtCore.Qt.AlignCenter) fontfortextbrowser = QtGui.QFont() fontfortextbrowser.setFamily("Montserrat") fontfortextbrowser.setPointSize(25) fontfortextbrowser.setBold(False) fontfortextbrowser.setWeight(100) self.cases_textBrowser.setFont(fontfortextbrowser) self.death_textBrowser.setFont(fontfortextbrowser) self.recoverd_textBrowser.setFont(fontfortextbrowser) ###End.### ###Layout for Overview. ### self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget) self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 130, 160, 371)) self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setSpacing(0) self.verticalLayout.setObjectName("verticalLayout") self.overview_button = QtWidgets.QPushButton(self.verticalLayoutWidget) font = QtGui.QFont() font.setPointSize(10) ### Buttons #### self.overview_button.setFont(font) self.overview_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.overview_button.setToolTipDuration(0) self.overview_button.setAutoFillBackground(True) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("Images/flat-icon-png-40260.png"), QtGui.QIcon.Selected, QtGui.QIcon.On) self.overview_button.setIcon(icon) self.overview_button.setIconSize(QtCore.QSize(40, 40)) self.overview_button.setObjectName("overview_button") self.verticalLayout.addWidget(self.overview_button) self.charts_button = QtWidgets.QPushButton(self.verticalLayoutWidget) font = QtGui.QFont() font.setPointSize(10) self.charts_button.setFont(font) self.charts_button.setToolTipDuration(1) self.charts_button.setAutoFillBackground(True) icon1 = QtGui.QIcon() icon1.addPixmap( QtGui.QPixmap( "Images/kisspng-computer-icons-bar-chart-charts-5abed4a903cbf3.1869123215224557210156.png" ), QtGui.QIcon.Selected, QtGui.QIcon.On) self.charts_button.setIcon(icon1) self.charts_button.setIconSize(QtCore.QSize(40, 40)) self.charts_button.setObjectName("charts_button") self.verticalLayout.addWidget(self.charts_button) self.location_button = QtWidgets.QPushButton(self.verticalLayoutWidget) font = QtGui.QFont() font.setPointSize(10) self.location_button.setFont(font) self.location_button.setAutoFillBackground(True) icon2 = QtGui.QIcon() icon2.addPixmap(QtGui.QPixmap("Images/icons8-location-64.png"), QtGui.QIcon.Selected, QtGui.QIcon.On) self.location_button.setIcon(icon2) self.location_button.setIconSize(QtCore.QSize(40, 40)) self.location_button.setObjectName("location_button") self.verticalLayout.addWidget(self.location_button) self.patterns_button = QtWidgets.QPushButton(self.verticalLayoutWidget) font = QtGui.QFont() font.setPointSize(10) self.patterns_button.setFont(font) self.patterns_button.setAutoFillBackground(True) icon3 = QtGui.QIcon() icon3.addPixmap(QtGui.QPixmap("Images/iconfinder_10_1516234.png"), QtGui.QIcon.Selected, QtGui.QIcon.On) self.patterns_button.setIcon(icon3) self.patterns_button.setIconSize(QtCore.QSize(40, 40)) self.patterns_button.setObjectName("patterns_button") self.verticalLayout.addWidget(self.patterns_button) self.news_button = QtWidgets.QPushButton(self.verticalLayoutWidget) font = QtGui.QFont() font.setPointSize(10) self.news_button.setFont(font) self.news_button.setAutoFillBackground(True) icon4 = QtGui.QIcon() icon4.addPixmap(QtGui.QPixmap("Images/news.png"), QtGui.QIcon.Selected, QtGui.QIcon.On) self.news_button.setIcon(icon4) self.news_button.setIconSize(QtCore.QSize(40, 40)) self.verticalLayout.addWidget(self.news_button) ### End #### ### Labels and Picture setup ### self.line_3 = QtWidgets.QFrame(self.centralwidget) self.line_3.setGeometry(QtCore.QRect(200, 0, 16, 711)) self.line_3.setFrameShape(QtWidgets.QFrame.VLine) self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken) self.line_3.setObjectName("line_3") self.about_button = QtWidgets.QPushButton(self.centralwidget) self.about_button.setGeometry(QtCore.QRect(20, 590, 158, 39)) font = QtGui.QFont() font.setPointSize(10) self.about_button.setFont(font) icon4 = QtGui.QIcon() icon4.addPixmap( QtGui.QPixmap("Images/25f03a917cfb2c9beb28d0ffcd236ffa.png"), QtGui.QIcon.Selected, QtGui.QIcon.On) self.about_button.setIcon(icon4) self.about_button.setIconSize(QtCore.QSize(30, 30)) self.about_button.setObjectName("about_button") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(270, 10, 71, 81)) self.label.setStyleSheet( "image: url(:/header/Images/philippines.png);") self.label.setText("") self.label.setObjectName("label") self.label_3 = QtWidgets.QLabel(self.centralwidget) self.label_3.setGeometry(QtCore.QRect(20, 20, 161, 61)) self.label_3.setStyleSheet( "image: url(:/header/Images/mapua-logo2.png);") self.label_3.setText("") self.label_3.setObjectName("label_3") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(-10, 0, 841, 771)) self.label_2.setStyleSheet( "background-image: url(:/bg/Images/bg-main4.png);") self.label_2.setText("") self.label_2.setObjectName("label_2") ### End ### ### Raises the widget. ### self.label_2.raise_() self.line.raise_() self.line_2.raise_() self.total_cases.raise_() self.total_death.raise_() self.total_recovered.raise_() self.title_status.raise_() self.cases_textBrowser.raise_() self.death_textBrowser.raise_() self.recoverd_textBrowser.raise_() self.verticalLayoutWidget.raise_() self.line_3.raise_() self.about_button.raise_() self.label.raise_() self.label_3.raise_() ### End. #### ### About Us Button ### MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.actionAbout_Us = QtWidgets.QAction(MainWindow) self.actionAbout_Us.setObjectName("actionAbout_Us") ### End #Charts UI self.chartsView = QtWidgets.QGraphicsView(self.centralwidget) self.chartsView.setGeometry(QtCore.QRect(228, 159, 541, 421)) self.chartsView.setObjectName("chartsView") self.updateChart_button = QtWidgets.QPushButton(self.centralwidget) self.updateChart_button.setGeometry(QtCore.QRect(610, 110, 161, 41)) font = QtGui.QFont() font.setPointSize(14) self.updateChart_button.setFont(font) self.updateChart_button.setObjectName("updateChart_button") self.updateChart_button.setText("Update") self.guide1 = QtWidgets.QLabel(self.centralwidget) self.guide1.setGeometry(QtCore.QRect(230, 100, 371, 20)) font = QtGui.QFont() font.setPointSize(10) font.setBold(True) font.setItalic(True) font.setWeight(75) self.guide1.setFont(font) self.guide1.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) self.guide1.setObjectName("guide1") self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget) self.horizontalLayoutWidget.setGeometry(QtCore.QRect( 230, 120, 371, 31)) self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget") self.horizontalLayout = QtWidgets.QHBoxLayout( self.horizontalLayoutWidget) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setObjectName("horizontalLayout") self.prevDate = QtWidgets.QDateEdit(self.horizontalLayoutWidget) self.prevDate.setMinimumDate(QtCore.QDate(2020, 3, 8)) self.prevDate.setDate(QtCore.QDate(2020, 3, 8)) self.prevDate.setObjectName("prevDate") self.horizontalLayout.addWidget(self.prevDate) self.currentDate = QtWidgets.QDateEdit(self.horizontalLayoutWidget) self.currentDate.setMinimumDateTime( QtCore.QDateTime(QtCore.QDate(2020, 3, 9), QtCore.QTime(0, 0, 0))) self.currentDate.setMinimumDate(QtCore.QDate(2020, 3, 9)) self.currentDate.setDate(QtCore.QDate(2020, 3, 9)) self.currentDate.setObjectName("currentDate") self.horizontalLayout.addWidget(self.currentDate) self.updateChart_button.raise_() self.horizontalLayoutWidget.raise_() self.prevDate.raise_() self.currentDate.raise_() self.chartsView.raise_() self.guide1.raise_() self.chartsView.hide() self.updateChart_button.hide() self.horizontalLayoutWidget.hide() self.prevDate.hide() self.currentDate.hide() self.guide1.hide() self.layoutlim = 0 #/ChartUI #Location UI self.locationView = QtWidgets.QLabel(self.centralwidget) self.locationView.setGeometry(QtCore.QRect(240, 110, 660, 520)) self.locationView.setObjectName("locationView") self.loc = location_widget(self.locationView) self.locationView.raise_() self.locationView.hide() #Patterns UI fontforLabel = QtGui.QFont() fontforLabel.setFamily("Montserrat") fontforLabel.setPointSize(17) fontforLabel.setBold(False) fontforLabel.setWeight(50) self.textBrowser_Current = QtWidgets.QLabel(self.centralwidget) self.textBrowser_Current.setStyleSheet( "QLabel { background-color : white; color : black; }") self.textBrowser_Current.setAlignment(QtCore.Qt.AlignCenter) self.textBrowser_Current.setGeometry(QtCore.QRect(290, 330, 201, 61)) self.textBrowser_Current.setObjectName("textBrowser_Current") self.textBrowser_Tomorrow = QtWidgets.QLabel(self.centralwidget) self.textBrowser_Tomorrow.setStyleSheet( "QLabel { background-color : white; color : black; }") self.textBrowser_Tomorrow.setAlignment(QtCore.Qt.AlignCenter) self.textBrowser_Tomorrow.setGeometry(QtCore.QRect(560, 330, 201, 61)) self.textBrowser_Tomorrow.setObjectName("textBrowser_Tomorrow") fontfortextbrowser1 = QtGui.QFont() fontfortextbrowser1.setFamily("Montserrat") fontfortextbrowser1.setPointSize(25) fontfortextbrowser1.setBold(False) fontfortextbrowser1.setWeight(100) self.textBrowser_Current.setFont(fontfortextbrowser1) self.textBrowser_Tomorrow.setFont(fontfortextbrowser1) self.label_Current = QtWidgets.QLabel(self.centralwidget) self.label_Current.setGeometry(QtCore.QRect(340, 270, 231, 61)) self.label_Current.setObjectName("label_Current") self.label_Current.setFont(fontforLabel) self.label_Tomorrow = QtWidgets.QLabel(self.centralwidget) self.label_Tomorrow.setGeometry(QtCore.QRect(545, 270, 231, 61)) self.label_Tomorrow.setObjectName("label_Tomorrow") self.label_Tomorrow.setAlignment(QtCore.Qt.AlignCenter) self.label_Tomorrow.setFont(fontforLabel) self.label_Current.raise_() self.label_Tomorrow.raise_() self.patterns_calcu() #/Patterns UI #News_UI self.doh_list = news_ui.news_ui(self.centralwidget) self.doh_list.setObjectName('doh_list') ws = DOH_Scrapper.DOH_Scrapper() ws.run() rawData = ws.getData() array_data = [] for x in rawData: data = news_ui.News() data.ArticleName = x[0] data.ArticleLink = x[1] array_data.append(data) self.doh_list.add_News(array_data) self.doh_list.raise_() #/News UI self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) #Data for Overview self.overview_data = COVID19_Scrapper.COVID19_Scrapper() data = [] data = self.overview_data.x self.cases_textBrowser.setText(data[0]) self.death_textBrowser.setText(data[1]) self.recoverd_textBrowser.setText(data[2]) #/Data for Overview self.updateChart_button.clicked.connect(self.on_update_chart_clicked) self.charts_button.clicked.connect(self.on_charts_clicked) self.patterns_button.clicked.connect(self.on_patterns_clicked) self.location_button.clicked.connect(self.on_location_clicked) self.overview_button.clicked.connect(self.on_overview_clicked) self.news_button.clicked.connect(self.on_news_clicked) self.on_overview_clicked() return def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "COVIDRecon")) self.total_cases.setText( _translate( "MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-weight:600; text-decoration: underline; color:#ffffff;\">TOTAL CASES</span></p></body></html>" )) self.total_death.setText( _translate( "MainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline; color:#ffffff;\">TOTAL DEATHS</span></p></body></html>" )) self.total_recovered.setText( _translate( "MainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline; color:#ffffff;\">TOTAL RECOVERED</span></p></body></html>" )) self.title_status.setText( _translate( "MainWindow", "<html><head/><body><p align=\"center\"><span style=\" color:#ffffff;\">COVID-19 Philippines</span></p></body></html>" )) self.overview_button.setToolTip( _translate("MainWindow", "Show Summary")) self.overview_button.setText(_translate("MainWindow", " OVERVIEW")) self.charts_button.setToolTip( _translate( "MainWindow", "<html><head/><body><p>Show latest cases of COVID-19.</p></body></html>" )) self.charts_button.setText(_translate("MainWindow", " CHARTS")) self.location_button.setText(_translate("MainWindow", " LOCATION")) self.patterns_button.setText(_translate("MainWindow", " PATTERNS")) self.about_button.setText(_translate("MainWindow", " ABOUT US")) self.label_Current.setText( _translate( "MainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline; color:#ffffff;\">Current</span></p></body></html>" )) self.label_Tomorrow.setText( _translate( "MainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline; color:#ffffff;text-align:center;\">After a Week</span></p></body></html>" )) self.about_button.clicked.connect(lambda: webbrowser.open( 'https://vppexis.github.io/CPE106L-ProjectCovidRecon/')) self.actionAbout_Us.setText(_translate("MainWindow", "About Us")) self.news_button.setText(_translate("MainWindow", "DOH NEWS")) self.about_button.clicked.connect(lambda: webbrowser.open( 'https://vppexis.github.io/CPE106L-ProjectCovidRecon/')) self.actionAbout_Us.setText(_translate("MainWindow", "About Us")) self.guide1.setText( _translate( "MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-weight:600; color:#ffffff;\">Date/Month/Year</span></p></body></html>" )) return #Gathers data for the chart. def data_gather(self): cursor = self.conn.cursor() cursor.execute( "SELECT date_rep_conf,COUNT(date_rep_conf) FROM casesByNCR GROUP BY date_rep_conf HAVING COUNT(date_rep_conf) > 1;" ) result = cursor.fetchall() self.df = pd.DataFrame(result, columns=['date', 'cases']) self.data_cases = self.df[['date', 'cases']] self.date_x = self.data_cases['date'] self.cases_y = self.data_cases['cases'] return #Main functin for charts. def setup_chart(self): if self.layoutlim == 0: # Date gather cursor = self.conn.cursor() cursor.execute( "SELECT date_rep_conf,COUNT(date_rep_conf) FROM casesByNCR GROUP BY date_rep_conf HAVING COUNT(date_rep_conf) > 1;" ) result = cursor.fetchall() self.df = pd.DataFrame(result, columns=['date', 'cases']) self.data_cases = self.df[['date', 'cases']] date_x = self.data_cases['date'] cases_y = self.data_cases['cases'] # Making the layout for the graph self.layout = QtWidgets.QVBoxLayout(self.chartsView) self.dynamic_canvas = FigureCanvasQTAgg(Figure(figsize=(5, 3))) self.layout.addWidget(self.dynamic_canvas) x = date_x y = np.cumsum(cases_y) dynamic_ax = self.dynamic_canvas.figure.subplots() self.dynamic_canvas.figure.autofmt_xdate() self.dynamic_canvas.figure.fmt_xdata = mdates.DateFormatter( '%y-%m-%d') self.recovered_chart() self.died_chart() dynamic_ax.plot(x, y, label='Cases', color='r') dynamic_ax.plot(self.R_x, self.R_y, label='Recovered', color='g') dynamic_ax.plot(self.D_x, self.D_y, label='Died', color='b') dynamic_ax.legend() dynamic_ax.set_xlabel('Dates of Report') dynamic_ax.set_ylabel('Population Affected') dynamic_ax.set_title('COVID-19 Cases') self.layoutlim = 1 return ### Chart for Recovered Data. def recovered_chart(self): cursor = self.conn.cursor() if self.layoutlim == 0: cursor.execute( "SELECT date_rep_conf, Count(health_status) from casesByNCR where health_status = 'Recovered'GROUP BY date_rep_conf;" ) result = cursor.fetchall() else: cursor.execute( "SELECT date_rep_conf,Count(health_status)from casesByNCR where (health_status = 'Recovered') And date_rep_conf between %s AND %s group by date_rep_conf", (self.minDate, self.maxDate)) result = cursor.fetchall() df = pd.DataFrame(result, columns=['date', 'recovered']) data_cases = df[['date', 'recovered']] self.R_x = data_cases['date'] self.R_y = np.cumsum(data_cases['recovered']) return ### Charts for dead data. def died_chart(self): cursor = self.conn.cursor() if self.layoutlim == 0: cursor.execute( "SELECT date_rep_conf, Count(health_status) from casesByNCR where health_status = 'Died'GROUP BY date_rep_conf;" ) result = cursor.fetchall() else: cursor.execute( "SELECT date_rep_conf,Count(health_status)from casesByNCR where (health_status = 'Died') And date_rep_conf between %s AND %s group by date_rep_conf", (self.minDate, self.maxDate)) result = cursor.fetchall() df = pd.DataFrame(result, columns=['date', 'Died']) data_cases = df[['date', 'Died']] self.D_x = data_cases['date'] self.D_y = np.cumsum(data_cases['Died']) return ### Updates the Graph def update_chart(self): self.minDate = self.prevDate.date().toPyDate() self.maxDate = self.currentDate.date().toPyDate() cursor = self.conn.cursor() cursor.execute( "SELECT date_rep_conf,Count(date_rep_conf) from casesByNCR where date_rep_conf between %s AND %s group by date_rep_conf having count(date_rep_conf) > 1;", (self.minDate, self.maxDate)) result = cursor.fetchall() df = pd.DataFrame(result, columns=['date', 'cases']) data_cases = df[['date', 'cases']] x = data_cases['date'] y = np.cumsum(data_cases['cases']) self.dynamic_canvas = FigureCanvasQTAgg(Figure(figsize=(5, 3))) self.layout.addWidget(self.dynamic_canvas) dynamic_ax = self.dynamic_canvas.figure.subplots() self.dynamic_canvas.figure.autofmt_xdate() self.dynamic_canvas.figure.fmt_xdata = mdates.DateFormatter('%y-%m-%d') self.recovered_chart() self.died_chart() dynamic_ax.plot(x, y, label='Cases', color='r') dynamic_ax.plot(self.R_x, self.R_y, label='Recovered', color='g') dynamic_ax.plot(self.D_x, self.D_y, label='Died', color='b') dynamic_ax.legend() dynamic_ax.set_xlabel('Dates of Report') dynamic_ax.set_ylabel('Population Affected') dynamic_ax.set_title('COVID-19 Cases') return ### Deletes the graph. def delete_canvas(self): self.dynamic_canvas.deleteLater() return ### Method for hiding Overview UI action def hide_overview_ui(self): self.total_cases.hide() self.total_death.hide() self.total_recovered.hide() self.cases_textBrowser.hide() self.death_textBrowser.hide() self.recoverd_textBrowser.hide() return ### Method for hiding Charts UI action def hide_charts_ui(self): self.chartsView.hide() self.updateChart_button.hide() self.horizontalLayoutWidget.hide() self.prevDate.hide() self.currentDate.hide() self.guide1.hide() return ### Method for hiding Location UI action def hide_location_ui(self): self.locationView.hide() return ### Method for hiding Patterns UI action def hide_patterns_ui(self): self.textBrowser_Current.hide() self.textBrowser_Tomorrow.hide() self.label_Current.hide() self.label_Tomorrow.hide() return ### Method for hiding News UI action. def hide_news_ui(self): self.doh_list.hide() return ### Method for Overview UI action. def on_overview_ui(self): self.total_cases.show() self.total_death.show() self.total_recovered.show() self.cases_textBrowser.show() self.death_textBrowser.show() self.recoverd_textBrowser.show() return ### Method for Charts UI action. def on_charts_ui(self): self.chartsView.show() self.updateChart_button.show() self.horizontalLayoutWidget.show() self.prevDate.show() self.currentDate.show() self.guide1.show() self.setup_chart() return ### Method for Location UI action. def on_location_ui(self): self.locationView.show() return ### Method for Patterns UI action. def on_patterns_ui(self): self.textBrowser_Current.show() self.textBrowser_Tomorrow.show() self.label_Current.show() self.label_Tomorrow.show() return ### Method for News UI action. def on_news_ui(self): self.doh_list.show() return ### Button action when overview is clicked. def on_overview_clicked(self): self.on_overview_ui() self.hide_charts_ui() self.hide_location_ui() self.hide_patterns_ui() self.hide_news_ui() return ### Button action when charts button is clicked. def on_charts_clicked(self): self.hide_overview_ui() self.on_charts_ui() self.hide_location_ui() self.hide_patterns_ui() self.hide_news_ui() return ### Button action when update button in charts ui is clicked. def on_update_chart_clicked(self): if self.layoutlim == 0: self.setup_chart() else: self.delete_canvas() self.update_chart() return ### Button action when location button is clicked. def on_location_clicked(self): self.hide_overview_ui() self.hide_charts_ui() self.on_location_ui() self.hide_patterns_ui() self.hide_news_ui() return ### Button action when patterns button is clicked. def on_patterns_clicked(self): self.hide_overview_ui() self.hide_charts_ui() self.hide_location_ui() self.on_patterns_ui() self.hide_news_ui() return ### Button action when news button is clicked. def on_news_clicked(self): self.hide_overview_ui() self.hide_charts_ui() self.hide_location_ui() self.hide_patterns_ui() self.on_news_ui() return ### Calculate the current data to predict future Cases. def patterns_calcu(self): gpd = getpastdate() self.textBrowser_Current.setText(str(gpd.get_past(0))) #current self.textBrowser_Tomorrow.setText(str(gpd.patterns_expected())) return
class Main(QMainWindow, Ui_MainWindow): def __init__(self, ): super(Main, self).__init__() self.setupUi(self) self.showMaximized() self.ave = np.array([]) # empty array for average bore self.auto_flag = False # autoscale flag self.spinBoxval = 0 # defualt 4D data_cube dimension self.spinBox.hide() # hide option unless 4D self.colourmap = 'viridis' # default colourmap self.interpMethod = 'nearest' # default interp method self.cmapmin = None # default colourbar range, i.e let matplotlib decide self.cmapmax = None self.hres = 1 # default res, i.e jut voxel numbers on axis self.vres = 1 self.Normx = None # normalisation method. default set to None self.Normy = None self.Normz = None self.XView.setChecked(True) self.fig = Figure() self.ax1 = self.fig.add_subplot(111) self.X = datacube() self.AveBoreView = 'X' # change view of cube self.XView.toggled.connect(lambda: self.btnstate(self.XView)) self.YView.toggled.connect(lambda: self.btnstate(self.YView)) self.ZView.toggled.connect(lambda: self.btnstate(self.ZView)) self.Bore.toggled.connect(lambda: self.btnstate(self.Bore)) self.AverageBore.toggled.connect( lambda: self.btnstate(self.AverageBore)) # update data when slider moved self.Scroll_Horz.valueChanged[int].connect(self.sliderval) self.Scroll_Vert.valueChanged[int].connect(self.sliderval) self.file_open(args) self.Open.triggered.connect(self.file_open) self.Save_Avg_Bore.triggered.connect(self.saveBore) self.Reset.triggered.connect(self.reset_plot) self.AutoScale.triggered.connect(self.Auto_Scale_plot) # self.Bore_View.triggered.connect(self.ViewBore) self.action_Save_Gif.triggered.connect(self.saveGif) self.action_Colour_Map.triggered.connect(self.changeColourMap) self.action_Interpolation_Method.triggered.connect(self.changeInterpolationMethod) self.action_Colour_Bar_Clip.triggered.connect(self.changeclipColourBarRange) self.action_Save_Image.triggered.connect(self.saveImage) self.action_Normalisation_Method.triggered.connect(self.changeNormMethod) self.action_Bore_Location.triggered.connect(self.setBoreLocation) self.spinBox.valueChanged.connect(self.changeSpinbox) def setBoreLocation(self, ): xloc, ok = QtWidgets.QInputDialog.getInt( self, 'Input location', 'Enter X location:') yloc, ok = QtWidgets.QInputDialog.getInt( self, 'Input location', 'Enter Y location:') self.Scroll_Horz.setValue(xloc) self.Scroll_Vert.setValue(yloc) if self.Bore.isChecked(): if self.BoreView == 'X': self.im.set_ydata(self.X.data[:, xloc, yloc][::]) elif self.BoreView == 'Y': self.im.set_ydata(self.X.data[xloc, :, yloc][::]) elif self.BoreView == 'Z': self.im.set_ydata(self.X.data[yloc, xloc, :][::]) # try and redraw try: self.im.axes.figure.canvas.draw() if self.auto_flag: self.im.autoscale() except AttributeError: pass def changeNormMethod(self, ): # func to change Normalisation method of matshow method = self.getNormDialog() if(method == 'Log'): self.Normx = colors.LogNorm(vmin=0.1, vmax=self.X.data[self.ind, :, :].max()) self.Normy = colors.LogNorm(vmin=0.1, vmax=self.X.data[:, self.ind, :].max()) self.Normz = colors.LogNorm(vmin=0.1, vmax=self.X.data[:, :, self.ind].max()) elif(method == 'Symmetric Log'): self.Normx = colors.SymLogNorm(linthresh=1., vmin=self.X.data[self.ind, :, :].min(), vmax=self.X.data[self.ind, :, :].max()) self.Normy = colors.SymLogNorm(linthresh=1., vmin=self.X.data[:, self.ind, :].min(), vmax=self.X.data[:, self.ind, :].max()) self.Normz = colors.SymLogNorm(linthresh=1., vmin=self.X.data[:, :, self.ind].max(), vmax=self.X.data[:, :, self.ind].max()) elif(method == 'Linear'): self.Normx = None self.Normy = None self.Normz = None self.reset_plot(False) self.init_plot() def saveImage(self, ): # saves data and image of current view name = self.showGifDialog() if self.XView.isChecked(): np.savetxt(name + '.dat', self.X.data[self.Scroll_Vert.value(), :, :], delimiter=' ') elif self.YView.isChecked(): np.savetxt(name + '.dat', self.X.data[:, self.Scroll_Vert.value(), :], delimiter=' ') elif self.ZView.isChecked(): np.savetxt(name + '.dat', self.X.data[:, :, self.Scroll_Vert.value()], delimiter=' ') self.hres, self.vres = self.showextentDialog() # scale x, y ticks to actual scale based upon user definition # thanks https://stackoverflow.com/a/17816809/6106938 # change so that it uses extent=[xmin, xmax, ymin, ymax] # set default as None # then change here. extent added to matshow(*args, extent=[...]) ticks = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x * self.hres)) self.ax1.xaxis.set_major_formatter(ticks) ticks = ticker.FuncFormatter(lambda y, pos: '{0:g}'.format(y * self.vres)) self.ax1.yaxis.set_major_formatter(ticks) self.fig.savefig(name + '.png') def changeColourMap(self, ): # change cmap self.colourmap = self.showColourmapsDialog() self.reset_plot(False) self.init_plot() def changeclipColourBarRange(self, ): # change vmin, vmax for cbar self.cmapmin, self.cmapmax = self.showclipColourBarDialog() self.reset_plot(False) self.init_plot() def changeInterpolationMethod(self, ): # change interpolation method for image self.interpMethod = str(self.showInterpolationDialog()) self.reset_plot(False) self.init_plot() def saveGif(self): rang = self.showGifframesDialog() # get range of frames step = self.showGifstepDialog() # get number of images name = self.showGifDialog() # name of file tight = self.showGifExtent() # tight or not # loop over range and make images tmpplace = self.Scroll_Vert.value() if rang * step > tmpplace: rang = tmpplace for i in range(rang): self.Scroll_Horz.setValue(self.ind) self.Scroll_Vert.setValue(tmpplace - (i * step)) self.sliderval() if tight: extent = self.ax1.get_window_extent().transformed(fig.dpi_scale_trans.inverted()) self.fig.savefig(str(i).zfill(3) + 'pic.png', bbox_inches=extent) else: self.fig.savefig(str(i).zfill(3) + 'pic.png') # use ffmpeg to create gif if tight: os.system("mogrify -trim *pic.png") os.system("ffmpeg -framerate 10 -pattern_type glob -i '*pic.png' -c:v libx264 -r 24 -pix_fmt yuv420p -vf 'pad=ceil(iw/2)*2:ceil(ih/2)*2' " + name + ".mp4") os.system('rm *pic.png') print('done') def changeSpinbox(self): # for 4d data cubes self.spinBoxval = int(self.spinBox.value()) fd = open(self.name, 'rb') self.readslice(fd, self.ndim, np.float64, self.cubeorder) self.reset_plot() self.init_plot() def Auto_Scale_plot(self): # autoscale cbar on plot and reset clipping if any self.cmapmin = None self.cmapmax = None if not self.auto_flag: self.auto_flag = True else: self.auto_flag = False def sliderval(self): # move slider and update data if self.XView.isChecked(): # fd = open(self.name, 'rb') self.X.readslice(self.Scroll_Horz.value()) self.im.set_data(self.X.data[self.Scroll_Vert.value(), :, :]) # self.Scroll_Horz.setValue(0) # pin unsed slider elif self.YView.isChecked(): self.X.readslice(self.Scroll_Horz.value()) self.im.set_data(self.X.data[:, self.Scroll_Vert.value(), :]) # self.Scroll_Horz.setValue(0) # pin unsed slider elif self.ZView.isChecked(): self.X.readslice(self.Scroll_Horz.value()) self.im.set_data(self.X.data[:, :, self.Scroll_Vert.value()]) # self.Scroll_Horz.setValue(0) # pin unsed slider elif self.Bore.isChecked(): if self.BoreView == 'X': self.im.set_ydata(self.X.data[:, self.Scroll_Horz.value(), self.Scroll_Vert.value()][::]) if self.auto_flag: self.ax1.relim() self.ax1.autoscale_view(True, True, True) elif self.BoreView == 'Y': self.im.set_ydata(self.X.data[self.Scroll_Horz.value(), :, self.Scroll_Vert.value()][::]) if self.auto_flag: self.ax1.relim() self.ax1.autoscale_view(True, True, True) elif self.BoreView == 'Z': self.im.set_ydata(self.X.data[self.Scroll_Vert.value(), self.Scroll_Horz.value(), :][::]) if self.auto_flag: self.ax1.relim() self.ax1.autoscale_view(True, True, True) elif self.AverageBore.isChecked(): self.Scroll_Horz.setValue(self.ind) self.Scroll_Vert.setValue(self.ind) # try and redraw try: self.im.axes.figure.canvas.draw() if self.auto_flag: self.im.autoscale() except AttributeError: pass def addmpl(self): # add plot to anvas self.rmmpl() self.canvas = FigureCanvas(self.fig) self.mplvl.addWidget(self.canvas) self.canvas.draw() self.toolbar = NavigationToolbar(self.canvas, self.mplwindow) self.mplvl.addWidget(self.toolbar) def rmmpl(self): # delete plot from canvas try: self.canvas.close() self.canvas.deleteLater() self.toolbar.close() self.toolbar.deleteLater() gc.collect() except: pass def saveBore(self,): # save bore as a list of points name = QtWidgets.QFileDialog.getSaveFileName(self, 'Save File') f = open(name, 'w') if len(self.ave) > 1: for i in range(len(self.ave)): f.write(str(self.ave[i]) + '\n') f.close() else: if self.BoreView == "X": tmp = self.X[:, self.Scroll_Horz.value(), self.Scroll_Vert.value()] elif self.BoreView == "Y": tmp = self.X[self.Scroll_Horz.value(), :, self.Scroll_Vert.value()] elif self.BoreView == "Z": tmp = self.X[self.Scroll_Horz.value(), self.Scroll_Vert.value(), :] for i in range(len(tmp)): f.write(str(tmp[i]) + '\n') def file_open(self, args): self.reset_plot() while True: try: # get file name if args.file is None: self.X.name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File')[0] else: self.X.name = args.file # get precision of data cube self.X.dtype, self.X.cubeorder, item = self.getPrec(args) # get dimensions of data cube. can be guessed bool4d = False if self.X.cubeorder == 4: bool4d = True self.X.ndim = self.getSize(args, item, bool4d) try: fd = open(self.X.name, 'rb') except FileNotFoundError: self.ErrorDialog("File not Found!") self.X.name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File')[0] self.X.readslice(0) self.init_plot() break except ValueError: size = os.path.getsize(self.X.name) if "Real*8" in item: size /= 8 elif "Real*4" in item: size /= 4 mssg = "Value of Ndim or precision is incorrect for this data cube.\n On disk size is: {:010d}.\n".format(int(size)) val2 = self.X.is_perfect_n(size, 2.) val3 = self.X.is_perfect_n(size, 3.) if (val2 and val3) != 0: mssg += " Try x=y={:04d}, z=1\n or x=y=z={:04d}.".format(int(val2), int(val3)) elif val2 != 0: mssg += "Try x=y={:04d}, z=1.".format(int(val2)) elif val3 != 0: mssg += "Try x=y=z={:04d}.".format(int(val3)) self.ErrorDialog(mssg) args.ndim = None args.fpprec = None except UnboundLocalError: pass break def getSize(self, args, item, bool4d): if args.ndim is None and item: size = os.path.getsize(self.X.name) if "Real*8" in item: size /= 8 elif "Real*4" in item: size /= 4 if self.X.is_perfect_n(size, 3.) != 0: size = self.X.is_perfect_n(size, 3.) ndim = (size, size, size) else: ndim = self.showNdimDialog(bool4d) else: ndim = (args.ndim, args.ndim, args.ndim) return ndim def getPrec(self, args): # get precision of data cube item = None if args.fpprec is None: item = str(self.showDtDialog()) if "Real*8" in item: dt = np.float64 elif "Real*4" in item: dt = np.float32 if "4 dim" in item: dim = 4 elif "3 dim" in item: dim = 3 else: if args.fpprec == 1: dt = np.float32 dim = 4 elif args.fpprec == 2: dt = np.float64 dim = 4 elif args.fpprec == 3: dt = np.float32 dim = 3 elif args.fpprec == 4: dt = np.float64 dim = 3 return dt, dim, item def btnstate(self, b): if b.text() == "X View": if b.isChecked() is True: self.reset_plot(False) self.Scroll_Vert.setMaximum(self.rows - 1) self.im = self.ax1.matshow(self.X.data[self.ind, :, :], vmin=self.cmapmin, vmax=self.cmapmax, cmap=str(self.colourmap), interpolation=self.interpMethod, norm=self.Normx) self.fig.colorbar(self.im) self.fig.set_tight_layout(True) self.ax1.set_aspect('auto') self.addmpl() if b.text() == "Y View": if b.isChecked() is True: self.reset_plot(False) self.Scroll_Vert.setMaximum(self.cols - 1) self.im = self.ax1.matshow(self.X.data[:, self.ind, :], vmin=self.cmapmin, vmax=self.cmapmax, cmap=str(self.colourmap), interpolation=self.interpMethod, norm=self.Normy) self.fig.colorbar(self.im) self.fig.set_tight_layout(True) self.ax1.set_aspect('auto') self.addmpl() if b.text() == "Z View": if b.isChecked() is True: self.reset_plot(False) self.Scroll_Vert.setMaximum(self.slices - 1) self.im = self.ax1.matshow(self.X.data[:, :, self.ind], vmin=self.cmapmin, vmax=self.cmapmax, cmap=str(self.colourmap), interpolation=self.interpMethod, norm=self.Normz) try: self.fig.colorbar(self.im) except ZeroDivisionError: self.ErrorDialog("Divison by zero, try another range") self.Normz = None self.Normy = None self.Normz = None self.cmapmin = None self.cmapmax = None self.btnstate(b) self.fig.set_tight_layout(True) self.ax1.set_aspect('auto') self.addmpl() if b.text() == "Draw Bore": if b.isChecked() is True: self.ViewBore() self.reset_plot(False) if self.BoreView == 'X': self.im, = self.ax1.plot(self.X.data[:, self.ind, self.ind]) elif self.BoreView == 'Y': self.im, = self.ax1.plot(self.X.data[self.ind, :, self.ind]) elif self.BoreView == 'Z': self.im, = self.ax1.plot(self.X.data[self.ind, self.ind, :]) self.fig.set_tight_layout(True) self.addmpl() if b.text() == "Avg. Bore": if b.isChecked() is True: self.AveBoreChecked() def ViewBore(self): self.BoreView = self.showBoreViewDialog() if self.BoreView == 'X': self.view = (1, 2) elif self.BoreView == 'Y': self.view = (0, 2) elif self.BoreView == 'Z': self.view = (0, 1) def AveBoreChecked(self): self.ViewBore() self.reset_plot(False) if len(self.ave) == 0: self.ave = np.array([]) self.ave = np.sum(self.X.data, self.view) self.ave /= (len(self.X.data[self.view[0]]) * len(self.X.data[self.view[1]])) self.im = self.ax1.plot(self.ave[::]) self.fig.set_tight_layout(True) self.addmpl() def reset_plot(self, *args): self.ave = np.array([]) self.fig.clf() self.ax1.clear() gc.collect() # fixes most of memory leak self.fig = Figure() self.ax1 = self.fig.add_subplot(111) self.rmmpl() def init_plot(self, ): self.rmmpl() if self.X.cubeorder == 4: self.rows, self.cols, self.slices, self.depth = self.X.ndim else: self.rows, self.cols, self.slices = self.X.ndim self.depth = 0 self.ind = 0 # int(rows / 2) if self.XView.isChecked(): view = self.XView self.Scroll_Vert.setMaximum(self.rows) self.Scroll_Horz.setMaximum(self.depth) elif self.YView.isChecked(): view = self.YView self.Scroll_Vert.setMaximum(self.cols) self.Scroll_Horz.setMaximum(self.depth) elif self.ZView.isChecked(): view = self.ZView self.Scroll_Vert.setMaximum(self.slices) self.Scroll_Horz.setMaximum(self.cols) elif self.AverageBore.isChecked(): view = self.AverageBore self.Scroll_Vert.setMaximum(self.rows) elif self.Bore_View.isChecked(): view = self.ViewBore self.Scroll_Vert.setMaximum(self.cols) self.Scroll_Horz.setMaximum(self.rows) self.btnstate(view) self.Scroll_Horz.setValue(self.ind) self.Scroll_Vert.setValue(self.ind) def showGifframesDialog(self, ): text, ok = QtWidgets.QInputDialog.getInt( self, '# of frames', 'Enter # of frames:') if ok: return(text) def showGifstepDialog(self, ): text, ok = QtWidgets.QInputDialog.getInt( self, 'Step size', 'Enter value of step:') if ok: return(text) def showGifExtent(self, ): items = ("Colour Bar", "No Colour Bar") text, ok = QtWidgets.QInputDialog.getItem( self, "Colour Bar on GIF?", " ", items, 0, False) if ok and text: if items == "Colour Bar": text = False else: text = True return text def showNdimDialog(self, bool4d): text1, ok1 = QtWidgets.QInputDialog.getInt( self, 'Input Ndim', 'Enter X Ndim:') if ok1: text2, ok2 = QtWidgets.QInputDialog.getInt( self, 'Input Ndim', 'Enter Y Ndim:') if ok2: text3, ok3 = QtWidgets.QInputDialog.getInt( self, 'Input Ndim', 'Enter Z Ndim:') if ok3 and bool4d: text4, ok4 = QtWidgets.QInputDialog.getInt( self, 'Input Ndim', 'Enter T Ndim:') return (text1, text2, text3, text4) else: return (text1, text2, text3) def showDtDialog(self, ): items = ("4 dim Real*4", "4 dim Real*8", "3 dim Real*4", "3 dim Real*8") item, ok = QtWidgets.QInputDialog.getItem(self, "Select Fortran Precision", "Precisions", items, 0, False) if ok and item: return item def showBoreViewDialog(self, ): items = ("X", "Y", "Z") item, ok = QtWidgets.QInputDialog.getItem(self, "Select Average Bore Direction", "Views", items, 0, False) if ok and item: return item def showGifDialog(self, ): text, ok = QtWidgets.QInputDialog.getText( self, 'Filename Dialog', 'Enter filename:') if ok: return str(text) def showextentDialog(self, ): hres, ok = QtWidgets.QInputDialog.getDouble( self, 'Data Extent', 'Enter horizontal resolution:', 0, -100, 100, 9,) if ok: vres, ok = QtWidgets.QInputDialog.getDouble( self, 'Data Extent', 'Enter vertical resolution:', 0, -100, 100, 9,) if ok: return (hres, vres) def getNormDialog(self, ): items = ("Log", "Linear", "Symmetric Log") item, ok = QtWidgets.QInputDialog.getItem(self, "Select cbar normalisation method", "Method:", items, 0, False) if ok and item: return item def showColourmapsDialog(self, ): items = ('viridis', 'inferno', 'plasma', 'magma', 'Blues', 'BuGn', 'BuPu', 'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd', 'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu', 'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd', 'afmhot', 'autumn', 'bone', 'cool', 'copper', 'gist_heat', 'gray', 'hot', 'pink', 'spring', 'summer', 'winter', 'BrBG', 'bwr', 'coolwarm', 'PiYG', 'PRGn', 'PuOr', 'RdBu', 'RdGy', 'RdYlBu', 'RdYlGn', 'Spectral', 'seismic', 'Accent', 'Dark2', 'Paired', 'Pastel1', 'Pastel2', 'Set1', 'Set2', 'Set3', 'Vega10', 'Vega20', 'Vega20b', 'Vega20c', 'gist_earth', 'terrain', 'ocean', 'gist_stern', 'brg', 'CMRmap', 'cubehelix', 'gnuplot', 'gnuplot2', 'gist_ncar', 'nipy_spectral', 'jet', 'rainbow', 'gist_rainbow', 'hsv', 'flag', 'prism') item, ok = QtWidgets.QInputDialog.getItem(self, "Select Colour Map", "Cmaps", items, 0, False) if ok and item: return item def showInterpolationDialog(self, ): items = ('none', 'nearest', 'bilinear', 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos') item, ok = QtWidgets.QInputDialog.getItem(self, "Select Interpolation Method", "Methods", items, 0, False) if ok and item: return item def showclipColourBarDialog(self, ): text1, ok1 = QtWidgets.QInputDialog.getDouble( self, 'Input cbar min', 'Enter min:', 0., np.finfo("d").min, np.finfo("d").max, 10) if ok1: text2, ok2 = QtWidgets.QInputDialog.getDouble( self, 'Input cbar max', 'Enter max:', 0., np.finfo("d").min, np.finfo("d").max, 10) if ok2: return (float(text1), float(text2)) def ErrorDialog(self, ErrMsg): QtWidgets.QMessageBox.warning(self, "Error", ErrMsg)