def on_fftBtn_clicked(self): try: npoints = int(self.fftNpointsEdit.text()) except ValueError: QMessageBox.warning(self, 'Error', 'Please enter a valid number of points.') return xmin = self.data.x.min() xmax = self.data.x.max() xinterp = linspace(xmin, xmax, npoints) yinterp = interp1d(self.data.x, self.data.y, kind='linear') yfft = fft(yinterp(xinterp)) p2 = abs(yfft) / npoints p1 = p2[:npoints // 2 + 2] p1[1:-1] *= 2 dx = (xmax - xmin) / (npoints - 1) new_data = ScanData.from_arrays(name='FFT(' + self.data.name + ')', x=(1. / dx) * arange(npoints // 2 + 2) / npoints, y=p1, dy=0.01 * ones(p1.shape), xcol='1/' + self.data.xaxis, ycol='|P1|') new_model = self.model.copy() from ufit.gui.scanitem import ScanDataItem session.add_item(ScanDataItem(new_data, new_model), self.item.group)
def _update_settings(self): """Update settings from controls.""" s = self.item.settings old_title = s.title title = s.title = self.titleBox.text() if title != old_title: self.item.update_htmldesc() xaxis = str(self.xaxisBox.currentText()) yaxis = str(self.yaxisBox.currentText()) if xaxis != s.xaxis or yaxis != s.yaxis: # new axes selected => discard limits on replot self.mapdata = None if xaxis == yaxis: QMessageBox.warning(self, 'Error', 'Please select distinct X ' 'and Y axes.') return s.xaxis = xaxis s.yaxis = yaxis s.interp = self.stepBox.value() s.zmin = maybe_float(self.zminEdit.text(), -1e300) s.zmax = maybe_float(self.zmaxEdit.text(), 1e300) s.yscale = maybe_float(self.scaleEdit.text(), 1.0) s.usemask = self.usemaskBox.isChecked() s.dots = self.dotsBox.isChecked() s.contour = self.contourBox.isChecked() s.logz = self.logBox.isChecked() s.gauss2d = self.fitBox.isChecked() session.set_dirty()
def on_subtractBtn_clicked(self): from ufit.gui.scanitem import ScanDataItem dlg = QDialog(self) loadUi(dlg, 'subtract.ui') data2obj = dlg.setList.populate(ScanDataItem) if dlg.exec_() != QDialog.Accepted: return witems = dlg.setList.selectedItems() if not witems: return try: prec = float(dlg.precisionEdit.text()) except ValueError: QMessageBox.warning(self, 'Error', 'Please enter a valid precision.') return new_data = self.data.subtract(data2obj[witems[0].type()].data, prec, dlg.destructBox.isChecked()) if not dlg.destructBox.isChecked(): new_model = self.model.copy() from ufit.gui.scanitem import ScanDataItem session.add_item(ScanDataItem(new_data, new_model), self.item.group) else: self.replotRequest.emit(None) session.set_dirty()
def on_mergeBtn_clicked(self): try: precision = float(self.mergeEdit.text()) except ValueError: QMessageBox.warning(self, 'Error', 'Enter a valid precision.') return new_data = self.datas[0].merge(precision, *self.datas[1:]) session.add_item(ScanDataItem(new_data), self.items[-1].group)
def save_session(self): if session.filename is None: return self.save_session_as() try: session.save() except Exception as err: logger.exception('Saving session failed') QMessageBox.warning(self, 'Error', 'Saving failed: %s' % err) return False return True
def on_actionExportParams_triggered(self): items = self.selected_items(ScanDataItem) dlg = ParamExportDialog(self, items) if dlg.exec_() != QDialog.Accepted: return expfilename = self._get_export_filename() if expfilename: try: dlg.do_export(expfilename) except Exception as e: logger.exception('While exporting parameters') QMessageBox.warning(self, 'Error', 'Could not export ' 'parameters: %s' % e)
def save_session_as(self): initialdir = session.dirname filename, _ = QFileDialog.getSaveFileName(self, 'Select file name', initialdir, 'ufit files (*.ufit)') if filename == '': return False session.set_filename(path_to_str(filename)) try: session.save() except Exception as err: logger.exception('Saving session failed') QMessageBox.warning(self, 'Error', 'Saving failed: %s' % err) return False return True
def on_rebinBtn_clicked(self): try: binsize = float(self.precisionEdit.text()) except ValueError: QMessageBox.warning(self, 'Error', 'Enter a valid precision.') return new_array, new_meta = rebin(self.data._data, binsize, self.data.meta) self.data.__init__(new_meta, new_array, self.data.xcol, self.data.ycol, self.data.ncol, self.data.nscale, name=self.data.name, sources=self.data.sources) self.replotRequest.emit(None) session.set_dirty()
def load_session(self, filename=None): if not filename: # Recent files action action = self.sender() if isinstance(action, QAction): if not self.check_save(): return filename = action.data() try: session.load(filename) with self.sgroup as settings: settings.setValue('loadfiledirectory', path.dirname(filename)) except Exception as err: logger.exception('Loading session %r failed' % filename) QMessageBox.warning(self, 'Error', 'Loading failed: %s' % err) else: self.re_expand_tree() self.setWindowModified(False) # if there are annotations, show the window automatically if session.props.get('annotations'): self.on_actionAnnotations_triggered()
def on_actionReorder_triggered(self): dlg = QDialog(self) loadUi(dlg, 'reorder.ui') data2obj = dlg.itemList.populate() if not dlg.exec_(): return new_structure = [] for i in range(dlg.itemList.count()): new_index = dlg.itemList.item(i).type() obj = data2obj[new_index] if isinstance(obj, ItemGroup): new_structure.append((obj, [])) else: if not new_structure: QMessageBox.warning( self, 'ufit', 'Reordering invalid: every data item ' 'must be below a group') return new_structure[-1][1].append(obj) session.reorder_groups(new_structure) self.re_expand_tree()
def on_addCustomBtn_clicked(self): dlg = QDialog(self) loadUi(dlg, 'custommodel.ui') while 1: if dlg.exec_() != QDialog.Accepted: return modelname = str(dlg.nameBox.text()) params = str(dlg.paramBox.text()) value = str(dlg.valueEdit.toPlainText()).strip() if not ident_re.match(modelname): QMessageBox.warning( self, 'Error', 'Please enter a valid model ' 'name (must be a Python identifier using ' 'only alphabetic characters and digits).') continue if not params: QMessageBox.warning(self, 'Error', 'Please enter some parameters.') continue for param in params.split(): if not ident_re.match(param): QMessageBox.warning( self, 'Error', 'Parameter name %s is not valid (must ' 'be a Python identifier using only alphabetic ' 'characters and digits).' % param) params = None break if not params: continue break self.insert_model_code('Custom(%r, %r, %r)' % (modelname, params, value))
def rebuild_map(self, quiet=True): s = self.item.settings try: self.mapdata = bin_mapping(s.xaxis, s.yaxis, self.item.datas, usemask=s.usemask, log=s.logz, yscale=s.yscale, interpolate=s.interp, minmax=(s.zmin, s.zmax)) return True except Exception as err: self.logger.exception('While creating mapping') if not quiet: err_text = str(err) # Qhull errors are *very* verbose. Discard everything except # the first paragraph. err_text = err_text.partition('\n\n')[0] QMessageBox.warning( self, 'Mapping error', 'Could not create mapping: %s (have you ' 'selected the right columns?)' % err_text) return False
def on_globalfitBtn_clicked(self): QMessageBox.warning(self, 'Sorry', 'Not implemented yet.')
def main(): app = QApplication([]) app.setOrganizationName('ufit') app.setApplicationName('gui') pixmap = QPixmap(':/splash.png') splash = QSplashScreen(pixmap, Qt.WindowStaysOnTopHint) splash.showMessage(u'Loading...' + u'\xa0' * 10 + '\n\n', Qt.AlignRight | Qt.AlignBottom) splash.show() time.sleep(0.1) with SettingGroup('main') as settings: if settings.value('current_version', '') != __version__: settings.setValue('current_version', __version__) # Execute here the actions to be performed only once after # each update (there is nothing there for now, but it could # be useful some day...) logger.info('Upgrade to version %s finished' % __version__) app.processEvents() def log_unhandled(*exc_info): logger.error('Unhandled exception in Qt callback', exc_info=exc_info) sys.excepthook = log_unhandled t1 = time.time() logger.info('Startup: import finished (%.3f s), starting GUI...' % (t1 - t0)) mainwindow = UFitMain() parser = optparse.OptionParser(usage='''\ Usage: %prog [-b directory] [.ufit file | data file] ''') parser.add_option('-b', '--browse', action='store', metavar='DIR', help='open browse window in specified directory') opts, args = parser.parse_args() if len(args) >= 1: datafile = path.abspath(args[0]) if path.isdir(datafile): # directory given, treat it as -b argument (browse) opts.browse = datafile elif datafile.endswith('.ufit'): try: mainwindow.filename = datafile mainwindow.load_session(datafile) except Exception as err: QMessageBox.warning(mainwindow, 'Error', 'Loading failed: %s' % err) mainwindow.filename = None else: dtempl, numor = extract_template(datafile) mainwindow.dloader.set_template(dtempl, numor, silent=False) mainwindow.show() if opts.browse: mainwindow.dloader.open_browser(opts.browse) t2 = time.time() logger.info('Startup: loading finished (%.3f s), main window opened' % (t2 - t1)) splash.deleteLater() app.exec_()