def _process_filenames(self): # TODO: allow multiple fileformats? # would need to modify input from DemonSession.notifyDataFile number_of_items = self.fileList.count() for i, filedesc in enumerate(self.params['filedescs']): uid = self.getIndexedUID(number_of_items + i) name = filedesc['filename'] filetype = filedesc.get('fileformat') if filetype is None or filetype not in ReaderRegistry.filetypes(): continue # Ignore unregistered file types self.add_to_flist(name, filetype, FILE, uid) try: # update display for selected live channel, # just cache otherwise self.setDataFromFile(name, filetype, uid, display=(i == self._livechannel)) except Exception as e: if uid in self._datacache: # image is already cached # suppress error message for cached image self.log.debug(e) else: # image is not cached and could not be loaded self.log.exception(e)
def on_actionOpen_triggered(self): """Open image file using registered reader classes.""" ftypes = { ffilter: ftype for ftype, ffilter in ReaderRegistry.filefilters() } fdialog = FileFilterDialog(self, "Open data files", "", ";;".join(ftypes.keys())) if self._fileopen_filter: fdialog.selectNameFilter(self._fileopen_filter) if fdialog.exec_() == fdialog.Accepted: self._fileopen_filter = fdialog.selectedNameFilter() tag = ftypes[self._fileopen_filter] files = fdialog.selectedFiles() if files: def _cacheFile(fn, tag): uid = uuid4() # setDataFromFile may raise an `NicosException`, e.g. # if the file cannot be opened. self.setDataFromFile(fn, tag, uid, display=False) return self.add_to_flist(fn, None, tag, uid) # load and display first item f = files.pop(0) self.fileList.setCurrentItem(_cacheFile(f, tag)) cachesize = self._cachesize - 1 # add first `cachesize` files to cache for _, f in enumerateWithProgress(files[:cachesize], "Loading data files...", parent=fdialog): _cacheFile(f, tag) # add further files to file list (open on request/itemClicked) for f in files[cachesize:]: self.add_to_flist(f, None, tag)
def setDataFromFile(self, filename, tag, uid=None, display=True): """Load data array from file and dispatch to live widgets using ``setData``. Do not use caching if uid is ``None``. """ try: array = ReaderRegistry.getReaderCls(tag).fromfile(filename) except KeyError: raise NicosError('Unsupported fileformat %r' % tag) if array is not None: self.setData(array, uid, display=display) else: raise NicosError('Cannot read file %r' % filename)
def on_actionOpen_triggered(self): """Open image file using registered reader classes.""" ftypes = { ffilter: ftype for ftype, ffilter in ReaderRegistry.filefilters() if not self._allowed_filetypes or ftype in self._allowed_filetypes } fdialog = FileFilterDialog(self, "Open data files", "", ";;".join(ftypes.keys())) if self._fileopen_filter: fdialog.selectNameFilter(self._fileopen_filter) if fdialog.exec_() != fdialog.Accepted: return files = fdialog.selectedFiles() if not files: return self._fileopen_filter = fdialog.selectedNameFilter() filetype = ftypes[self._fileopen_filter] errors = [] def _cacheFile(fn, filetype): uid = uuid4() # setDataFromFile may raise an `NicosException`, e.g. # if the file cannot be opened. try: self.setDataFromFile(fn, filetype, uid, display=False) except Exception as err: errors.append('%s: %s' % (fn, err)) else: return self.add_to_flist(fn, filetype, FILE, uid) # load and display first item f = files.pop(0) item = _cacheFile(f, filetype) if item is not None: self.fileList.setCurrentItem(item) cachesize = self._cachesize - 1 # add first `cachesize` files to cache for _, f in enumerateWithProgress(files[:cachesize], "Loading data files...", parent=fdialog): _cacheFile(f, filetype) # add further files to file list (open on request/itemClicked) for f in files[cachesize:]: self.add_to_flist(f, filetype, FILE) if errors: self.showError('Some files could not be opened:\n\n' + '\n'.join(errors))
def __init__(self, parent, client, options): Panel.__init__(self, parent, client, options) loadUi(self, 'panels/live.ui') self._allowed_tags = set() self._allowed_detectors = set() self._ignore_livedata = False # ignore livedata, e.g. wrong detector self._last_idx = 0 self._last_tag = None self._last_fnames = None self._last_format = None self._runtime = 0 self._range_active = False self._cachesize = 20 self._livewidgets = {} # livewidgets for rois: roi_key -> widget self._fileopen_filter = None self.widget = None self.menu = None self.statusBar = QStatusBar(self, sizeGripEnabled=False) policy = self.statusBar.sizePolicy() policy.setVerticalPolicy(QSizePolicy.Fixed) self.statusBar.setSizePolicy(policy) self.statusBar.setSizeGripEnabled(False) self.layout().addWidget(self.statusBar) self.toolbar = QToolBar('Live data') self.toolbar.addAction(self.actionOpen) self.toolbar.addAction(self.actionPrint) self.toolbar.addSeparator() self.toolbar.addAction(self.actionLogScale) self.toolbar.addSeparator() self.toolbar.addAction(self.actionKeepRatio) self.toolbar.addAction(self.actionUnzoom) self.toolbar.addAction(self.actionColormap) self.toolbar.addAction(self.actionMarkCenter) self.toolbar.addAction(self.actionROI) self._actions2D = [self.actionROI, self.actionColormap] self.setControlsEnabled(False) self.set2DControlsEnabled(False) # self.widget.setControls(Logscale | MinimumMaximum | BrightnessContrast | # Integrate | Histogram) self.liveitems = [] self.setLiveItems(1) self._livechannel = 0 self.splitter.setSizes([20, 80]) self.splitter.restoreState(self.splitterstate) if hasattr(self.window(), 'closed'): self.window().closed.connect(self.on_closed) client.livedata.connect(self.on_client_livedata) client.liveparams.connect(self.on_client_liveparams) client.connected.connect(self.on_client_connected) client.cache.connect(self.on_cache) self.rois = {} self.detectorskey = None # configure instrument specific behavior self._instrument = options.get('instrument', '') # self.widget.setInstrumentOption(self._instrument) # if self._instrument == 'toftof': # self.widget.setAxisLabels('time channels', 'detectors') # elif self._instrument == 'imaging': # self.widget.setControls(ShowGrid | Logscale | Grayscale | # Normalize | Darkfield | Despeckle | # CreateProfile | Histogram | MinimumMaximum) # self.widget.setStandardColorMap(True, False) # configure allowed file types supported_filetypes = ReaderRegistry.filetypes() opt_filetypes = set(options.get('filetypes', supported_filetypes)) self._allowed_tags = opt_filetypes & set(supported_filetypes) # configure allowed detector device names detectors = options.get('detectors') if detectors: self._allowed_detectors = set(detectors) # configure caching self._cachesize = options.get('cachesize', self._cachesize) if self._cachesize < 1: self._cachesize = 1 # always cache the last live image self._datacache = BoundedOrderedDict(maxlen=self._cachesize)
def __new__(mcs, clsname, bases, attrs): new_class = type.__new__(mcs, clsname, bases, attrs) # Add the notification class to the registry. ReaderRegistry.registerReader(new_class) return new_class
def readDataFromFile(filename, filetype): try: return ReaderRegistry.getReaderCls(filetype).fromfile(filename) except KeyError: raise NicosError('Unsupported file format %r' % filetype) from None
def __init__(self, parent, client, options): Panel.__init__(self, parent, client, options) loadUi(self, self.ui) self._allowed_filetypes = set() self._allowed_detectors = set() self._runtime = 0 self._range_active = False self._cachesize = 20 self._livewidgets = {} # livewidgets for rois: roi_key -> widget self._fileopen_filter = None self.widget = None self.menu = None self.unzoom = False self.lastSettingsIndex = None self._axis_labels = {} self.params = {} self._offset = 0 self.statusBar = QStatusBar(self, sizeGripEnabled=False) policy = self.statusBar.sizePolicy() policy.setVerticalPolicy(QSizePolicy.Fixed) self.statusBar.setSizePolicy(policy) self.statusBar.setSizeGripEnabled(False) self.layout().addWidget(self.statusBar) self.toolbar = QToolBar('Live data') self.toolbar.addAction(self.actionOpen) self.toolbar.addAction(self.actionPrint) self.toolbar.addAction(self.actionSavePlot) self.toolbar.addSeparator() self.toolbar.addAction(self.actionLogScale) self.toolbar.addSeparator() self.toolbar.addAction(self.actionKeepRatio) self.toolbar.addAction(self.actionUnzoom) self.toolbar.addAction(self.actionColormap) self.toolbar.addAction(self.actionMarkCenter) self.toolbar.addAction(self.actionROI) self._actions2D = [self.actionROI, self.actionColormap] self.setControlsEnabled(False) self.set2DControlsEnabled(False) # hide fileselection in liveonly mode self._liveOnlyIndex = options.get('liveonlyindex', None) if self._liveOnlyIndex is not None: self.pastFilesWidget.hide() self.statusBar.hide() # disable interactions with the plot self.setAttribute(Qt.WA_TransparentForMouseEvents) self.liveitems = [] self.setLiveItems(1) self._livechannel = 0 self.splitter.setSizes([20, 80]) self.splitter.restoreState(self.splitterstate) if hasattr(self.window(), 'closed'): self.window().closed.connect(self.on_closed) client.livedata.connect(self.on_client_livedata) client.connected.connect(self.on_client_connected) client.cache.connect(self.on_cache) self.rois = {} self.detectorskey = None # configure allowed file types supported_filetypes = ReaderRegistry.filetypes() opt_filetypes = set(options.get('filetypes', supported_filetypes)) self._allowed_filetypes = opt_filetypes & set(supported_filetypes) # configure allowed detector device names detectors = options.get('detectors') if detectors: self._allowed_detectors = set(detectors) defaults = options.get('defaults', []) if 'logscale' in defaults: self.actionLogScale.setChecked(True) if 'center' in defaults: self.actionMarkCenter.setChecked(True) if 'nolines' not in defaults: self.actionLines.setChecked(True) if 'markers' in defaults: self.actionSymbols.setChecked(True) if 'unzoom' in defaults: self.unzoom = True self.plotsettings = options.get('plotsettings', [DEFAULTS]) # configure caching self._cachesize = options.get('cachesize', self._cachesize) if self._cachesize < 1 or self._liveOnlyIndex is not None: self._cachesize = 1 # always cache the last live image self._datacache = BoundedOrderedDict(maxlen=self._cachesize) self._initControlsGUI()