def addSettings(self, param): """Adds a dockwidget designed to store a ParameterTree, also adds to 'Windows' menu""" parameterTree = ParameterTree() parameterTree.addParameters(param._PyQtGraphParameter) dock = self.addDock(parameterTree, name=param.getName(), area=Qt.TopDockWidgetArea) dock.setMaximumWidth(560) return dock
def __init__(self): super(maintest, self).__init__() self.values = {'module 1': module(1), 'module 2': module(2), 'module 3': module(3)} self.module = self.values['module 2'] p = [ {'name': 'Module', 'type': 'list', 'values': self.values, 'set': self.setmodule, 'get': self.getmodule, 'childmode': "root", 'help': '%namehdr%Boatload of text is possible here. Can use markup too with external help window.'}, {'name': 'Rocks to Skips', 'type': 'int', 'value': 0, 'help': 'Another help example', 'helpwnd': None, 'linked':['1/Rocks to Skips']}, {'name': '1/Rocks to Skips', 'type': 'float', 'help': 'Another help example', 'helpwnd': None, 'get': self.getLinked} ] self.params = Parameter(name='Root', type='group', children=p).register() self.params.init() self.t = ParameterTree() self.t.addParameters(self.params.getPyQtGraphParameter()) self.test = Parameter(name='Test', type='group') self.test.addChildren([ {'name':'baud', 'type':'int', 'key':'baud', 'limits':(500, 2000000), 'value':38400} ]) self.params.append(self.test) self.test.remove() self.test.getChild("baud").setValue(500) self.params.append(self.test) self.t2 = ParameterTree() self.params2 = Parameter(name='Root', type='group') self.params.getChild("Module").stealDynamicParameters(self.params2) self.t2.addParameters(self.params2._PyQtGraphParameter)
def __init__(self, parent, settings): super(GeneralTab, self).__init__(parent) self.settings = settings self.getParams().addChildren( [ { "name": "Project Folder", "type": "file", "filter": "dir", "get": lambda: self.settings.value("project-home-dir"), "set": lambda v: self.settings.setValue("project-home-dir", v), "psync": False, } ] ) parameterTree = ParameterTree() parameterTree.addParameters(self.getParams()._PyQtGraphParameter) defdirLayout = QHBoxLayout() defdirLayout.addWidget(parameterTree) mainLayout = QVBoxLayout() mainLayout.addLayout(defdirLayout) mainLayout.addStretch(1) self.setLayout(mainLayout)
def _draw_text_inputs(self, layout): """ Generates a GUI that can accept parameter values. """ params = [ {'name': 'damage :: Saturation Threshold', 'type': 'int', 'value': 10000, 'suffix': 'ADU'}, {'name': 'damage :: Area Threshold', 'type': 'int', 'value': 20, 'suffix': '%', 'limits': (0, 100)}, {'name': 'xtal :: Saturation Threshold', 'type': 'int', 'value': 5000, 'suffix': 'ADU'}, {'name': 'xtal :: Area Threshold', 'type': 'int', 'value': 1, 'suffix': '%', 'limits': (0, 100)}, {'name': 'diffuse :: Saturation Threshold', 'type': 'int', 'value': 1000, 'suffix': 'ADU'}, {'name': 'diffuse :: Area Threshold', 'type': 'int', 'value': 20, 'suffix': '%', 'limits': (0, 100)} ] self._params = Parameter.create(name='params', type='group', children=params) self._params.sigTreeStateChanged.connect(self._enable_apply) t = ParameterTree() t.setParameters(self._params, showTop=False) layout.addWidget(t, 0, 1) return
class Ui_ChildWindow(object): def setupUi(self, MainWindow, params): #app = QtGui.QApplication([]) #self.win = QtGui.QMainWindow() self.area = DockArea() MainWindow.setCentralWidget(self.area) MainWindow.resize(500, 700) MainWindow.setWindowTitle('Action construct') self.seq_cntr = Dock("Sequence", size=(150,200)) self.area.addDock(self.seq_cntr, 'left') ## first dock gets save/restore buttons self.t = ParameterTree() if params != None: self.p_child = Parameter.create(name='params', type='group', children=params) self.t.setParameters(self.p_child, showTop=False) self.t.setWindowTitle('pyqtgraph example: Parameter Tree') self.seq_cntr.addWidget(self.t) self.seq = pg.LayoutWidget() self.label = QtGui.QLabel("""Controls""") self.saveBtn = QtGui.QPushButton('Add Action') self.restoreBtn = QtGui.QPushButton('Modify table') self.restoreBtn.setEnabled(False) self.seq.addWidget(self.label, row=0, col=0) self.seq.addWidget(self.saveBtn, row=1, col=0) self.seq.addWidget(self.restoreBtn, row=2, col=0) self.seq_cntr.addWidget(self.seq)
class LayerControlTree(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.basicParam = {'name': 'Layer','expanded':False, 'type': 'group','autoIncrementName':True, 'children': [ {'name': 'LayerType', 'type': 'list', 'values': {"RGB": 0, "LAB": 1, "ChannelWise": 2}, 'value': 0}, {'name': 'Channel', 'type': 'int', 'value': 0,'limits':[0,2]}, {'name': 'Opacity', 'type': 'float', 'value': 0.0, 'step': 0.1,'limits':[0,1]}, {'name': 'Show', 'type': 'bool', 'value': True, 'tip': "Show / Hide this layer"}, {'name': 'HideOthers', 'type': 'action','tip':"Hide all other layers"}, {'name': 'Gradient', 'type': 'colormap'}, #{'name': 'Subgroup', 'type': 'group', 'children': [ # {'name': 'Sub-param 1', 'type': 'int', 'value': 10}, # {'name': 'Sub-param 2', 'type': 'float', 'value': 1.2e6}, #]}, #{'name': 'Text Parameter', 'type': 'text', 'value': 'Some text...'}, #{'name': 'Action Parameter', 'type': 'action'}, ]} params = [] self.paramGroup = Parameter.create(name='params', type='group', children=params) self.paramGroup.sigTreeStateChanged.connect(self.change) self.parameterTree = ParameterTree() self.parameterTree.setParameters(self.paramGroup, showTop=False) # add view box to graph view layout self.hbox = QtGui.QHBoxLayout() self.setLayout(self.hbox) self.hbox.addWidget(self.parameterTree) def addLayerControl(self,layer): layerParam = setupLayerParam(layer.layerName(),layer.baseControlTemplate(), layer.controlTemplate()) layerParam = self.paramGroup.addChild(layerParam) # pass parameter to layer itself layer.setLayerParameter(layerParam) def removeLayerControl(self,layer): paramToRemove = layer.layerParameter self.paramGroup.removeChild(paramToRemove) ## If anything changes in the tree, print a message def change(self,param, changes): #print("tree changes:") for param, change, data in changes: path = self.paramGroup.childPath(param) if path is not None: childName = '.'.join(path) else: childName = param.name()
class FringeRemoveNode(Node): """Node for removing fringes""" nodeName = 'FringeRemove' nodePaths = [('Analysis',)] def __init__(self, name): terminals = { 'sig':{'io':'in'}, 'ref':{'io':'in'}, 'bkg':{'io':'in'}, 'sigMask': {'io':'in'}, 'ref1':{'io':'out', 'bypass': '******'} } super().__init__(name, terminals=terminals) paras_property = [ {'name': 'rank', 'type': 'int', 'readonly': True}, {'name': 'rankLimit', 'type': 'int', 'value': 100}, {'name': 'trunc', 'type': 'float'}, {'name': 'updateLib', 'type': 'bool'}, {'name': 'reset', 'type': 'action'} ] self.paras = Parameter.create(name='params', type='group', children=paras_property) self.paratree = ParameterTree() self.paratree.setParameters(self.paras, showTop=False) self.remover = FringeRemove() self.paras.param('reset').sigActivated.connect(self.remover.reset) def onReset(self): self.remover.reset() self.paras['rank'] = 0 def ctrlWidget(self): return self.paratree def process(self, sig, ref, bkg, sigMask, display=True): self.remover.setTrunc(self.paras['trunc']) ref = ref - bkg if self.paras['updateLib'] and self.paras['rank'] <= self.paras['rankLimit']: self.remover.updateLibrary(ref) self.paras['rank'] = self.remover.rank sig = sig - bkg coef, ref = self.remover.reconstruct(np.ma.array(sig, mask=sigMask)) ref = ref.reshape(512, 512) + bkg return {'ref1': ref} def saveState(self): state = super().saveState() state['paras'] = self.paras.saveState() return state def restoreState(self, state): super().restoreState(state) self.paras.restoreState(state['paras'])
class maintest(Parameterized): def __init__(self): super(maintest, self).__init__() self.values = {'module 1': module(1), 'module 2': module(2), 'module 3': module(3)} self.module = self.values['module 2'] p = [ {'name': 'Module', 'type': 'list', 'values': self.values, 'set': self.setmodule, 'get': self.getmodule, 'childmode': "root", 'help': '%namehdr%Boatload of text is possible here. Can use markup too with external help window.'}, {'name': 'Rocks to Skips', 'type': 'int', 'value': 0, 'help': 'Another help example', 'helpwnd': None, 'linked': ['1/Rocks to Skips']}, {'name': '1/Rocks to Skips', 'type': 'float', 'help': 'Another help example', 'helpwnd': None, 'get': self.getLinked} ] self.params = Parameter(name='Root', type='group', children=p).register() self.params.init() self.t = ParameterTree() self.t.addParameters(self.params.getPyQtGraphParameter()) self.test = Parameter(name='Test', type='group') self.test.addChildren([ {'name': 'baud', 'type': 'int', 'key': 'baud', 'limits': (500, 2000000), 'value': 38400} ]) self.params.append(self.test) self.test.remove() self.test.getChild("baud").setValue(500) self.params.append(self.test) self.t2 = ParameterTree() self.params2 = Parameter(name='Root', type='group') self.params.getChild("Module").stealDynamicParameters(self.params2) self.t2.addParameters(self.params2._PyQtGraphParameter) self.params.save("abcde.txt") self.params.load("abcde.txt") def printhelp(self, msg, obj): print msg def getmodule(self): return self.module @setupSetParam("Module") def setmodule(self, module): print "Changing Module" self.module = module def getLinked(self): try: return 1.0 / float(self.params.getChild('Rocks to Skips').getValue()) except: return 0
def setupTree(): params = [ {'name':'Update Time (s)', 'type':'float', 'value':1}, {'name':'std', 'type':'float', 'value':0}, {'name':'Save Figure', 'type':'action', 'visible':True} ] p = Parameter.create(name = 'params', type = 'group', children = params) t = ParameterTree() t.setParameters(p, showTop = False) return t,p
def setupTree(): params = [ {'name':'Update Time (s)', 'type':'float', 'value':1}, {'name':'Sample Name', 'type':'int', 'value':1}, {'name':'Counter', 'type':'int', 'value':0} ] p = Parameter.create(name = 'params', type = 'group', children = params) t = ParameterTree() t.setParameters(p, showTop = False) return t,p
def __init__(self,dataSet=None): self.dataSet=dataSet ParameterTree.__init__(self) self.setObjectName("ConfigurationWidget") self.setWindowTitle("Measurement Configuration") self.setParams() self.p.sigTreeStateChanged.connect(self.change) self.connections=[] self.p.param("File Configuration","Folder").sigValueChanged.connect(self.folderModeChanged)
class InputCalibrationChannel(SheetForm, SheetBase): def __init__(self, config, channel, parent=None): SheetBase.__init__(self, parent) SheetForm.__init__(self) self.config = config self.channel = channel self.settings = self.config.get("InputCalibration.{0}".format(channel), ChannelSettings()) self.myCalibration = None self.treeWidget = None def setupUi(self, callback, MainWindow): SheetForm.setupUi(self, MainWindow) self.calibrationsCombo.addItems( list(AnalogInputCalibration.AnalogInputCalibrationMap.keys()) ) self.calibrationsCombo.currentIndexChanged["QString"].connect( self.onCalibrationChanged ) self.callback = callback if self.settings.calibration: self.onCalibrationChanged(self.settings.calibration) self.calibrationsCombo.setCurrentIndex(self.calibrationsCombo.findText(self.settings.calibration)) def onCalibrationChanged(self, calibration): calibration = str(calibration) if self.myCalibration: self.settings.parameters[self.settings.calibration] = self.myCalibration.parameters self.myCalibration = AnalogInputCalibration.AnalogInputCalibrationMap[calibration]() if calibration in self.settings.parameters: self.myCalibration.parameters = self.settings.parameters[calibration] if not self.treeWidget: try: self.param = Parameter.create(name='params', type='group', children=self.myCalibration.paramDef()) self.treeWidget = ParameterTree() self.treeWidget.setParameters(self.param, showTop=False) self.verticalLayout.insertWidget(2, self.treeWidget) self.param.sigTreeStateChanged.connect(self.myCalibration.update, QtCore.Qt.UniqueConnection) except (TypeError, AttributeError): pass else: self.param = Parameter.create(name='params', type='group', children=self.myCalibration.paramDef()) self.treeWidget.setParameters(self.param, showTop=False) try: self.param.sigTreeStateChanged.connect(self.myCalibration.update, QtCore.Qt.UniqueConnection ) except TypeError: pass # we want the connection to be unique self.settings.calibration = calibration self.callback( self.channel, self.myCalibration ) def saveConfig(self): if self.myCalibration: self.settings.parameters[self.settings.calibration] = self.myCalibration.parameters self.config["InputCalibration.{0}".format(self.channel)] = self.settings
def __init__(self): QtGui.QWidget.__init__(self) self.neuron_data = None self.setWindowTitle("Experiment Control - Data Analysis & Visualization") self.layout = QtGui.QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) self.splitter = QtGui.QSplitter() self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter2 = QtGui.QSplitter() self.splitter2.setOrientation(QtCore.Qt.Vertical) self.layout.addWidget(self.splitter) self.splitter.addWidget(self.splitter2) self.plot_widget = pg.GraphicsLayoutWidget() self.tree = ParameterTree(showHeader=False) self.params = Parameter.create( name="params", type="group", children=[ dict(name="Reanalyze", type="bool", value=False), dict(name="Load", type="action"), dict(name="GCFR-sigma (ms)", type="float", value=100.0, step=0.1, limits=[1, 5000]), dict(name="Save", type="action"), ], ) self.tree.setParameters(self.params, showTop=False) # self.params.param('Save').sigActivated.connect(self.SavePlot) self.params.param("Load").sigActivated.connect(self.OpenDataFile) self.splitter2.addWidget(self.tree) self.trial_list_tree = pg.TreeWidget(parent=self.splitter2) self.splitter.addWidget(self.plot_widget) self.trial_list_tree.setColumnCount(1)
def __init__(self, parent = None): #print "init!!!!!" self.parent = parent ## Dock: Labels self.dLabels = Dock("Labels", size=(1, 1)) self.wLabels = ParameterTree() self.wLabels.setWindowTitle('Labels') self.dLabels.addWidget(self.wLabels) self.labels_grp = 'Labels' self.labels_A_str = 'Single' self.labels_B_str = 'Multi' self.labels_C_str = 'Dunno' self.labelA = False self.labelB = False self.labelC = False ####################### # Mandatory parameter # ####################### self.params = [ {'name': self.labels_grp, 'type': 'group', 'children': [ {'name': self.labels_A_str, 'type': 'bool', 'value': self.labelA, 'tip': "Single"}, {'name': self.labels_B_str, 'type': 'bool', 'value': self.labelB, 'tip': "Multi"}, {'name': self.labels_C_str, 'type': 'bool', 'value': self.labelC, 'tip': "Dunno"}, ]}, ] self.pLabels = Parameter.create(name='paramsLabel', type='group', \ children=self.params, expanded=True) self.pLabels.sigTreeStateChanged.connect(self.change) self.wLabels.setParameters(self.pLabels, showTop=False)
def __init__(self, parent = None, savedstate=None): super(ProjectSettingsDialog, self).__init__(parent) self.setWindowTitle("Application Settings") layout = QtGui.QVBoxLayout(self) self.initKeyParamMapping() self._settings = Parameter.create(name='params', type='group', children=settings_params) if savedstate: self._settings.restoreState(savedstate) # Holds settings keys that have changed by the user when the # dialog is closed. Used to update any needed gui values.. self._updated_settings={} self._settings.sigTreeStateChanged.connect(self.handleSettingChange) self.initSettingsValues() self.ptree = ParameterTree() self.ptree.setParameters(self._settings, showTop=False) self.ptree.setWindowTitle('MarkWrite Application Settings') layout.addWidget(self.ptree) self.ptree.adjustSize() # OK and Cancel buttons self.buttons = QtGui.QDialogButtonBox( QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self) layout.addWidget(self.buttons) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) self.resize(500,700)
def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.basicParam = {'name': 'Layer','expanded':False, 'type': 'group','autoIncrementName':True, 'children': [ {'name': 'LayerType', 'type': 'list', 'values': {"RGB": 0, "LAB": 1, "ChannelWise": 2}, 'value': 0}, {'name': 'Channel', 'type': 'int', 'value': 0,'limits':[0,2]}, {'name': 'Opacity', 'type': 'float', 'value': 0.0, 'step': 0.1,'limits':[0,1]}, {'name': 'Show', 'type': 'bool', 'value': True, 'tip': "Show / Hide this layer"}, {'name': 'HideOthers', 'type': 'action','tip':"Hide all other layers"}, {'name': 'Gradient', 'type': 'colormap'}, #{'name': 'Subgroup', 'type': 'group', 'children': [ # {'name': 'Sub-param 1', 'type': 'int', 'value': 10}, # {'name': 'Sub-param 2', 'type': 'float', 'value': 1.2e6}, #]}, #{'name': 'Text Parameter', 'type': 'text', 'value': 'Some text...'}, #{'name': 'Action Parameter', 'type': 'action'}, ]} params = [] self.paramGroup = Parameter.create(name='params', type='group', children=params) self.paramGroup.sigTreeStateChanged.connect(self.change) self.parameterTree = ParameterTree() self.parameterTree.setParameters(self.paramGroup, showTop=False) # add view box to graph view layout self.hbox = QtGui.QHBoxLayout() self.setLayout(self.hbox) self.hbox.addWidget(self.parameterTree)
def onCalibrationChanged(self, calibration): calibration = str(calibration) if self.myCalibration: self.settings.parameters[self.settings.calibration] = self.myCalibration.parameters self.myCalibration = AnalogInputCalibration.AnalogInputCalibrationMap[calibration]() if calibration in self.settings.parameters: self.myCalibration.parameters = self.settings.parameters[calibration] if not self.treeWidget: try: self.param = Parameter.create(name='params', type='group', children=self.myCalibration.paramDef()) self.treeWidget = ParameterTree() self.treeWidget.setParameters(self.param, showTop=False) self.verticalLayout.insertWidget(2, self.treeWidget) self.param.sigTreeStateChanged.connect(self.myCalibration.update, QtCore.Qt.UniqueConnection) except (TypeError, AttributeError): pass else: self.param = Parameter.create(name='params', type='group', children=self.myCalibration.paramDef()) self.treeWidget.setParameters(self.param, showTop=False) try: self.param.sigTreeStateChanged.connect(self.myCalibration.update, QtCore.Qt.UniqueConnection ) except TypeError: pass # we want the connection to be unique self.settings.calibration = calibration self.callback( self.channel, self.myCalibration )
class SettingsEditorDialog(QtGui.QDialog): def __init__(self,ndViewer, parent): super(SettingsEditorDialog, self).__init__(parent) self.resize(800,600) self.ndViewer = ndViewer self.layout = QtGui.QVBoxLayout() self.setLayout(self.layout) self.paramTree = ParameterTree() self.paramTree.setParameters(self.ndViewer.options.p, showTop=False) self.layout.addWidget(self.paramTree) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: self.hide() event.accept() else: super(QtGui.QDialog, self).keyPressEvent(event)
class InstrumentLoggingSelection( SelectionUi ): def __init__(self, config, classdict, instancename="ExternalParameterSelection.ParametersSequence", plotNames=None, parent=None, instrumentLoggingHandler=None ): super(InstrumentLoggingSelection, self).__init__(config, dict(), classdict, instancename, parent) self.instrumentLoggingHandler = instrumentLoggingHandler self.current = None def setupUi(self, MainWindow): super(InstrumentLoggingSelection, self).setupUi(MainWindow) self.loggingHandlerTreeWidget = ParameterTree(self.splitter) self.loggingHandlerTreeWidget.setObjectName("loggingHandlerTreeWidget") self.loggingHandlerTreeWidget.headerItem().setText(0, "1") self.loggingHandlerTreeWidget.header().setVisible(False) def onActiveInstrumentChanged(self, modelIndex, modelIndex2 ): self.current = self.parameters.at(modelIndex.row()).name super(InstrumentLoggingSelection, self).onActiveInstrumentChanged( modelIndex, modelIndex2 ) self.loggingHandlerTreeWidget.setParameters( self.instrumentLoggingHandler.parameter(self.current) ) def refreshParamTree(self): if self.current is not None: self.loggingHandlerTreeWidget.setParameters( self.instrumentLoggingHandler.parameter(self.current) )
def __init__(self,ndViewer, parent): super(SettingsEditorDialog, self).__init__(parent) self.resize(800,600) self.ndViewer = ndViewer self.layout = QtGui.QVBoxLayout() self.setLayout(self.layout) self.paramTree = ParameterTree() self.paramTree.setParameters(self.ndViewer.options.p, showTop=False) self.layout.addWidget(self.paramTree)
def __init__(self, parent = None, with_config = False, **kargs ): QtGui.QWidget.__init__(self, parent) self.resize(800,600) mainlayout = QtGui.QVBoxLayout() self.setLayout(mainlayout) self.glview = gl.GLViewWidget() mainlayout.addWidget(self.glview) self.glview .setCameraPosition(160,160,15) if with_config: h = QtGui.QHBoxLayout() mainlayout.addLayout(h) but = QtGui.QPushButton('Config', icon = QtGui.QIcon.fromTheme('configure')) h.addWidget(but) but.clicked.connect(self.open_params) but = QtGui.QPushButton('Save png', icon = QtGui.QIcon.fromTheme('save')) h.addWidget(but) but.clicked.connect(self.open_save_dialog) _params = [ {'name': 'cortical_mesh', 'type': 'list', 'values': cortical_meshes.keys(), 'value' : 'BrainMesh_ICBM152'}, {'name': 'cortical_alpha', 'type': 'float', 'value': .1, 'limits': [0., 1.], 'step' : .01}, {'name': 'cortical_color', 'type': 'color', 'value': 'w'}, {'name': 'background_color', 'type': 'color', 'value': 'k'}, ] self.params = Parameter.create(name='params', type='group', children=_params) self.tree = ParameterTree(parent = self) self.tree.setParameters(self.params) self.tree.setWindowFlags(QtCore.Qt.Dialog) self.mesh = None for k,v in kargs.items(): self.params[k] = v self.change_background_color() self.plot_mesh() self.change_color_mesh() self.params.param('cortical_mesh').sigValueChanged.connect(self.plot_mesh) self.params.param('cortical_alpha').sigValueChanged.connect(self.change_color_mesh) self.params.param('cortical_color').sigValueChanged.connect(self.change_color_mesh) self.params.param('background_color').sigValueChanged.connect(self.change_background_color) self.glview.resizeGL(self.glview.width(), self.glview.height())
def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(MainWindow, self).__init__(parent) self.setupUi(self) self.plotly_pyqt5 = Plotly_PyQt5() '''手动调整窗口部件的大小,使之看着更美观''' self.widget_parameter_tree.setMaximumWidth(300) self.widget_parameter_tree.setMinimumWidth(200) self.QWebEngineView_ProductVsHs300.setMinimumHeight(500) self.tabWidget.setMinimumHeight(400) '''显示parametertree,这里通过布局管理器来把ParameterTree间接地嵌套进Widget窗口里面''' from mypyqtgraph import p from pyqtgraph.parametertree import ParameterTree t = ParameterTree() t.setParameters(p, showTop=False) t.setHeaderLabels(["参数", "数值"]) # t.setWindowTitle('pyqtgraph example: Parameter Tree') layout = QtGui.QGridLayout() self.widget_parameter_tree.setLayout(layout) layout.addWidget( QtGui.QLabel("千石资本-和聚光明1号资产管理计划基本信息"), 0, 0, 1, 1) layout.addWidget(t) '''显示绘图函数''' self.QWebEngineView_ProductVsHs300.load( QUrl.fromLocalFile(self.plotly_pyqt5.get_plotly_path_product_vs_hs300())) self.QWebEngineView_LagestBack.load(QUrl.fromLocalFile(self.plotly_pyqt5.get_plotly_path_lagest_back())) self.QWebEngineView_PeriodReturn.load(QUrl.fromLocalFile(self.plotly_pyqt5.get_plotly_path_period_return())) self.QWebEngineview_MonthReturn.load(QUrl.fromLocalFile(self.plotly_pyqt5.get_plotly_path_month_return()))
def __init__(self, title, paramlist, about="", doneButton=False, appendable=False): super(ParameterWidget, self).__init__() self.ParamGroup = ScalableGroup if appendable else pTypes.GroupParameter self.hasDone = doneButton self.parameters = self.ParamGroup(name="Parameters", children=ParameterWidget.build_parameter_list(paramlist)) self.parameters.sigTreeStateChanged.connect(self.paramsChanged) self.info = about self.tree = ParameterTree() self.tree.setParameters(self.parameters, showTop=False) self.tree.setWindowTitle(title) self.makeLayout() self.resize(800, 600)
def setupTree(startup): params = [ {'name':'ChA', 'type':'int', 'value': startup['ChA']}, {'name':'BiasV_ChA', 'type':'float', 'value': startup['BiasV_ChA']}, {'name':'ChA Singles (cps)', 'type':'float', 'value': startup['ChA Singles (cps)']}, {'name':'ChB', 'type':'int', 'value':startup['ChB']}, {'name':'BiasV_ChB', 'type':'float', 'value':startup['BiasV_ChB']}, {'name':'ChB Singles (cps)', 'type':'float', 'value': startup['ChB Singles (cps)']}, {'name':'Min (s)', 'type':'float', 'value':startup['Min (s)']}, {'name':'Max (s)', 'type':'float', 'value':startup['Max (s)']}, {'name':'binSize', 'type':'int', 'value':startup['binSize']}, {'name':'Update Time (s)', 'type':'float', 'value' :startup['Update Time (s)']}, {'name':'Counter', 'type':'int', 'value':startup['Counter']}, {'name':'algorithm', 'type':'str', 'value':startup['algorithm']}, {'name':'Pause Histogram', 'type':'bool', 'value':startup['Pause Histogram']}, {'name':'Reset Histogram', 'type':'action', 'visible':startup['Reset Histogram']}, {'name':'Save Path', 'type':'str', 'value':startup['Save Path']}, {'name':'Save Figure', 'type':'action', 'visible':startup['Save Figure']}, {'name':'Save Data', 'type':'action', 'visible':startup['Save Data']} ] p = Parameter.create(name = 'params', type = 'group', children = params) t = ParameterTree() t.setParameters(p, showTop = False) return t,p
def setupParametersTree(self): """Setup all parameter trees so they can be reloaded later with changes""" self.params = Parameter.create(name='Generic Settings', type='group', children=self.cwParams) ExtendedParameter.setupExtended(self.params, self) self.paramTree = ParameterTree() self.paramTree.setParameters(self.params, showTop=False) self.preprocessingParamTree = ParameterTree() self.attackParamTree = ParameterTree() self.postprocessingParamTree = ParameterTree() self.resultsParamTree = ParameterTree() self.results.paramListUpdated.connect(self.reloadParamListResults) self.reloadParamListResults()
def __init__(self): QtCore.QObject.__init__(self) self.initParam() ## Create tree of Parameter objects self.parameter = Parameter.create(name='OCR Parameter', type='group', children=self.params) def turn2change(param, changes): self.changeParam(param, changes) self.parameter.sigTreeStateChanged.connect(turn2change) self.tree = ParameterTree(None, showHeader=False) self.tree.setParameters(self.parameter, showTop=True) #Lazy Mode: self.textList = None self.ocrIndex = None
def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setWindowTitle("PyeMovements") self.modelpicker = QComboBox() self.modelpicker.addItem("CRISP") self.modelparams = Parameter.create(name='params', type='group', children=self.params) self.paramtree = ParameterTree() self.paramtree.setParameters(self.modelparams, showTop=False) self.nsaccadelab = QLabel("# Saccades") self.nsaccadelab.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.nsaccades = QSpinBox() self.nsaccades.setRange(1,1000000) self.nsaccades.setValue(10000) self.runbutton = QPushButton("Start simulation") self.runbutton.clicked.connect(self.handle_runbutton_clicked) self.resetbutton = QPushButton("Reset simulation") self.resetbutton.setEnabled(False) self.resetbutton.clicked.connect(self.handle_resetbutton_clicked) self.centralwidget = QWidget(self) self.fixation_plot_widget = pg.PlotWidget(title="Fixation Duration Histogram",labels={"left":"Count","bottom":"Duration (s)"}) self.fixation_plot_data = pg.PlotDataItem() self.grid = QGridLayout() self.grid.addWidget(self.modelpicker,0,0,1,2) self.grid.addWidget(self.paramtree,1,0,1,2) self.grid.addWidget(self.nsaccadelab,2,0,1,1) self.grid.addWidget(self.nsaccades,2,1,1,1) self.grid.addWidget(self.runbutton,3,0,1,1) self.grid.addWidget(self.resetbutton,3,1,1,1) self.grid.addWidget(self.fixation_plot_widget,0,2,4,1) self.setCentralWidget(self.centralwidget) self.centralwidget.setLayout(self.grid) self.sim_reset() self.plots_timer = QTimer() self.plots_timer.timeout.connect(self.updateFixationPlot) self.plots_timer.start(50)
def initUI(self): '''Initializes the main window widgets.''' self.initToolBar() self.initMenuBar() self.parametertree = ParameterTree() self.viewwidget = gl.GLViewWidget() widget = QtGui.QWidget() hbox = QtGui.QHBoxLayout(widget) hbox.addWidget(self.parametertree) hbox.addWidget(self.viewwidget, 1) self.setCentralWidget(widget) self.resize(1200, 600) self.setWindowTitle('MolViewer :: Main window') self.drawgrid() self.show()
def setupUi(self, Form): Form.setObjectName(_fromUtf8("Form")) Form.resize(241, 367) Form.setWindowTitle(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8)) self.gridLayout = QtGui.QGridLayout(Form) self.gridLayout.setSpacing(0) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label = QtGui.QLabel(Form) self.label.setText(QtGui.QApplication.translate("Form", "Item to export:", None, QtGui.QApplication.UnicodeUTF8)) self.label.setObjectName(_fromUtf8("label")) self.gridLayout.addWidget(self.label, 0, 0, 1, 3) self.itemTree = QtGui.QTreeWidget(Form) self.itemTree.setObjectName(_fromUtf8("itemTree")) self.itemTree.headerItem().setText(0, _fromUtf8("1")) self.itemTree.header().setVisible(False) self.gridLayout.addWidget(self.itemTree, 1, 0, 1, 3) self.label_2 = QtGui.QLabel(Form) self.label_2.setText(QtGui.QApplication.translate("Form", "Export format", None, QtGui.QApplication.UnicodeUTF8)) self.label_2.setObjectName(_fromUtf8("label_2")) self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3) self.formatList = QtGui.QListWidget(Form) self.formatList.setObjectName(_fromUtf8("formatList")) self.gridLayout.addWidget(self.formatList, 3, 0, 1, 3) self.exportBtn = QtGui.QPushButton(Form) self.exportBtn.setText(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8)) self.exportBtn.setObjectName(_fromUtf8("exportBtn")) self.gridLayout.addWidget(self.exportBtn, 6, 1, 1, 1) self.closeBtn = QtGui.QPushButton(Form) self.closeBtn.setText(QtGui.QApplication.translate("Form", "Close", None, QtGui.QApplication.UnicodeUTF8)) self.closeBtn.setObjectName(_fromUtf8("closeBtn")) self.gridLayout.addWidget(self.closeBtn, 6, 2, 1, 1) self.paramTree = ParameterTree(Form) self.paramTree.setObjectName(_fromUtf8("paramTree")) self.paramTree.headerItem().setText(0, _fromUtf8("1")) self.paramTree.header().setVisible(False) self.gridLayout.addWidget(self.paramTree, 5, 0, 1, 3) self.label_3 = QtGui.QLabel(Form) self.label_3.setText(QtGui.QApplication.translate("Form", "Export options", None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setObjectName(_fromUtf8("label_3")) self.gridLayout.addWidget(self.label_3, 4, 0, 1, 3) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form)
def __init__(self, parent = None): self.parent = parent ## Dock 8: Quantifier self.dSmall = Dock("Small Data", size=(100, 100)) self.w8 = ParameterTree() self.dSmall.addWidget(self.w8) self.w11a = pg.LayoutWidget() self.refreshBtn = QtGui.QPushButton('Refresh') self.w11a.addWidget(self.refreshBtn, row=0, col=0) self.dSmall.addWidget(self.w11a) # Add plot self.w9 = pg.PlotWidget(title="Metric") self.dSmall.addWidget(self.w9) # Quantifier parameter tree self.quantifier_grp = 'Small data' self.quantifier_filename_str = 'filename' self.quantifier_dataset_str = 'dataset' self.quantifier_sort_str = 'sort' # Quantifier self.quantifier_filename = '' self.quantifier_dataset = '/entry_1/result_1/' self.quantifier_sort = False self.quantifierFileOpen = False self.quantifierHasData = False self.params = [ {'name': self.quantifier_grp, 'type': 'group', 'children': [ {'name': self.quantifier_filename_str, 'type': 'str', 'value': self.quantifier_filename, 'tip': "Full path Hdf5 filename"}, {'name': self.quantifier_dataset_str, 'type': 'str', 'value': self.quantifier_dataset, 'tip': "Hdf5 dataset metric, nPeaksAll or nHitsAll"}, {'name': self.quantifier_sort_str, 'type': 'bool', 'value': self.quantifier_sort, 'tip': "Ascending sort metric"}, ]}, ] self.pSmall = Parameter.create(name='paramsQuantifier', type='group', \ children=self.params, expanded=True) self.w8.setParameters(self.pSmall, showTop=False) self.pSmall.sigTreeStateChanged.connect(self.change) self.refreshBtn.clicked.connect(self.reloadQuantifier)
def set_GUI(self): """ Create the graphic interface of the h5 file analyser, including: * *h5 file dock* : QtreeWidget (custom instance of Tree_layout) showing the contents of the h5 file * *status bar* : the top_down information bar * *tree_dock* : The QTree viewer * *1D viewer dock* : the preview window of 1D data * *2D viewer dock* : the preview window of 2D data * *Navigator viewer dock* : the global navigator graphic interface """ # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # h5 file dock V_splitter = QtWidgets.QSplitter(Qt.Vertical) H_splitter = QtWidgets.QSplitter(Qt.Horizontal) Form = QtWidgets.QWidget() self.ui.h5file_tree = Tree_layout(Form, col_counts=2, labels=["Node", 'Pixmap']) self.ui.h5file_tree.ui.Tree.setMinimumWidth(250) self.ui.h5file_tree.ui.Tree.itemClicked.connect( self.show_h5_attributes) self.ui.h5file_tree.ui.Tree.itemDoubleClicked.connect( self.show_h5_data) V_splitter.addWidget(Form) self.ui.attributes_table = pymodaq_ptypes.Table_custom() V_splitter.addWidget(self.ui.attributes_table) H_splitter.addWidget(V_splitter) self.ui.settings_tree = ParameterTree() self.ui.settings_tree.setMinimumWidth(300) H_splitter.addWidget(self.ui.settings_tree) self.ui.menubar = self.mainwindow.menuBar() self.create_menu(self.ui.menubar) # %%create status bar self.ui.statusbar = QtWidgets.QStatusBar() self.ui.statusbar.setMaximumHeight(25) # %% create tree dock file_dock = Dock("File data", size=(1, 1), autoOrientation=False) # give this dock the minimum possible size file_dock.setOrientation('vertical') file_dock.addWidget(H_splitter) file_dock.addWidget(self.ui.statusbar) self.settings = Parameter.create(name='Param', type='group') self.ui.settings_tree.setParameters(self.settings, showTop=False) # #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # #% 1D viewer Dock viewer1D_widget = QtWidgets.QWidget() self.ui.viewer1D = Viewer1D(viewer1D_widget) dock1D = Dock('Viewer1D') dock1D.addWidget(viewer1D_widget) # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # % 2D viewer Dock viewer2D_widget = QtWidgets.QWidget() self.ui.viewer2D = Viewer2D(viewer2D_widget) dock2D = Dock('Viewer2D') dock2D.addWidget(viewer2D_widget) # #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # #% Navigator viewer Dock navigator1D_widget = QtWidgets.QWidget() self.ui.navigator1D = Viewer1D(navigator1D_widget) self.ui.navigator1D.ui.crosshair.crosshair_dragged.connect( self.update_viewer_data) self.ui.navigator1D.ui.crosshair_pb.click() navigator2D_widget = QtWidgets.QWidget() self.ui.navigator2D = Viewer2D(navigator2D_widget) self.ui.navigator2D.crosshair_dragged.connect( self.update_viewer_data ) # export scaled position in conjonction with 2D scaled axes self.ui.navigator2D.ui.crosshair_pb.click() dock_nav = Dock('Navigator') dock_nav.addWidget(navigator1D_widget) dock_nav.addWidget(navigator2D_widget, 1, 0) self.dockarea.addDock(file_dock, 'top') self.dockarea.addDock(dock2D, 'right', file_dock) self.dockarea.addDock(dock1D, 'bottom', dock2D) self.dockarea.addDock(dock_nav, 'right', dock2D)
class TreeFromToml(QObject): def __init__(self, conf_path=None): super().__init__() self.config_path = utils.get_set_local_dir().joinpath('config.toml') config = utils.load_config(self.config_path) params = [{ 'title': 'Config path', 'name': 'config_path', 'type': 'str', 'value': str(self.config_path), 'readonly': True }] params.extend(self.dict_to_param(config)) self.settings = Parameter.create(title='settings', name='settings', type='group', children=params) self.settings_tree = ParameterTree() self.settings_tree.setParameters(self.settings, showTop=False) def show_dialog(self): self.dialog = QtWidgets.QDialog() self.dialog.setWindowTitle('Please enter new configuration values!') self.dialog.setLayout(QtWidgets.QVBoxLayout()) buttonBox = QtWidgets.QDialogButtonBox(parent=self.dialog) buttonBox.addButton('Save', buttonBox.AcceptRole) buttonBox.accepted.connect(self.dialog.accept) buttonBox.addButton('Cancel', buttonBox.RejectRole) buttonBox.rejected.connect(self.dialog.reject) self.dialog.layout().addWidget(self.settings_tree) self.dialog.layout().addWidget(buttonBox) self.dialog.setWindowTitle('Configuration entries') res = self.dialog.exec() if res == self.dialog.Accepted: with open(self.config_path, 'w') as f: config = self.param_to_dict(self.settings) config.pop('config_path') toml.dump(config, f) @classmethod def param_to_dict(cls, param): config = dict() for child in param.children(): if 'group' in child.opts['type']: config[child.name()] = cls.param_to_dict(child) else: if child.opts['type'] == 'datetime': config[child.name()] = datetime.fromtimestamp( child.value().toSecsSinceEpoch() ) # convert QDateTime to python datetime elif child.opts['type'] == 'date': qdt = QtCore.QDateTime() qdt.setDate(child.value()) pdt = datetime.fromtimestamp(qdt.toSecsSinceEpoch()) config[child.name()] = pdt.date() elif child.opts['type'] == 'list': config[child.name()] = child.opts['limits'] else: config[child.name()] = child.value() return config @classmethod def dict_to_param(cls, config): params = [] for key in config: if isinstance(config[key], dict): params.append({ 'title': f'{key.capitalize()}:', 'name': key, 'type': 'group', 'children': cls.dict_to_param(config[key]), 'expanded': 'user' in key.lower() or 'general' in key.lower() }) else: param = { 'title': f'{key.capitalize()}:', 'name': key, 'value': config[key] } if isinstance(config[key], float): param['type'] = 'float' elif isinstance( config[key], bool ): # placed before int because a bool is an instance of int param['type'] = 'bool' elif isinstance(config[key], int): param['type'] = 'int' elif isinstance(config[key], datetime.datetime): param['type'] = 'datetime' elif isinstance(config[key], datetime.date): param['type'] = 'date' elif isinstance(config[key], str): param['type'] = 'str' elif isinstance(config[key], list): param['type'] = 'list' param['values'] = config[key] param['value'] = config[key][0] param['show_pb'] = True params.append(param) return params
class ScanSelector(QObject): scan_select_signal = pyqtSignal(ROI) params = [ { 'title': 'Scan options', 'name': 'scan_options', 'type': 'group', 'children': [ { 'title': 'Sources:', 'name': 'sources', 'type': 'list', }, { 'title': 'Viewers:', 'name': 'viewers', 'type': 'list', }, { 'title': 'Scan type:', 'name': 'scan_type', 'type': 'list', 'values': ['Scan1D', 'Scan2D'], 'value': 'Scan2D' }, ] }, { 'title': 'Scan Area', 'name': 'scan_area', 'type': 'group', 'children': [ { 'title': 'ROI select:', 'name': 'ROIselect', 'type': 'group', 'visible': True, 'children': [ { 'title': 'x0:', 'name': 'x0', 'type': 'int', 'value': 0, 'min': 0 }, { 'title': 'y0:', 'name': 'y0', 'type': 'int', 'value': 0, 'min': 0 }, { 'title': 'width:', 'name': 'width', 'type': 'int', 'value': 10, 'min': 1 }, { 'title': 'height:', 'name': 'height', 'type': 'int', 'value': 10, 'min': 1 }, ] }, { 'title': 'Coordinates:', 'name': 'coordinates', 'type': 'itemselect', 'visible': True }, ] }, ] def __init__(self, viewer_items=[], scan_type='Scan2D', positions=[]): """ Parameters ---------- viewer_items: dict where the keys are the titles of the sources while the values are dict with keys viewers: list of plotitems names: list of viewer titles scan_type: (str) either 'Scan1D' correspondign to a polyline ROI or 'Scan2D' for a rect Roi positions: list in case of 'Scan1D', should be a sequence of 2 floats sequence [(x1,y1),(x2,y2),(x3,y3),...] in case of 'Scan2D', should be a sequence of 4 floats (x, y , w, h) """ super(ScanSelector, self).__init__() self._viewers_items = viewer_items self.sources_names = list(viewer_items.keys()) if len(viewer_items) != 0: self.scan_selector_source = viewer_items[ self.sources_names[0]]['viewers'][0] else: self.scan_selector_source = None self.scan_selector = None self.setupUI() self.settings.child('scan_options', 'scan_type').setValue(scan_type) self.remove_scan_selector() if self.scan_selector_source is not None: if len(viewer_items[self.sources_names[0]]['viewers']) == 1: self.settings.child('scan_options', 'viewers').hide() else: self.settings.child('scan_options', 'viewers').hide() self.update_scan_area_type() if scan_type == "Scan1D" and positions != []: self.scan_selector.setPoints(positions) elif scan_type == 'Scan2D' and positions != []: self.scan_selector.setPos(positions[:2]) self.scan_selector.setSize(positions[3:]) @property def viewers_items(self): return self._viewers_items @viewers_items.setter def viewers_items(self, items): self._viewers_items = items self.sources_names = list(items.keys()) self.scan_selector_source = items[self.sources_names[0]]['viewers'][0] self.settings.child('scan_options', 'sources').setOpts(limits=self.sources_names) viewer_names = self._viewers_items[self.sources_names[0]]['names'] self.settings.child('scan_options', 'viewers').setOpts(limits=viewer_names) def show(self, visible=True): self.show_scan_selector(visible) if visible: self.widget.show() else: self.widget.hide() def hide(self): self.show(False) def setupUI(self): self.widget = QtWidgets.QWidget() layout = QtWidgets.QVBoxLayout() self.settings_tree = ParameterTree() layout.addWidget(self.settings_tree, 10) self.settings_tree.setMinimumWidth(300) self.settings = Parameter.create(name='Settings', type='group', children=self.params) self.settings_tree.setParameters(self.settings, showTop=False) self.settings.child('scan_options', 'sources').setOpts(limits=self.sources_names) if len(self.viewers_items): viewer_names = self._viewers_items[self.sources_names[0]]['names'] else: viewer_names = [] self.settings.child('scan_options', 'viewers').setOpts(limits=viewer_names) self.settings.sigTreeStateChanged.connect(self.source_changed) self.widget.setLayout(layout) #self.widget.show() self.widget.setWindowTitle('Scan Selector') def source_changed(self, param, changes): for param, change, data in changes: path = self.settings.childPath(param) if path is not None: childName = '.'.join(path) else: childName = param.name() if change == 'childAdded': pass elif change == 'value': if param.name() == 'sources' and param.value() is not None: viewer_names = self._viewers_items[param.value()]['names'] self.settings.child('scan_options', 'viewers').setOpts(limits=viewer_names) if len(viewer_names) == 1: self.settings.child('scan_options', 'viewers').hide() self.remove_scan_selector() self.scan_selector_source = self._viewers_items[ param.value()]['viewers'][0] self.update_scan_area_type() if param.name() == 'scan_type': if param.value() == 'Scan1D': self.settings.child('scan_area', 'ROIselect').hide() self.settings.child('scan_area', 'coordinates').show() self.remove_scan_selector() self.update_scan_area_type() else: self.settings.child('scan_area', 'ROIselect').show() self.settings.child('scan_area', 'coordinates').hide() self.remove_scan_selector() self.update_scan_area_type() self.scan_selector.sigRegionChangeFinished.emit( self.scan_selector) elif change == 'parent': pass def remove_scan_selector(self): if self.scan_selector_source is not None: try: self.scan_selector_source.image_widget.plotitem.removeItem( self.scan_selector) except: pass pyqtSlot(str) def update_scan_area_type(self): if self.settings.child('scan_options', 'scan_type').value() == 'Scan1D': scan_area_type = 'PolyLines' else: scan_area_type = 'Rect' self.remove_scan_selector() if scan_area_type == 'Rect': self.scan_selector = RectROI([0, 0], [10, 10]) elif scan_area_type == 'PolyLines': self.scan_selector = PolyLineROI_custom([(0, 0), [10, 10]]) if self.scan_selector_source is not None: self.scan_selector.sigRegionChangeFinished.connect( self.update_scan) self.scan_selector_source.image_widget.plotitem.addItem( self.scan_selector) self.show_scan_selector() self.scan_selector.sigRegionChangeFinished.emit(self.scan_selector) def show_scan_selector(self, visible=True): self.scan_selector.setVisible(visible) def update_scan(self, roi): if self.scan_selector_source is not None: if isinstance(roi, RectROI): self.settings.child('scan_area', 'ROIselect', 'x0').setValue(roi.pos().x()) self.settings.child('scan_area', 'ROIselect', 'y0').setValue(roi.pos().y()) self.settings.child('scan_area', 'ROIselect', 'width').setValue(roi.size().x()) self.settings.child('scan_area', 'ROIselect', 'height').setValue(roi.size().y()) elif isinstance(roi, PolyLineROI_custom): self.settings.child('scan_area', 'coordinates').setValue( dict(all_items=[ '({:.03f} , {:.03f})'.format(pt.x(), pt.y()) for pt in roi.get_vertex() ], selected=[])) self.scan_select_signal.emit(roi)
class Ui_WindowModel(QWidget): """ """ def __init__(self,): super().__init__() self.setupUi() def setupUi(self, ): """ """ self.gridLayout_2 = QtWidgets.QGridLayout(self) self.gridLayout_2.setObjectName("gridLayout_2") self.gridGeneral = QtWidgets.QGridLayout() self.gridGeneral.setObjectName("gridGeneral") self.toolBox = QtWidgets.QToolBox(self) self.toolBox.setFrameShadow(QtWidgets.QFrame.Plain) self.toolBox.setObjectName("toolBox") self.model = QtWidgets.QWidget() self.model.setGeometry(QtCore.QRect(0, 0, 558, 451)) self.model.setObjectName("model") self.gridLayout_4 = QtWidgets.QGridLayout(self.model) self.gridLayout_4.setContentsMargins(0, 0, 0, 0) self.gridLayout_4.setObjectName("gridLayout_4") self.gridModel = QtWidgets.QGridLayout() self.gridModel.setContentsMargins(5, 5, 5, 5) self.gridModel.setSpacing(5) self.gridModel.setObjectName("gridModel") self.line = QtWidgets.QFrame(self.model) self.line.setFrameShape(QtWidgets.QFrame.VLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.gridModel.addWidget(self.line, 0, 1, 1, 1) self.openGLWidget = QtWidgets.QOpenGLWidget(self.model) self.openGLWidget.setObjectName("openGLWidget") self.gridModel.addWidget(self.openGLWidget, 0, 2, 1, 1) self.ModelDescriptionTree = ParameterTree(self.model) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.ModelDescriptionTree.sizePolicy().hasHeightForWidth()) self.ModelDescriptionTree.setSizePolicy(sizePolicy) self.ModelDescriptionTree.setObjectName("ModelDescriptionTree") self.gridModel.addWidget(self.ModelDescriptionTree, 0, 0, 1, 1) self.gridLayout_4.addLayout(self.gridModel, 0, 1, 1, 1) self.toolBox.addItem(self.model, "") self.param = QtWidgets.QWidget() self.param.setGeometry(QtCore.QRect(0, 0, 558, 451)) self.param.setObjectName("param") self.gridLayout_6 = QtWidgets.QGridLayout(self.param) self.gridLayout_6.setContentsMargins(0, 0, 0, 0) self.gridLayout_6.setObjectName("gridLayout_6") self.gridParam = QtWidgets.QGridLayout() self.gridParam.setContentsMargins(5, 5, 5, 5) self.gridParam.setSpacing(5) self.gridParam.setObjectName("gridParam") self.ParametersTree = ParameterTree(self.param) self.ParametersTree.setObjectName("ParametersTree") self.gridParam.addWidget(self.ParametersTree, 0, 0, 1, 1) self.gridLayout_6.addLayout(self.gridParam, 0, 0, 1, 1) self.toolBox.addItem(self.param, "") self.result = QtWidgets.QWidget() self.result.setObjectName("result") self.gridLayout_8 = QtWidgets.QGridLayout(self.result) self.gridLayout_8.setContentsMargins(0, 0, 0, 0) self.gridLayout_8.setObjectName("gridLayout_8") self.gridRes = QtWidgets.QGridLayout() self.gridRes.setContentsMargins(5, 5, 5, 5) self.gridRes.setSpacing(5) self.gridRes.setObjectName("gridRes") self.ResTree = ParameterTree(self.result) self.ResTree.setObjectName("ResTree") self.gridRes.addWidget(self.ResTree, 0, 0, 1, 1) self.gridLayout_8.addLayout(self.gridRes, 0, 0, 1, 1) self.toolBox.addItem(self.result, "") self.gridGeneral.addWidget(self.toolBox, 0, 0, 1, 1) self.gridLayout_2.addLayout(self.gridGeneral, 0, 0, 1, 1) self.retranslateUi(self) self.toolBox.setCurrentIndex(2) def retranslateUi(self, WindowModel): _translate = QtCore.QCoreApplication.translate self.toolBox.setItemText(self.toolBox.indexOf(self.model), _translate("WindowModel", "General information about the subjective model")) self.toolBox.setItemText(self.toolBox.indexOf(self.param), _translate("WindowModel", "Detailed description of the parameters")) self.toolBox.setItemText(self.toolBox.indexOf(self.result), _translate("WindowModel", "Detailed description of the resultes "))
class H5Saver(QObject): """QObject containing all methods in order to save datas in a *hdf5 file* with a hierachy compatible with the H5Browser. The saving parameters are contained within a **Parameter** object: self.settings that can be displayed on a UI (see :numref:`other_settings`) using the widget self.settings_tree. At the creation of a new file, a node group named **Raw_datas** and represented by the attribute ``raw_group`` is created and set with a metadata attribute: * 'type' given by the **save_type** class parameter The root group of the file is then set with a few metadata: * 'pymodaq_version' the current pymodaq version, e.g. 1.6.2 * 'file' the file name * 'date' the current date * 'time' the current time All datas will then be saved under this node in various groups See Also -------- H5Browser Parameters ---------- h5_file: pytables hdf5 file object used to save all datas and metadas h5_file_path: str or Path pyqtSignal signal represented by a float. Is emitted each time the hardware reached the target position within the epsilon precision (see comon_parameters variable) save_type: str an element of the list module attribute save_types = ['scan', 'detector', 'custom'] * 'scan' is used for DAQ_Scan module and should be used for similar application * 'detector' is used for DAQ_Viewer module and should be used for similar application * 'custom' should be used for customized applications Attributes ---------- status_sig: pyqtSignal emits a signal of type Threadcommand in order to senf log information to a main UI new_file_sig: pyqtSignal emits a boolean signal to let the program know when the user pressed the new file button on the UI settings: Parameter Parameter instance (pyqtgraph) containing all settings (could be represented using the settings_tree widget) settings_tree: ParameterTree Widget representing as a Tree structure, all the settings defined in the class preamble variable ``params`` """ status_sig = pyqtSignal(utils.ThreadCommand) new_file_sig = pyqtSignal(bool) params = [ { 'title': 'Save type:', 'name': 'save_type', 'type': 'list', 'values': save_types, 'readonly': True }, { 'title': 'Save 2D datas:', 'name': 'save_2D', 'type': 'bool', 'value': True }, { 'title': 'Save raw datas only:', 'name': 'save_raw_only', 'type': 'bool', 'value': True, 'tooltip': 'if True, will not save extracted ROIs used to do live plotting, only raw datas and the scan \ result will be saved' }, { 'title': 'Do Save:', 'name': 'do_save', 'type': 'bool', 'default': False, 'value': False }, { 'title': 'N saved:', 'name': 'N_saved', 'type': 'int', 'default': 0, 'value': 0, 'visible': False }, { 'title': 'custom_name?:', 'name': 'custom_name', 'type': 'bool', 'default': False, 'value': False }, { 'title': 'show file content?:', 'name': 'show_file', 'type': 'bool', 'default': False, 'value': False }, { 'title': 'Base path:', 'name': 'base_path', 'type': 'browsepath', 'value': 'C:\Data', 'filetype': False, 'readonly': True, }, { 'title': 'Base name:', 'name': 'base_name', 'type': 'str', 'value': 'Scan', 'readonly': True }, { 'title': 'Current scan:', 'name': 'current_scan_name', 'type': 'str', 'value': '', 'readonly': True }, { 'title': 'Current path:', 'name': 'current_scan_path', 'type': 'text', 'value': 'C:\Data', 'readonly': True, 'visible': False }, { 'title': 'h5file:', 'name': 'current_h5_file', 'type': 'text_pb', 'value': '', 'readonly': True }, { 'title': 'Compression options:', 'name': 'compression_options', 'type': 'group', 'children': [ { 'title': 'Compression library:', 'name': 'h5comp_library', 'type': 'list', 'value': 'zlib', 'values': ['zlib', 'lzo', 'bzip2', 'blosc'] }, { 'title': 'Compression level:', 'name': 'h5comp_level', 'type': 'int', 'value': 5, 'min': 0, 'max': 9 }, ] }, ] def __init__(self, h5_file_path=None, h5_file=None, save_type='scan'): """Initialize the H5Saver object Creates the ``setting`` and ``settings_tree`` object """ super(H5Saver, self).__init__() if save_type not in save_types: raise Exception('Invalid saving type') self.h5_file = h5_file self.h5_file_path = h5_file_path self.h5_file_name = None self.logger_array = None self.current_group = None self.current_scan_group = None self.current_scan_name = None self.raw_group = None self.settings = Parameter.create(title='Saving settings', name='save_settings', type='group', children=self.params) self.settings_tree = ParameterTree() self.settings_tree.setMinimumHeight(310) self.settings_tree.setParameters(self.settings, showTop=False) self.settings.child( ('current_h5_file' )).sigActivated.connect(lambda: self.emit_new_file(True)) self.settings.child(('save_type')).setValue(save_type) self.filters = tables.Filters( complevel=self.settings.child('compression_options', 'h5comp_level').value(), complib=self.settings.child('compression_options', 'h5comp_library').value()) # self.settings.child('saving_options', 'save_independent').show(save_type == 'scan') # self.settings.child('saving_options', 'do_save').show(not save_type == 'scan') # self.settings.child('saving_options', 'current_scan_name').show(save_type == 'scan') self.settings.sigTreeStateChanged.connect( self.parameter_tree_changed ) # any changes on the settings will update accordingly the detector def emit_new_file(self, status): """Emits the new_file_sig Parameters ---------- status: bool emits True if a new file has been asked by the user pressing the new file button on the UI """ self.new_file_sig.emit(status) def init_file(self, update_h5=False, custom_naming=False, addhoc_file_path=None): """Initializes a new h5 file. Could set the h5_file attributes as: * a file with a name following a template if ``custom_naming`` is ``False`` and ``addhoc_file_path`` is ``None`` * a file within a name set using a file dialog popup if ``custom_naming`` is ``True`` * a file with a custom name if ``addhoc_file_path`` is a ``Path`` object or a path string Parameters ---------- update_h5: bool create a new h5 file with name specified by other parameters if false try to open an existing file and will append new data to it custom_naming: bool if True, a selection file dialog opens to set a new file name addhoc_file_path: Path or str supplied name by the user for the new file Returns ------- update_h5: bool True if new file has been created, False otherwise """ date = datetime.datetime.now() if addhoc_file_path is None: if not os.path.isdir(self.settings.child(('base_path')).value()): os.mkdir(self.settings.child(('base_path')).value()) # set the filename and path base_name = self.settings.child(('base_name')).value() if not custom_naming: custom_naming = self.settings.child(('custom_name')).value() if not custom_naming: scan_type = self.settings.child( ('save_type')).value() == 'scan' scan_path, current_scan_name, save_path = self.update_file_paths( update_h5) self.current_scan_name = current_scan_name self.settings.child( ('current_scan_name')).setValue(current_scan_name) self.settings.child( ('current_scan_path')).setValue(str(scan_path)) if not scan_type: self.h5_file_path = save_path #will remove the dataset part used for DAQ_scan datas self.h5_file_name = base_name + date.strftime( '_%Y%m%d_%H_%M_%S.h5') else: self.h5_file_path = save_path self.h5_file_name = save_path.name + ".h5" else: self.h5_file_name = utils.select_file(start_path=base_name, save=True, ext='h5') self.h5_file_path = self.h5_file_name.parent else: if isinstance(addhoc_file_path, str): addhoc_file_path = Path(addhoc_file_path) self.h5_file_path = addhoc_file_path.parent self.h5_file_name = addhoc_file_path.name fullpathname = str(self.h5_file_path.joinpath(self.h5_file_name)) self.settings.child(('current_h5_file')).setValue(fullpathname) if update_h5: self.current_scan_group = None scan_group = None if self.current_scan_group is not None: scan_group = self.current_scan_group._v_name if update_h5: self.close_file() self.h5_file = tables.open_file(fullpathname, 'w', title='PyMoDAQ file') self.h5_file.root._v_attrs['pymodaq_version'] = get_version() else: self.close_file() self.h5_file = tables.open_file(fullpathname, 'a', title='PyMoDAQ file') self.raw_group = self.get_set_group(self.h5_file.root, 'Raw_datas', title='Data from PyMoDAQ modules') self.get_set_logger(self.raw_group) if scan_group is not None: self.current_scan_group = self.get_set_group( self.raw_group, scan_group) else: self.current_scan_group = self.get_last_scan() self.raw_group._v_attrs['type'] = self.settings.child( ('save_type')).value() self.h5_file.root._v_attrs['file'] = date.strftime(self.h5_file_name) if update_h5: self.h5_file.root._v_attrs['date'] = date.strftime('%Y%m%d') self.h5_file.root._v_attrs['time'] = date.strftime('%H:%M:%S') return update_h5 def update_file_paths(self, update_h5=False): """Apply the template depending on the 'save_type' settings child Parameters ---------- update_h5: bool if True, will increment the file name and eventually the current scan index if False, get the current scan index in the h5 file Returns ------- scan_path: Path current_filename: str dataset_path: Path See Also -------- :py:meth:`pymodaq.daq_utils.daq_utils.set_current_scan_path` """ try: # set the filename and path base_path = self.settings.child(('base_path')).value() base_name = self.settings.child(('base_name')).value() current_scan = self.settings.child(('current_scan_name')).value() scan_type = self.settings.child(('save_type')).value() == 'scan' if current_scan == '' or update_h5: next_scan_index = 0 update_h5 = True #just started the main program so one should create a new h5 else: next_scan_index = self.get_scan_index() scan_path, current_filename, dataset_path = utils.set_current_scan_path( base_path, base_name, update_h5, next_scan_index, create_dataset_folder=scan_type) self.settings.child(('current_scan_path')).setValue(str(scan_path)) return scan_path, current_filename, dataset_path except Exception as e: print(e) def get_last_scan(self): """Gets the last scan node within the h5_file and under the the **raw_group** Returns ------- scan_group: pytables group or None """ groups = [ group for group in list(self.raw_group._v_groups) if 'Scan' in group ] groups.sort() if len(groups) != 0: scan_group = self.h5_file.get_node(self.raw_group, groups[-1]) else: scan_group = None return scan_group def get_scan_index(self): """ return the scan group index in the "scan templating": Scan000, Scan001 as an integer """ try: if self.current_scan_group is None: return 0 else: groups = [ group for group in list(self.raw_group._v_groups) if 'Scan' in group ] groups.sort() flag = False for child in list( self.h5_file.get_node(self.raw_group, groups[-1])._v_groups): if 'scan' in child: return len(groups) return 0 except Exception as e: return 0 def load_file(self, base_path=None, file_path=None): """Opens a file dialog to select a h5file saved on disk to be used Parameters ---------- base_path file_path See Also -------- :py:meth:`init_file` :py:meth:`pymodaq.daq_utils.daq_utils.select_file` """ if base_path is None: base_path = self.settings.child('base_path').value() if not os.path.isdir(base_path): base_path = None if file_path is None: file_path = utils.select_file(base_path, save=False, ext='h5') if not isinstance(file_path, Path): file_path = Path(file_path) if 'h5' not in file_path.suffix: raise IOError('Invalid file type, should be a h5 file') self.init_file(addhoc_file_path=file_path) def close_file(self): """Flush data and close the h5file """ try: if self.h5_file is not None: self.h5_file.flush() if self.h5_file.isopen: self.h5_file.close() except Exception as e: print(e) #no big deal def is_node_in_group(self, where, name): """ Check if a given node with name is in the group defined by where (comparison on lower case strings) Parameters ---------- where: (str or node) path or parent node instance name: (str) group node name Returns ------- bool True if node exists, False otherwise """ nodes_names = [ node._v_name.lower() for node in self.h5_file.list_nodes(where) ] return name.lower() in nodes_names def get_set_logger(self, where): """ Retrieve or create (if absent) a logger enlargeable array to store logs Get attributed to the class attribute ``logger_array`` Parameters ---------- where: node location within the tree where to save or retrieve the array Returns ------- logger_array: vlarray enlargeable array accepting strings as elements """ logger = 'Logger' if not logger in list(self.h5_file.get_node(where)._v_children.keys()): # check if logger node exist text_atom = tables.atom.ObjectAtom() self.logger_array = self.h5_file.create_vlarray(where, logger, atom=text_atom) self.logger_array._v_attrs['type'] = 'log' else: self.logger_array = self.h5_file.get_node(where, name=logger) return self.logger_array def get_set_group(self, where, name, title=''): """Retrieve or create (if absent) a node group Get attributed to the class attribute ``current_group`` Parameters ---------- where: str or node path or parent node instance name: str group node name title: str node title Returns ------- group: group node """ if not name in list(self.h5_file.get_node(where)._v_children.keys()): self.current_group = self.h5_file.create_group(where, name, title) else: self.current_group = self.h5_file.get_node(where, name) return self.current_group def add_data_group(self, where, group_data_type, title='', settings_as_xml='', metadata=dict([])): """Creates a group node at given location in the tree Parameters ---------- where: group node where to create data group group_data_type: list of str either ['data0D', 'data1D', 'data2D'] title: str, optional a title for this node, will be saved as metadata settings_as_xml: str, optional XML string created from a Parameter object to be saved as metadata metadata: dict, optional will be saved as a new metadata attribute with name: key and value: dict value Returns ------- group: group node See Also -------- :py:meth:`àdd_group` """ if group_data_type not in group_data_types: raise Exception('Invalid data group type') group = self.add_group(group_data_type, '', where, title, settings_as_xml, metadata) return group def add_navigation_axis(self, data, parent_group, axis='x_axis', enlargeable=False, title='', metadata=dict([])): """ Create carray for navigation axis within a scan Parameters ---------- data: (ndarray) of dimension 1 parent_group: (str or node) parent node where to save new data axis: (str) either x_axis or y_axis """ if axis not in ['x_axis', 'y_axis', 'z_axis']: raise Exception('Invalid navigation axis name') array = self.add_array(parent_group, 'scan_{:s}'.format(axis), 'navigation_axis', data_shape=data.shape, data_dimension='1D', array_to_save=data, enlargeable=enlargeable, title=title, metadata=metadata) return array def add_data_live_scan(self, channel_group, data_dict, scan_type='scan1D', title=''): shape, dimension, size = utils.get_data_dimension( data_dict['data'], scan_type=scan_type, remove_scan_dimension=True) data_array = self.add_array(channel_group, 'Data', 'data', array_type=np.float, title=title, data_shape=shape, data_dimension=dimension, scan_type=scan_type, array_to_save=data_dict['data']) if 'x_axis' in data_dict: if not isinstance(data_dict['x_axis'], dict): array_to_save = data_dict['x_axis'] tmp_dict = dict(label='', units='') else: tmp_dict = copy.deepcopy(data_dict['x_axis']) array_to_save = tmp_dict.pop('data') if 'x_axis' in data_dict: array = self.add_array(channel_group, 'x_axis', 'axis', array_type=np.float, array_to_save=array_to_save, enlargeable=False, data_dimension='1D', metadata=tmp_dict) if 'y_axis' in data_dict: if not isinstance(data_dict['y_axis'], dict): array_to_save = data_dict['y_axis'] tmp_dict = dict(label='', units='') else: tmp_dict = copy.deepcopy(data_dict['y_axis']) array_to_save = tmp_dict.pop('data') if 'y_axis' in data_dict: array = self.add_array(channel_group, 'y_axis', 'axis', array_type=np.float, array_to_save=array_to_save, enlargeable=False, data_dimension='1D', metadata=tmp_dict) return data_array def add_data(self, channel_group, data_dict, scan_type='scan1D', scan_shape=[], title='', enlargeable=False, init=False, add_scan_dim=False): shape, dimension, size = utils.get_data_dimension(data_dict['data']) data_array = self.add_array(channel_group, 'Data', 'data', array_type=np.float, title=title, data_shape=shape, enlargeable=enlargeable, data_dimension=dimension, scan_type=scan_type, scan_shape=scan_shape, array_to_save=data_dict['data'], init=init, add_scan_dim=add_scan_dim) if 'x_axis' in data_dict: if not isinstance(data_dict['x_axis'], dict): array_to_save = data_dict['x_axis'] tmp_dict = dict(label='', units='') else: tmp_dict = copy.deepcopy(data_dict['x_axis']) array_to_save = tmp_dict.pop('data') array = self.add_array(channel_group, 'x_axis', 'axis', array_type=np.float, array_to_save=array_to_save, enlargeable=False, data_dimension='1D', metadata=tmp_dict) if 'y_axis' in data_dict: if not isinstance(data_dict['y_axis'], dict): array_to_save = data_dict['y_axis'] tmp_dict = dict(label='', units='') else: tmp_dict = copy.deepcopy(data_dict['y_axis']) array_to_save = tmp_dict.pop('data') array = self.add_array(channel_group, 'y_axis', 'axis', array_type=np.float, array_to_save=array_to_save, enlargeable=False, data_dimension='1D', metadata=tmp_dict) self.h5_file.flush() return data_array def add_array(self, where, name, data_type, data_shape=(1, ), data_dimension='0D', scan_type='', scan_shape=[], title='', array_to_save=None, array_type=np.float, enlargeable=False, metadata=dict([]), init=False, add_scan_dim=False): if data_dimension not in data_dimensions: raise Exception('Invalid data dimension') if data_type not in data_types: raise Exception('Invalid data type') if scan_type != '': scan_type = utils.uncapitalize(scan_type) if scan_type not in scan_types: raise Exception('Invalid scan type') if enlargeable: shape = [0] if data_shape != (1, ): shape.extend(data_shape) shape = tuple(shape) array = self.h5_file.create_earray(where, utils.capitalize(name), tables.Atom.from_dtype( np.dtype(array_type)), shape=shape, title=title, filters=self.filters) array._v_attrs['shape'] = shape else: if add_scan_dim: #means it is an array initialization to zero shape = scan_shape[:] shape.extend(data_shape) if init or array_to_save is None: array_to_save = np.zeros(shape) array = self.h5_file.create_carray(where, utils.capitalize(name), obj=array_to_save, title=title, filters=self.filters) array._v_attrs['shape'] = array_to_save.shape array._v_attrs['type'] = data_type array._v_attrs['data_dimension'] = data_dimension array._v_attrs['scan_type'] = scan_type for metadat in metadata: array._v_attrs[metadat] = metadata[metadat] return array def append(self, array, data): if not (isinstance(array, tables.vlarray.VLArray) or isinstance(array, tables.earray.EArray)): raise Exception('This array cannot be appended') if isinstance(data, np.ndarray): if data.shape != (1, ): shape = [1] shape.extend(data.shape) array.append(data.reshape(shape)) else: array.append(data) else: array.append(data) sh = list(array._v_attrs['shape']) sh[0] += 1 array._v_attrs['shape'] = tuple(sh) def add_group(self, group_name, group_type, where, title='', settings_as_xml='', metadata=dict([])): """ Add a node in the h5 file tree of the group type Parameters ---------- group_name: (str) a custom name for this group group_type: (str) one of the possible values of **group_types** where: (str or node) parent node where to create the new group settings_as_xml: (str) XML string containing Parameters representation (see custom_Tree) metadata: (dict) extra metadata to be saved with this new group node Returns ------- (node): newly created group node """ if group_type not in group_types: raise Exception('Invalid group type') try: node = self.h5_file.get_node(where, utils.capitalize(group_name)) except tables.NoSuchNodeError as e: node = None if node is None: node = self.get_set_group(where, utils.capitalize(group_name), title) node._v_attrs['settings'] = settings_as_xml node._v_attrs['type'] = group_type.lower() for metadat in metadata: node._v_attrs[metadat] = metadata[metadat] return node def add_incremental_group(self, group_type, where, title='', settings_as_xml='', metadata=dict([])): """ Add a node in the h5 file tree of the group type with an increment in the given name Parameters ---------- group_type: (str) one of the possible values of **group_types** where: (str or node) parent node where to create the new group settings_as_xml: (str) XML string containing Parameters representation (see custom_Tree) metadata: (dict) extra metadata to be saved with this new group node Returns ------- (node): newly created group node """ if group_type not in group_types: raise Exception('Invalid group type') nodes = list(self.h5_file.get_node(where)._v_children.keys()) nodes_tmp = [] for node in nodes: if utils.capitalize(group_type) in node: nodes_tmp.append(node) nodes_tmp.sort() if len(nodes_tmp) == 0: ind_group = -1 else: ind_group = int(nodes_tmp[-1][-3:]) group = self.get_set_group( where, utils.capitalize(group_type) + '{:03d}'.format(ind_group + 1), title) group._v_attrs['settings'] = settings_as_xml if group_type.lower() != 'ch': group._v_attrs['type'] = group_type.lower() else: group._v_attrs['type'] = '' for metadat in metadata: group._v_attrs[metadat] = metadata[metadat] return group def add_det_group(self, where, title='', settings_as_xml='', metadata=dict([])): """ Add a new group of type detector See Also ------- add_incremental_group """ group = self.add_incremental_group('detector', where, title, settings_as_xml, metadata) return group def add_CH_group(self, where, title='', settings_as_xml='', metadata=dict([])): """ Add a new group of type channel See Also ------- add_incremental_group """ group = self.add_incremental_group('ch', where, title, settings_as_xml, metadata) return group def add_live_scan_group(self, where, dimensionality, title='', settings_as_xml='', metadata=dict([])): """ Add a new group of type live scan See Also ------- add_incremental_group """ group = self.add_group('Live_scan_{:s}'.format(dimensionality), '', where, title=title, settings_as_xml=settings_as_xml, metadata=metadata) return group def add_scan_group(self, title='', settings_as_xml='', metadata=dict([])): """ Add a new group of type scan See Also ------- add_incremental_group """ if self.current_scan_group is not None: if list(self.current_scan_group._v_children) == []: new_scan = False else: new_scan = True else: new_scan = True if new_scan: self.current_scan_group = self.add_incremental_group( 'scan', self.raw_group, title, settings_as_xml, metadata) self.current_scan_group._v_attrs['description'] = '' self.settings.child(('current_scan_name')).setValue( self.current_scan_group._v_name) return self.current_scan_group def add_move_group(self, where, title='', settings_as_xml='', metadata=dict([])): """ Add a new group of type move See Also ------- add_incremental_group """ group = self.add_incremental_group('move', where, title, settings_as_xml, metadata) return group def parameter_tree_changed(self, param, changes): for param, change, data in changes: path = self.settings.childPath(param) if change == 'childAdded': pass elif change == 'value': if param.name() == 'show_file': param.setValue(False) self.show_file_content() elif param.name() == 'base_path': try: if not os.path.isdir(param.value()): os.mkdir(param.value()) except: self.update_status( "The base path couldn't be set, please check your options" ) elif param.name() in custom_tree.iter_children( self.settings.child(('compression_options')), []): self.filters = tables.Filters( complevel=self.settings.child('compression_options', 'h5comp_level').value(), complib=self.settings.child('compression_options', 'h5comp_library').value()) elif change == 'parent': pass def update_status(self, status): self.status_sig.emit( utils.ThreadCommand("Update_Status", [status, 'log'])) def show_file_content(self): form = QtWidgets.QWidget() if not self.h5_file.isopen: if self.h5_file_path.exists(): self.analysis_prog = H5Browser(form, h5file=self.h5_file_path) else: raise FileExistsError('no File presents') else: self.analysis_prog = H5Browser(form, h5file=self.h5_file) form.show()
def __init__(self, *args, **kwargs): super(DefocusParameterTree, self).__init__(*args, **kwargs) self.setLayout(QVBoxLayout()) self.parameter_tree = ParameterTree() self.layout().addWidget(self.parameter_tree) self.layout().setContentsMargins(0, 0, 0, 0)
self.addChild({'name': 'other information', 'type': 'text', 'value': 'Some text...'}) self.addChild({'name': 'save', 'type': 'action'}) ############################################################################## ############################################################################## ## Start Qt event loop unless running in interactive mode or using pyside. if __name__ == '__main__': ## Create tree of Parameter objects params = [Input(name='Input'), Generator(name='Generator'), AllPlotScalableGroup(name='Graph')] p = Parameter.create(name='params', type='group', children=params) ## Create two ParameterTree widgets, both accessing the same data t = ParameterTree() t.setParameters(p, showTop=False) t.setWindowTitle('pyqtgraph example: Parameter Tree') win = QtGui.QWidget() layout = QtGui.QGridLayout() win.setLayout(layout) layout.addWidget(t, 1, 0, 1, 1) win.show() win.resize(800,800) import sys if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): QtGui.QApplication.instance().exec_() ##############################################################################
class BuildGui(): def __init__(self, tree): """ Test fixture """ self.basename = '/Users/pbmanis/Documents/data/MRK_Pyramidal' self.filename = None self.tree = tree print('tree: ', tree) self.mainwin = pg.Qt.QtGui.QMainWindow() self.win = pg.Qt.QtGui.QWidget() self.main_layout = pg.Qt.QtGui.QGridLayout() # top level layout for the window self.win.setLayout(self.main_layout) self.mainwin.setCentralWidget(self.win) self.mainwin.show() self.mainwin.setWindowTitle('Data Selection') self.mainwin.setGeometry( 100 , 100 , 1400 , 900) # build buttons at top of controls self.current_DSC = list(self.tree.keys())[0] self.btn_read = pg.Qt.QtGui.QPushButton("Read") self.btn_find = pg.Qt.QtGui.QPushButton('Find and Read') # use a nested grid layout for the buttons button_layout = pg.Qt.QtGui.QGridLayout() button_layout.addWidget(self.btn_read, 1, 0, 1, 1) # button_layout.addWidget(self.btn_analyze, 0, 1, 1, 1) button_layout.addWidget(self.btn_find, 0, 0, 1, 1) # build parametertree in left column # ptreewidth = 320 self.main_layout.setColumnMinimumWidth(0, ptreewidth) # analysis # empty in test rig params = [ {'name': 'Analysis', 'type': 'group', 'children': [], }] self.analysis_ptree = ParameterTree() self.analysis_ptreedata = Parameter.create(name='params', type='group', children=params) self.analysis_ptree.setParameters(self.analysis_ptreedata) self.ptree = ParameterTree() self.ptreedata = Parameter.create(name='dataset', type='group', children=self.setParams(0)) self.ptree.setParameters(self.ptreedata) # add the table with granularity of "cells" self.prottree = ParameterTree() self.setProtocols() # add the protocols # use a grid layout to hold the trees self.ptree_widget = pg.Qt.QtGui.QWidget() self.ptree_layout = pg.Qt.QtGui.QGridLayout() self.ptree_widget.setLayout(self.ptree_layout) self.ptree_layout.setSpacing(2) # ptree in row 1 col 0, 4 rows, 2 cols self.ptree_layout.addWidget(self.analysis_ptree) self.ptree_layout.addWidget(self.ptree) # Parameter Tree on left self.ptree_layout.addWidget(self.prottree) # protocol tree just below # self.ptree_layout.setColumnStretch(0, 5) self.ptree_layout.setRowStretch(0, 5) self.ptree_layout.setRowStretch(1, 1) self.ptree_layout.setRowStretch(2, 1) # build plot window self.plots_widget = pg.Qt.QtGui.QWidget() self.plots_layout = pg.Qt.QtGui.QGridLayout() self.plots_widget.setLayout(self.plots_layout) self.plots_layout.setContentsMargins(4, 4, 4, 4) self.plots_layout.setSpacing(2) self.plots = {} for panel in zip(['Wave', 'Average', 'PSTH'], [0, 14, 18], [1, 5, 5],): self.plots[panel[0]] = pg.PlotWidget() self.plots_layout.addWidget(self.plots[panel[0]], panel[1], 0, panel[2], 1) self.plots[panel[0]].getAxis('left').setLabel('V', color="#ff0000") self.plots[panel[0]].setTitle(panel[0], color="#ff0000") self.plots[panel[0]].getAxis('bottom').setLabel('t (sec)', color="#ff0000") self.main_layout.addWidget(self.plots_widget, 0, 2, 22, 1) self.main_layout.addLayout(button_layout, 0, 0, 1, 2) self.main_layout.addWidget(self.ptree_widget, 1, 0, -1, 2) self.retrieveAllParameters() # connect buttons and ptrees to actions self.ptreedata.sigTreeStateChanged.connect(self.update_DSC) self.prottreedata.sigTreeStateChanged.connect(self.get_current) self.btn_read.clicked.connect(self.read_run) # self.btn_analyze.clicked.connect(self.analyze) self.btn_find.clicked.connect(self.find_run) # print( self.MParams) def retrieveAllParameters(self): pass def read_run(self): pass def find_run(self): pass def setParams(self, isel): self.params = [ {'name': 'Day', 'type': 'group', 'children': [{'name': 'Slices/Cells', 'type': 'list', 'values': list(self.tree.keys()), 'value': list(self.tree.keys())[isel]}] } ] return self.params def setProtocols(self): """ Update the prototocls to correspond to the current parameters, top protocol selected """ if self.tree == None: raise ValueError('setProtocols: Must set up read data before setting up protocols') self.protocols = [ {'name': 'Protos', 'type': 'group', 'children': [{'name': 'Protocols', 'type': 'list', 'values': self.tree[self.current_DSC][:], 'value': self.tree[self.current_DSC][0]}] } ] self.prottreedata = Parameter.create(name='protocol', type='group', children=self.protocols) self.prottree.setParameters(self.prottreedata) self.current_protocol = self.tree[self.current_DSC][0] self.prottreedata.sigTreeStateChanged.connect(self.get_current) return self.protocols def get_current(self, param, changes): for param, change, data in changes: # path = self.prottreedata.childPath(param) # if path is not None: # childName = '.'.join(path) # else: # childName = param.name() self.current_protocol = data def update_DSC(self, param, changes): for param, change, data in changes: # path = self.ptreedata.childPath(param) # if path is not None: # childName = '.'.join(path) # else: # childName = param.name() self.current_DSC = data self.setProtocols()
def __init__(self, tree): """ Test fixture """ self.basename = '/Users/pbmanis/Documents/data/MRK_Pyramidal' self.filename = None self.tree = tree print('tree: ', tree) self.mainwin = pg.Qt.QtGui.QMainWindow() self.win = pg.Qt.QtGui.QWidget() self.main_layout = pg.Qt.QtGui.QGridLayout() # top level layout for the window self.win.setLayout(self.main_layout) self.mainwin.setCentralWidget(self.win) self.mainwin.show() self.mainwin.setWindowTitle('Data Selection') self.mainwin.setGeometry( 100 , 100 , 1400 , 900) # build buttons at top of controls self.current_DSC = list(self.tree.keys())[0] self.btn_read = pg.Qt.QtGui.QPushButton("Read") self.btn_find = pg.Qt.QtGui.QPushButton('Find and Read') # use a nested grid layout for the buttons button_layout = pg.Qt.QtGui.QGridLayout() button_layout.addWidget(self.btn_read, 1, 0, 1, 1) # button_layout.addWidget(self.btn_analyze, 0, 1, 1, 1) button_layout.addWidget(self.btn_find, 0, 0, 1, 1) # build parametertree in left column # ptreewidth = 320 self.main_layout.setColumnMinimumWidth(0, ptreewidth) # analysis # empty in test rig params = [ {'name': 'Analysis', 'type': 'group', 'children': [], }] self.analysis_ptree = ParameterTree() self.analysis_ptreedata = Parameter.create(name='params', type='group', children=params) self.analysis_ptree.setParameters(self.analysis_ptreedata) self.ptree = ParameterTree() self.ptreedata = Parameter.create(name='dataset', type='group', children=self.setParams(0)) self.ptree.setParameters(self.ptreedata) # add the table with granularity of "cells" self.prottree = ParameterTree() self.setProtocols() # add the protocols # use a grid layout to hold the trees self.ptree_widget = pg.Qt.QtGui.QWidget() self.ptree_layout = pg.Qt.QtGui.QGridLayout() self.ptree_widget.setLayout(self.ptree_layout) self.ptree_layout.setSpacing(2) # ptree in row 1 col 0, 4 rows, 2 cols self.ptree_layout.addWidget(self.analysis_ptree) self.ptree_layout.addWidget(self.ptree) # Parameter Tree on left self.ptree_layout.addWidget(self.prottree) # protocol tree just below # self.ptree_layout.setColumnStretch(0, 5) self.ptree_layout.setRowStretch(0, 5) self.ptree_layout.setRowStretch(1, 1) self.ptree_layout.setRowStretch(2, 1) # build plot window self.plots_widget = pg.Qt.QtGui.QWidget() self.plots_layout = pg.Qt.QtGui.QGridLayout() self.plots_widget.setLayout(self.plots_layout) self.plots_layout.setContentsMargins(4, 4, 4, 4) self.plots_layout.setSpacing(2) self.plots = {} for panel in zip(['Wave', 'Average', 'PSTH'], [0, 14, 18], [1, 5, 5],): self.plots[panel[0]] = pg.PlotWidget() self.plots_layout.addWidget(self.plots[panel[0]], panel[1], 0, panel[2], 1) self.plots[panel[0]].getAxis('left').setLabel('V', color="#ff0000") self.plots[panel[0]].setTitle(panel[0], color="#ff0000") self.plots[panel[0]].getAxis('bottom').setLabel('t (sec)', color="#ff0000") self.main_layout.addWidget(self.plots_widget, 0, 2, 22, 1) self.main_layout.addLayout(button_layout, 0, 0, 1, 2) self.main_layout.addWidget(self.ptree_widget, 1, 0, -1, 2) self.retrieveAllParameters() # connect buttons and ptrees to actions self.ptreedata.sigTreeStateChanged.connect(self.update_DSC) self.prottreedata.sigTreeStateChanged.connect(self.get_current) self.btn_read.clicked.connect(self.read_run) # self.btn_analyze.clicked.connect(self.analyze) self.btn_find.clicked.connect(self.find_run)
class CrystalIndexing(object): def __init__(self, parent = None): self.parent = parent ## Dock: Indexing self.dock = Dock("Indexing", size=(1, 1)) self.win = ParameterTree() self.win.setWindowTitle('Indexing') self.dock.addWidget(self.win) self.winL = pg.LayoutWidget() self.launchIndexBtn = QtGui.QPushButton('Launch indexing') self.winL.addWidget(self.launchIndexBtn, row=0, col=0) self.synchBtn = QtGui.QPushButton('Deploy CrystFEL geometry') self.winL.addWidget(self.synchBtn, row=1, col=0) self.dock.addWidget(self.winL) self.index_grp = 'Crystal indexing' self.index_on_str = 'Indexing on' self.index_geom_str = 'CrystFEL geometry' self.index_peakMethod_str = 'Peak method' self.index_intRadius_str = 'Integration radii' self.index_pdb_str = 'Unitcell' self.index_method_str = 'Indexing method' self.index_tolerance_str = 'Tolerance' self.index_extra_str = 'Extra CrystFEL parameters' self.index_condition_str = 'Index condition' self.launch_grp = 'Batch' self.outDir_str = 'Output directory' self.runs_str = 'Runs(s)' self.sample_str = 'Sample name' self.tag_str = 'Tag' self.queue_str = 'Queue' self.chunkSize_str = 'Chunk size' self.cpu_str = 'CPUs' self.keepData_str = 'Keep CXI images' self.noe_str = 'Number of events to process' (self.psanaq_str,self.psnehq_str,self.psfehq_str,self.psnehprioq_str,self.psfehprioq_str,self.psnehhiprioq_str,self.psfehhiprioq_str,self.psdebugq_str) = \ ('psanaq','psnehq','psfehq','psnehprioq','psfehprioq','psnehhiprioq','psfehhiprioq','psdebugq') self.noQueue_str = 'N/A' self.outDir = self.parent.psocakeDir self.outDir_overridden = False self.runs = '' self.sample = 'crystal' self.tag = '' self.queue = self.psanaq_str self.chunkSize = 500 self.cpu = 12 self.noe = -1 # Indexing if self.parent.facility == self.parent.facilityLCLS: self.showIndexedPeaks = False self.indexedPeaks = None self.hiddenCXI = '.temp.cxi' self.hiddenCrystfelStream = '.temp.stream' self.hiddenCrystfelList = '.temp.lst' self.indexingOn = False self.numIndexedPeaksFound = 0 self.geom = '.temp.geom' self.peakMethod = 'cxi' self.intRadius = '3,4,5' self.pdb = '' self.indexingMethod = 'mosflm,dirax' self.tolerance = '5,5,5,1.5' self.extra = '' self.condition = '' self.keepData = True elif self.parent.facility == self.parent.facilityPAL: self.showIndexedPeaks = False self.indexedPeaks = None self.hiddenCXI = '.temp.cxi' self.hiddenCrystfelStream = '.temp.stream' self.hiddenCrystfelList = '.temp.lst' self.indexingOn = False self.numIndexedPeaksFound = 0 self.geom = '.temp.geom' self.peakMethod = 'cxi' self.intRadius = '4,5,6' self.pdb = '' self.indexingMethod = 'mosflm,dirax' self.tolerance = '5,5,5,1.5' self.extra = '' self.condition = '' self.keepData = True ####################### # Mandatory parameter # ####################### if self.parent.facility == self.parent.facilityLCLS: self.params = [ {'name': self.index_grp, 'type': 'group', 'children': [ {'name': self.index_on_str, 'type': 'bool', 'value': self.indexingOn, 'tip': "Turn on indexing"}, {'name': self.index_geom_str, 'type': 'str', 'value': self.geom, 'tip': "CrystFEL geometry file"}, #{'name': self.index_peakMethod_str, 'type': 'str', 'value': self.peakMethod, 'tip': "Turn on indexing"}, {'name': self.index_intRadius_str, 'type': 'str', 'value': self.intRadius, 'tip': "Integration radii"}, {'name': self.index_pdb_str, 'type': 'str', 'value': self.pdb, 'tip': "(Optional) CrystFEL unitcell file"}, {'name': self.index_method_str, 'type': 'str', 'value': self.indexingMethod, 'tip': "comma separated indexing methods"}, {'name': self.index_tolerance_str, 'type': 'str', 'value': self.tolerance, 'tip': "Indexing tolerance, default: 5,5,5,1.5"}, {'name': self.index_extra_str, 'type': 'str', 'value': self.extra, 'tip': "Other indexing parameters, comma separated (e.g. --multi,--no-check-peaks)"}, {'name': self.index_condition_str, 'type': 'str', 'value': self.condition, 'tip': "indexing condition e.g. 41 in #evr1# and #eventNumber# > 3"}, ]}, {'name': self.launch_grp, 'type': 'group', 'children': [ {'name': self.outDir_str, 'type': 'str', 'value': self.outDir}, {'name': self.runs_str, 'type': 'str', 'value': self.runs, 'tip': "comma separated or use colon for a range, e.g. 1,3,5:7 = runs 1,3,5,6,7"}, {'name': self.sample_str, 'type': 'str', 'value': self.sample, 'tip': "name of the sample saved in the cxidb file, e.g. lysozyme"}, {'name': self.tag_str, 'type': 'str', 'value': self.tag, 'tip': "attach tag to stream, e.g. cxitut13_0010_tag.stream"}, {'name': self.queue_str, 'type': 'list', 'values': {self.psfehhiprioq_str: self.psfehhiprioq_str, self.psnehhiprioq_str: self.psnehhiprioq_str, self.psfehprioq_str: self.psfehprioq_str, self.psnehprioq_str: self.psnehprioq_str, self.psfehq_str: self.psfehq_str, self.psnehq_str: self.psnehq_str, self.psanaq_str: self.psanaq_str, self.psdebugq_str: self.psdebugq_str}, 'value': self.queue, 'tip': "Choose queue"}, {'name': self.chunkSize_str, 'type': 'int', 'value': self.chunkSize, 'tip': "number of patterns to process per worker"}, {'name': self.keepData_str, 'type': 'bool', 'value': self.keepData, 'tip': "Do not delete cxidb images in cxi file"}, ]}, ] elif self.parent.facility == self.parent.facilityPAL: self.params = [ {'name': self.index_grp, 'type': 'group', 'children': [ {'name': self.index_on_str, 'type': 'bool', 'value': self.indexingOn, 'tip': "Turn on indexing"}, {'name': self.index_geom_str, 'type': 'str', 'value': self.geom, 'tip': "CrystFEL geometry file"}, {'name': self.index_intRadius_str, 'type': 'str', 'value': self.intRadius, 'tip': "Integration radii"}, {'name': self.index_pdb_str, 'type': 'str', 'value': self.pdb, 'tip': "(Optional) CrystFEL unitcell file"}, {'name': self.index_method_str, 'type': 'str', 'value': self.indexingMethod, 'tip': "comma separated indexing methods"}, {'name': self.index_tolerance_str, 'type': 'str', 'value': self.tolerance, 'tip': "Indexing tolerance, default: 5,5,5,1.5"}, {'name': self.index_extra_str, 'type': 'str', 'value': self.extra, 'tip': "Other CrystFEL indexing parameters"}, ]}, {'name': self.launch_grp, 'type': 'group', 'children': [ {'name': self.outDir_str, 'type': 'str', 'value': self.outDir}, {'name': self.runs_str, 'type': 'str', 'value': self.runs, 'tip': "comma separated or use colon for a range, e.g. 1,3,5:7 = runs 1,3,5,6,7"}, {'name': self.sample_str, 'type': 'str', 'value': self.sample, 'tip': "name of the sample saved in the cxidb file, e.g. lysozyme"}, {'name': self.tag_str, 'type': 'str', 'value': self.tag, 'tip': "attach tag to stream, e.g. cxitut13_0010_tag.stream"}, {'name': self.queue_str, 'type': 'list', 'values': {self.noQueue_str: self.noQueue_str}, 'value': self.queue, 'tip': "Choose queue"}, {'name': self.cpu_str, 'type': 'int', 'value': self.cpu, 'tip': "number of cores to use for indexing per run"}, {'name': self.keepData_str, 'type': 'bool', 'value': self.keepData, 'tip': "Do not delete cxidb images in cxi file"}, ]}, ] self.p9 = Parameter.create(name='paramsCrystalIndexing', type='group', \ children=self.params, expanded=True) self.win.setParameters(self.p9, showTop=False) self.p9.sigTreeStateChanged.connect(self.change) if using_pyqt4: self.parent.connect(self.launchIndexBtn, QtCore.SIGNAL("clicked()"), self.indexPeaks) self.parent.connect(self.synchBtn, QtCore.SIGNAL("clicked()"), self.syncGeom) else: self.launchIndexBtn.clicked.connect(self.indexPeaks) self.synchBtn.clicked.connect(self.syncGeom) # Launch indexing def indexPeaks(self): self.parent.thread.append(LaunchIndexer.LaunchIndexer(self.parent)) # send parent parameters with self self.parent.thread[self.parent.threadCounter].launch(self.parent.experimentName, self.parent.detInfo) self.parent.threadCounter += 1 # Update psana geometry def syncGeom(self): if self.parent.facility == self.parent.facilityLCLS: with pg.BusyCursor(): print "#################################################" print "Updating psana geometry with CrystFEL geometry" print "#################################################" self.parent.geom.findPsanaGeometry() psanaGeom = self.parent.psocakeRunDir + "/.temp.data" if self.parent.args.localCalib: cmd = ["crystfel2psana", "-e", self.parent.experimentName, "-r", str(self.parent.runNumber), "-d", str(self.parent.det.name), "--rootDir", '.', "-c", self.geom, "-p", psanaGeom, "-z", str(self.parent.clen)] else: cmd = ["crystfel2psana", "-e", self.parent.experimentName, "-r", str(self.parent.runNumber), "-d", str(self.parent.det.name), "--rootDir", self.parent.rootDir, "-c", self.geom, "-p", psanaGeom, "-z", str(self.parent.clen)] if self.parent.args.v >= 0: print "cmd: ", cmd p = subprocess.Popen(cmd, stdout=subprocess.PIPE) output = p.communicate()[0] p.stdout.close() # Reload new psana geometry cmts = {'exp': self.parent.experimentName, 'app': 'psocake', 'comment': 'converted from crystfel geometry'} if self.parent.args.localCalib: calibDir = './calib' elif self.parent.args.outDir is None: calibDir = self.parent.rootDir + '/calib' else: calibDir = self.parent.dir + self.parent.experimentName[:3] + '/' + self.parent.experimentName + '/calib' deploy_calib_file(cdir=calibDir, src=str(self.parent.det.name), type='geometry', run_start=self.parent.runNumber, run_end=None, ifname=psanaGeom, dcmts=cmts, pbits=0) self.parent.exp.setupExperiment() self.parent.img.getDetImage(self.parent.eventNumber) self.parent.geom.updateRings() self.parent.index.updateIndex() self.parent.geom.drawCentre() # Show mask self.parent.mk.updatePsanaMaskOn() elif self.parent.facility == self.parent.facilityPAL: print "deploy crystfel geom is not implemented for PAL" # If anything changes in the parameter tree, print a message def change(self, panel, changes): for param, change, data in changes: path = panel.childPath(param) if self.parent.args.v >= 1: print(' path: %s' % path) print(' change: %s' % change) print(' data: %s' % str(data)) print(' ----------') self.paramUpdate(path, change, data) ############################## # Mandatory parameter update # ############################## def paramUpdate(self, path, change, data): if path[1] == self.index_on_str: self.updateIndexStatus(data) elif path[1] == self.index_geom_str: self.updateGeom(data) elif path[1] == self.index_peakMethod_str: self.updatePeakMethod(data) elif path[1] == self.index_intRadius_str: self.updateIntegrationRadius(data) elif path[1] == self.index_pdb_str: self.updatePDB(data) elif path[1] == self.index_method_str: self.updateIndexingMethod(data) elif path[1] == self.index_tolerance_str: self.updateTolerance(data) elif path[1] == self.index_extra_str: self.updateExtra(data) elif path[1] == self.index_condition_str: self.updateCondition(data) # launch grp elif path[1] == self.outDir_str: self.updateOutputDir(data) elif path[1] == self.runs_str: self.updateRuns(data) elif path[1] == self.sample_str: self.updateSample(data) elif path[1] == self.tag_str: self.updateTag(data) elif path[1] == self.queue_str: self.updateQueue(data) elif path[1] == self.chunkSize_str: self.updateChunkSize(data) elif path[1] == self.cpu_str: self.updateCpu(data) elif path[1] == self.noe_str: self.updateNoe(data) elif path[1] == self.keepData_str: self.keepData = data def updateIndexStatus(self, data): self.indexingOn = data self.showIndexedPeaks = data self.updateIndex() def updateGeom(self, data): self.geom = data self.updateIndex() def updatePeakMethod(self, data): self.peakMethod = data if self.indexingOn: self.updateIndex() def updateIntegrationRadius(self, data): self.intRadius = data self.updateIndex() def updatePDB(self, data): self.pdb = data self.updateIndex() def updateIndexingMethod(self, data): self.indexingMethod = data self.updateIndex() def updateTolerance(self, data): self.tolerance = data self.updateIndex() def updateExtra(self, data): self.extra = data.replace(" ","") self.updateIndex() def updateCondition(self, data): self.condition = data self.updateIndex() def updateIndex(self): if self.indexingOn: if self.parent.pk.peaks is None: self.parent.index.clearIndexedPeaks() else: self.indexer = IndexHandler(parent=self.parent) self.indexer.computeIndex(self.parent.experimentName, self.parent.runNumber, self.parent.detInfo, self.parent.eventNumber, self.geom, self.peakMethod, self.intRadius, self.pdb, self.indexingMethod, self.parent.pk.minPeaks, self.parent.pk.maxPeaks, self.parent.pk.minRes, self.tolerance, self.extra, self.outDir, queue=None) else: # do not display predicted spots self.parent.index.clearIndexedPeaks() def updateOutputDir(self, data): self.outDir = data self.outDir_overridden = True def updateRuns(self, data): self.runs = data def updateSample(self, data): self.sample = data def updateTag(self, data): self.tag = data def updateQueue(self, data): self.queue = data def updateChunkSize(self, data): self.chunkSize = data def updateCpu(self, data): self.cpu = data def updateNoe(self, data): self.noe = data def clearIndexedPeaks(self): self.parent.img.win.getView().removeItem(self.parent.img.abc_text) self.parent.img.indexedPeak_feature.setData([], [], pxMode=False) if self.parent.args.v >= 1: print "Done clearIndexedPeaks" def displayWaiting(self): if self.showIndexedPeaks: if self.numIndexedPeaksFound == 0: # indexing proceeding xMargin = 5 # pixels if self.parent.facility == self.parent.facilityLCLS: maxX = np.max(self.parent.det.indexes_x(self.parent.evt)) + xMargin maxY = np.max(self.parent.det.indexes_y(self.parent.evt)) elif self.parent.facility == self.parent.facilityPAL: yMargin = 0 # pixels (dim0, dim1) = self.parent.calib.shape self.iy = np.tile(np.arange(dim0), [dim1, 1]) self.ix = np.transpose(self.iy) maxX = np.max(self.ix) + xMargin maxY = np.max(self.iy) - yMargin # Draw a big X cenX = np.array((self.parent.cx,)) + 0.5 cenY = np.array((self.parent.cy,)) + 0.5 diameter = 256 # self.peakRadius*2+1 self.parent.img.indexedPeak_feature.setData(cenX, cenY, symbol='t', \ size=diameter, brush=(255, 255, 255, 0), \ pen=pg.mkPen({'color': "#FF00FF", 'width': 3}), pxMode=False) self.parent.img.abc_text = pg.TextItem(html='', anchor=(0, 0)) self.parent.img.win.getView().addItem(self.parent.img.abc_text) self.parent.img.abc_text.setPos(maxX, maxY) def drawIndexedPeaks(self, latticeType=None, centering=None, unitCell=None): self.clearIndexedPeaks() if self.showIndexedPeaks: if self.indexedPeaks is not None and self.numIndexedPeaksFound > 0: # indexing succeeded cenX = self.indexedPeaks[:,0]+0.5 cenY = self.indexedPeaks[:,1]+0.5 cenX = np.concatenate((cenX,cenX,cenX)) cenY = np.concatenate((cenY,cenY,cenY)) diameter = np.ones_like(cenX) diameter[0:self.numIndexedPeaksFound] = float(self.intRadius.split(',')[0])*2 diameter[self.numIndexedPeaksFound:2*self.numIndexedPeaksFound] = float(self.intRadius.split(',')[1])*2 diameter[2*self.numIndexedPeaksFound:3*self.numIndexedPeaksFound] = float(self.intRadius.split(',')[2])*2 self.parent.img.indexedPeak_feature.setData(cenX, cenY, symbol='o', \ size=diameter, brush=(255,255,255,0), \ pen=pg.mkPen({'color': "#FF00FF", 'width': 1.5}), pxMode=False) # Write unit cell parameters if unitCell is not None: xMargin = 5 yMargin = 400 if self.parent.facility == self.parent.facilityLCLS: maxX = np.max(self.parent.det.indexes_x(self.parent.evt)) + xMargin maxY = np.max(self.parent.det.indexes_y(self.parent.evt)) - yMargin elif self.parent.facility == self.parent.facilityPAL: (dim0, dim1) = self.parent.calib.shape self.iy = np.tile(np.arange(dim0), [dim1, 1]) self.ix = np.transpose(self.iy) maxX = np.max(self.ix) + xMargin maxY = np.max(self.iy) - yMargin #myMessage = '<div style="text-align: center"><span style="color: #FF00FF; font-size: 12pt;">lattice='+\ # str(latticeType) +'<br>centering=' + str(centering) + '<br>a='+\ # str(round(float(unitCell[0])*10,2))+'A <br>b='+str(round(float(unitCell[1])*10,2))+'A <br>c='+\ # str(round(float(unitCell[2])*10,2))+'A <br>α='+str(round(float(unitCell[3]),2))+\ # '° <br>β='+str(round(float(unitCell[4]),2))+'° <br>γ='+\ # str(round(float(unitCell[5]),2))+'° <br></span></div>' myMessage = '<div style="text-align: center"><span style="color: #FF00FF; font-size: 12pt;">lattice='+\ str(latticeType) +'<br>centering=' + str(centering) + '<br></span></div>' self.parent.img.abc_text = pg.TextItem(html=myMessage, anchor=(0,0)) self.parent.img.win.getView().addItem(self.parent.img.abc_text) self.parent.img.abc_text.setPos(maxX, maxY) else: # Failed indexing #xMargin = 5 # pixels #if self.parent.facility == self.parent.facilityLCLS: # maxX = np.max(self.parent.det.indexes_x(self.parent.evt))+xMargin # maxY = np.max(self.parent.det.indexes_y(self.parent.evt)) #elif self.parent.facility == self.parent.facilityPAL: # yMargin = 0 # pixels # (dim0, dim1) = self.parent.calib.shape # self.iy = np.tile(np.arange(dim0), [dim1, 1]) # self.ix = np.transpose(self.iy) # maxX = np.max(self.ix) + xMargin # maxY = np.max(self.iy) - yMargin # Draw a big X cenX = np.array((self.parent.cx,))+0.5 cenY = np.array((self.parent.cy,))+0.5 diameter = 256 #self.peakRadius*2+1 self.parent.img.indexedPeak_feature.setData(cenX, cenY, symbol='x', \ size=diameter, brush=(255,255,255,0), \ pen=pg.mkPen({'color': "#FF00FF", 'width': 3}), pxMode=False) self.parent.img.abc_text = pg.TextItem(html='', anchor=(0,0)) self.parent.img.win.getView().addItem(self.parent.img.abc_text) self.parent.img.abc_text.setPos(0,0) else: self.parent.img.indexedPeak_feature.setData([], [], pxMode=False) self.parent.img.abc_text = pg.TextItem(html='', anchor=(0, 0)) self.parent.img.win.getView().addItem(self.parent.img.abc_text) self.parent.img.abc_text.setPos(0, 0) if self.parent.args.v >= 1: print "Done drawIndexedPeaks" # This function probably doesn't get called def launchIndexing(self, requestRun=None): self.batchIndexer = IndexHandler(parent=self.parent) if requestRun is None: self.batchIndexer.computeIndex(self.parent.experimentName, self.parent.runNumber, self.parent.detInfo, self.parent.eventNumber, self.geom, self.peakMethod, self.intRadius, self.pdb, self.indexingMethod, self.parent.pk.minPeaks, self.parent.pk.maxPeaks, self.parent.pk.minRes, self.tolerance, self.extra, self.outDir, self.runs, self.sample, self.tag, self.queue, self.chunkSize, self.noe) else: self.batchIndexer.computeIndex(self.parent.experimentName, requestRun, self.parent.detInfo, self.parent.eventNumber, self.geom, self.peakMethod, self.intRadius, self.pdb, self.indexingMethod, self.parent.pk.minPeaks, self.parent.pk.maxPeaks, self.parent.pk.minRes, self.tolerance, self.extra, self.outDir, self.runs, self.sample, self.tag, self.queue, self.chunkSize, self.noe) if self.parent.args.v >= 1: print "Done updateIndex"
def __init__(self, parent = None): self.parent = parent ## Dock: Indexing self.dock = Dock("Indexing", size=(1, 1)) self.win = ParameterTree() self.win.setWindowTitle('Indexing') self.dock.addWidget(self.win) self.winL = pg.LayoutWidget() self.launchIndexBtn = QtGui.QPushButton('Launch indexing') self.winL.addWidget(self.launchIndexBtn, row=0, col=0) self.synchBtn = QtGui.QPushButton('Deploy CrystFEL geometry') self.winL.addWidget(self.synchBtn, row=1, col=0) self.dock.addWidget(self.winL) self.index_grp = 'Crystal indexing' self.index_on_str = 'Indexing on' self.index_geom_str = 'CrystFEL geometry' self.index_peakMethod_str = 'Peak method' self.index_intRadius_str = 'Integration radii' self.index_pdb_str = 'Unitcell' self.index_method_str = 'Indexing method' self.index_tolerance_str = 'Tolerance' self.index_extra_str = 'Extra CrystFEL parameters' self.index_condition_str = 'Index condition' self.launch_grp = 'Batch' self.outDir_str = 'Output directory' self.runs_str = 'Runs(s)' self.sample_str = 'Sample name' self.tag_str = 'Tag' self.queue_str = 'Queue' self.chunkSize_str = 'Chunk size' self.cpu_str = 'CPUs' self.keepData_str = 'Keep CXI images' self.noe_str = 'Number of events to process' (self.psanaq_str,self.psnehq_str,self.psfehq_str,self.psnehprioq_str,self.psfehprioq_str,self.psnehhiprioq_str,self.psfehhiprioq_str,self.psdebugq_str) = \ ('psanaq','psnehq','psfehq','psnehprioq','psfehprioq','psnehhiprioq','psfehhiprioq','psdebugq') self.noQueue_str = 'N/A' self.outDir = self.parent.psocakeDir self.outDir_overridden = False self.runs = '' self.sample = 'crystal' self.tag = '' self.queue = self.psanaq_str self.chunkSize = 500 self.cpu = 12 self.noe = -1 # Indexing if self.parent.facility == self.parent.facilityLCLS: self.showIndexedPeaks = False self.indexedPeaks = None self.hiddenCXI = '.temp.cxi' self.hiddenCrystfelStream = '.temp.stream' self.hiddenCrystfelList = '.temp.lst' self.indexingOn = False self.numIndexedPeaksFound = 0 self.geom = '.temp.geom' self.peakMethod = 'cxi' self.intRadius = '3,4,5' self.pdb = '' self.indexingMethod = 'mosflm,dirax' self.tolerance = '5,5,5,1.5' self.extra = '' self.condition = '' self.keepData = True elif self.parent.facility == self.parent.facilityPAL: self.showIndexedPeaks = False self.indexedPeaks = None self.hiddenCXI = '.temp.cxi' self.hiddenCrystfelStream = '.temp.stream' self.hiddenCrystfelList = '.temp.lst' self.indexingOn = False self.numIndexedPeaksFound = 0 self.geom = '.temp.geom' self.peakMethod = 'cxi' self.intRadius = '4,5,6' self.pdb = '' self.indexingMethod = 'mosflm,dirax' self.tolerance = '5,5,5,1.5' self.extra = '' self.condition = '' self.keepData = True ####################### # Mandatory parameter # ####################### if self.parent.facility == self.parent.facilityLCLS: self.params = [ {'name': self.index_grp, 'type': 'group', 'children': [ {'name': self.index_on_str, 'type': 'bool', 'value': self.indexingOn, 'tip': "Turn on indexing"}, {'name': self.index_geom_str, 'type': 'str', 'value': self.geom, 'tip': "CrystFEL geometry file"}, #{'name': self.index_peakMethod_str, 'type': 'str', 'value': self.peakMethod, 'tip': "Turn on indexing"}, {'name': self.index_intRadius_str, 'type': 'str', 'value': self.intRadius, 'tip': "Integration radii"}, {'name': self.index_pdb_str, 'type': 'str', 'value': self.pdb, 'tip': "(Optional) CrystFEL unitcell file"}, {'name': self.index_method_str, 'type': 'str', 'value': self.indexingMethod, 'tip': "comma separated indexing methods"}, {'name': self.index_tolerance_str, 'type': 'str', 'value': self.tolerance, 'tip': "Indexing tolerance, default: 5,5,5,1.5"}, {'name': self.index_extra_str, 'type': 'str', 'value': self.extra, 'tip': "Other indexing parameters, comma separated (e.g. --multi,--no-check-peaks)"}, {'name': self.index_condition_str, 'type': 'str', 'value': self.condition, 'tip': "indexing condition e.g. 41 in #evr1# and #eventNumber# > 3"}, ]}, {'name': self.launch_grp, 'type': 'group', 'children': [ {'name': self.outDir_str, 'type': 'str', 'value': self.outDir}, {'name': self.runs_str, 'type': 'str', 'value': self.runs, 'tip': "comma separated or use colon for a range, e.g. 1,3,5:7 = runs 1,3,5,6,7"}, {'name': self.sample_str, 'type': 'str', 'value': self.sample, 'tip': "name of the sample saved in the cxidb file, e.g. lysozyme"}, {'name': self.tag_str, 'type': 'str', 'value': self.tag, 'tip': "attach tag to stream, e.g. cxitut13_0010_tag.stream"}, {'name': self.queue_str, 'type': 'list', 'values': {self.psfehhiprioq_str: self.psfehhiprioq_str, self.psnehhiprioq_str: self.psnehhiprioq_str, self.psfehprioq_str: self.psfehprioq_str, self.psnehprioq_str: self.psnehprioq_str, self.psfehq_str: self.psfehq_str, self.psnehq_str: self.psnehq_str, self.psanaq_str: self.psanaq_str, self.psdebugq_str: self.psdebugq_str}, 'value': self.queue, 'tip': "Choose queue"}, {'name': self.chunkSize_str, 'type': 'int', 'value': self.chunkSize, 'tip': "number of patterns to process per worker"}, {'name': self.keepData_str, 'type': 'bool', 'value': self.keepData, 'tip': "Do not delete cxidb images in cxi file"}, ]}, ] elif self.parent.facility == self.parent.facilityPAL: self.params = [ {'name': self.index_grp, 'type': 'group', 'children': [ {'name': self.index_on_str, 'type': 'bool', 'value': self.indexingOn, 'tip': "Turn on indexing"}, {'name': self.index_geom_str, 'type': 'str', 'value': self.geom, 'tip': "CrystFEL geometry file"}, {'name': self.index_intRadius_str, 'type': 'str', 'value': self.intRadius, 'tip': "Integration radii"}, {'name': self.index_pdb_str, 'type': 'str', 'value': self.pdb, 'tip': "(Optional) CrystFEL unitcell file"}, {'name': self.index_method_str, 'type': 'str', 'value': self.indexingMethod, 'tip': "comma separated indexing methods"}, {'name': self.index_tolerance_str, 'type': 'str', 'value': self.tolerance, 'tip': "Indexing tolerance, default: 5,5,5,1.5"}, {'name': self.index_extra_str, 'type': 'str', 'value': self.extra, 'tip': "Other CrystFEL indexing parameters"}, ]}, {'name': self.launch_grp, 'type': 'group', 'children': [ {'name': self.outDir_str, 'type': 'str', 'value': self.outDir}, {'name': self.runs_str, 'type': 'str', 'value': self.runs, 'tip': "comma separated or use colon for a range, e.g. 1,3,5:7 = runs 1,3,5,6,7"}, {'name': self.sample_str, 'type': 'str', 'value': self.sample, 'tip': "name of the sample saved in the cxidb file, e.g. lysozyme"}, {'name': self.tag_str, 'type': 'str', 'value': self.tag, 'tip': "attach tag to stream, e.g. cxitut13_0010_tag.stream"}, {'name': self.queue_str, 'type': 'list', 'values': {self.noQueue_str: self.noQueue_str}, 'value': self.queue, 'tip': "Choose queue"}, {'name': self.cpu_str, 'type': 'int', 'value': self.cpu, 'tip': "number of cores to use for indexing per run"}, {'name': self.keepData_str, 'type': 'bool', 'value': self.keepData, 'tip': "Do not delete cxidb images in cxi file"}, ]}, ] self.p9 = Parameter.create(name='paramsCrystalIndexing', type='group', \ children=self.params, expanded=True) self.win.setParameters(self.p9, showTop=False) self.p9.sigTreeStateChanged.connect(self.change) if using_pyqt4: self.parent.connect(self.launchIndexBtn, QtCore.SIGNAL("clicked()"), self.indexPeaks) self.parent.connect(self.synchBtn, QtCore.SIGNAL("clicked()"), self.syncGeom) else: self.launchIndexBtn.clicked.connect(self.indexPeaks) self.synchBtn.clicked.connect(self.syncGeom)
def __init__(self, parent = None): self.parent = parent self.d9 = Dock("Peak Finder", size=(1, 1)) ## Dock 9: Peak finder self.w10 = ParameterTree() self.d9.addWidget(self.w10) #self.w11 = pg.LayoutWidget() #self.generatePowderBtn = QtGui.QPushButton('Generate Powder') #self.launchBtn = QtGui.QPushButton('Launch peak finder') #self.w11.addWidget(self.launchBtn, row=0,col=0) #self.w11.addWidget(self.generatePowderBtn, row=0, col=0) #self.d9.addWidget(self.w11) self.userUpdate = None self.doingUpdate = False # Peak finding self.hitParam_grp = 'Peak finder' self.hitParam_showPeaks_str = 'Show peaks found' self.hitParam_algorithm_str = 'Algorithm' # algorithm 0 self.hitParam_algorithm0_str = 'None' # algorithm 1 self.hitParam_alg1_npix_min_str = 'npix_min' self.hitParam_alg1_npix_max_str = 'npix_max' self.hitParam_alg1_amax_thr_str = 'amax_thr' self.hitParam_alg1_atot_thr_str = 'atot_thr' self.hitParam_alg1_son_min_str = 'son_min' self.hitParam_algorithm1_str = 'Droplet' self.hitParam_alg1_thr_low_str = 'thr_low' self.hitParam_alg1_thr_high_str = 'thr_high' self.hitParam_alg1_rank_str = 'rank' self.hitParam_alg1_radius_str = 'radius' self.hitParam_alg1_dr_str = 'dr' # algorithm 2 self.hitParam_alg2_npix_min_str = 'npix_min' self.hitParam_alg2_npix_max_str = 'npix_max' self.hitParam_alg2_amax_thr_str = 'amax_thr' self.hitParam_alg2_atot_thr_str = 'atot_thr' self.hitParam_alg2_son_min_str = 'son_min' self.hitParam_algorithm2_str = 'FloodFill' self.hitParam_alg2_thr_str = 'thr' self.hitParam_alg2_r0_str = 'r0' self.hitParam_alg2_dr_str = 'dr' # algorithm 3 self.hitParam_alg3_npix_min_str = 'npix_min' self.hitParam_alg3_npix_max_str = 'npix_max' self.hitParam_alg3_amax_thr_str = 'amax_thr' self.hitParam_alg3_atot_thr_str = 'atot_thr' self.hitParam_alg3_son_min_str = 'son_min' self.hitParam_algorithm3_str = 'Ranker' self.hitParam_alg3_rank_str = 'rank' self.hitParam_alg3_r0_str = 'r0' self.hitParam_alg3_dr_str = 'dr' # algorithm 4 self.hitParam_alg4_npix_min_str = 'npix_min' self.hitParam_alg4_npix_max_str = 'npix_max' self.hitParam_alg4_amax_thr_str = 'amax_thr' self.hitParam_alg4_atot_thr_str = 'atot_thr' self.hitParam_alg4_son_min_str = 'son_min' self.hitParam_algorithm4_str = 'iDroplet' self.hitParam_alg4_thr_low_str = 'thr_low' self.hitParam_alg4_thr_high_str = 'thr_high' self.hitParam_alg4_rank_str = 'rank' self.hitParam_alg4_r0_str = 'radius' self.hitParam_alg4_dr_str = 'dr' self.hitParam_outDir_str = 'Output directory' self.hitParam_runs_str = 'Run(s)' self.hitParam_queue_str = 'queue' self.hitParam_cpu_str = 'CPUs' self.hitParam_psanaq_str = 'psanaq' self.hitParam_psnehq_str = 'psnehq' self.hitParam_psfehq_str = 'psfehq' self.hitParam_psnehprioq_str = 'psnehprioq' self.hitParam_psfehprioq_str = 'psfehprioq' self.hitParam_psnehhiprioq_str = 'psnehhiprioq' self.hitParam_psfehhiprioq_str = 'psfehhiprioq' self.hitParam_psdebugq_str = 'psdebugq' self.hitParam_noe_str = 'Number of events to process' self.hitParam_threshold_str = 'Indexable number of peaks' self.hitParam_launch_str = 'Launch peak finder' self.hitParam_extra_str = 'Extra parameters' self.save_minPeaks_str = 'Minimum number of peaks' self.save_maxPeaks_str = 'Maximum number of peaks' self.save_minRes_str = 'Minimum resolution (pixels)' self.save_sample_str = 'Sample name' self.showPeaks = True self.peaks = None self.numPeaksFound = 0 self.algorithm = 0 self.algInitDone = False self.peaksMaxRes = 0 self.classify = False self.hitParam_alg1_npix_min = 2. self.hitParam_alg1_npix_max = 20. self.hitParam_alg1_amax_thr = 0. self.hitParam_alg1_atot_thr = 1000. self.hitParam_alg1_son_min = 7. self.hitParam_alg1_thr_low = 250. self.hitParam_alg1_thr_high = 600. self.hitParam_alg1_rank = 2 self.hitParam_alg1_radius = 2 self.hitParam_alg1_dr = 1 # self.hitParam_alg2_npix_min = 1. # self.hitParam_alg2_npix_max = 5000. # self.hitParam_alg2_amax_thr = 1. # self.hitParam_alg2_atot_thr = 1. # self.hitParam_alg2_son_min = 1. # self.hitParam_alg2_thr = 10. # self.hitParam_alg2_r0 = 1. # self.hitParam_alg2_dr = 0.05 # self.hitParam_alg3_npix_min = 5. # self.hitParam_alg3_npix_max = 5000. # self.hitParam_alg3_amax_thr = 0. # self.hitParam_alg3_atot_thr = 0. # self.hitParam_alg3_son_min = 4. # self.hitParam_alg3_rank = 3 # self.hitParam_alg3_r0 = 5. # self.hitParam_alg3_dr = 0.05 # self.hitParam_alg4_npix_min = 1. # self.hitParam_alg4_npix_max = 45. # self.hitParam_alg4_amax_thr = 800. # self.hitParam_alg4_atot_thr = 0 # self.hitParam_alg4_son_min = 7. # self.hitParam_alg4_thr_low = 200. # self.hitParam_alg4_thr_high = self.hitParam_alg1_thr_high # self.hitParam_alg4_rank = 3 # self.hitParam_alg4_r0 = 2 # self.hitParam_alg4_dr = 1 self.hitParam_outDir = self.parent.psocakeDir self.hitParam_outDir_overridden = False self.hitParam_runs = '' self.hitParam_queue = self.hitParam_psanaq_str self.hitParam_cpus = 24 self.hitParam_noe = -1 self.hitParam_threshold = 15 # usually crystals with less than 15 peaks are not indexable self.minPeaks = 15 self.maxPeaks = 2048 self.minRes = -1 self.sample = 'sample' self.profile = 0 self.hitParam_extra = '' self.params = [ {'name': self.hitParam_grp, 'type': 'group', 'children': [ {'name': self.hitParam_showPeaks_str, 'type': 'bool', 'value': self.showPeaks, 'tip': "Show peaks found shot-to-shot"}, {'name': self.hitParam_algorithm_str, 'type': 'list', 'values': {self.hitParam_algorithm1_str: 1, self.hitParam_algorithm0_str: 0}, 'value': self.algorithm}, {'name': self.hitParam_algorithm1_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "", 'readonly': True, 'children': [ {'name': self.hitParam_alg1_npix_min_str, 'type': 'float', 'value': self.hitParam_alg1_npix_min, 'tip': "Only keep the peak if number of pixels above thr_low is above this value"}, {'name': self.hitParam_alg1_npix_max_str, 'type': 'float', 'value': self.hitParam_alg1_npix_max, 'tip': "Only keep the peak if number of pixels above thr_low is below this value"}, {'name': self.hitParam_alg1_amax_thr_str, 'type': 'float', 'value': self.hitParam_alg1_amax_thr, 'tip': "Only keep the peak if max value is above this value"}, {'name': self.hitParam_alg1_atot_thr_str, 'type': 'float', 'value': self.hitParam_alg1_atot_thr, 'tip': "Only keep the peak if integral inside region of interest is above this value"}, {'name': self.hitParam_alg1_son_min_str, 'type': 'float', 'value': self.hitParam_alg1_son_min, 'tip': "Only keep the peak if signal-over-noise is above this value"}, {'name': self.hitParam_alg1_thr_low_str, 'type': 'float', 'value': self.hitParam_alg1_thr_low, 'tip': "Grow a seed peak if above this value"}, {'name': self.hitParam_alg1_thr_high_str, 'type': 'float', 'value': self.hitParam_alg1_thr_high, 'tip': "Start a seed peak if above this value"}, {'name': self.hitParam_alg1_rank_str, 'type': 'int', 'value': self.hitParam_alg1_rank, 'tip': "region of integration is a square, (2r+1)x(2r+1)"}, {'name': self.hitParam_alg1_radius_str, 'type': 'int', 'value': self.hitParam_alg1_radius, 'tip': "region inside the region of interest"}, {'name': self.hitParam_alg1_dr_str, 'type': 'float', 'value': self.hitParam_alg1_dr, 'tip': "background region outside the region of interest"}, ]}, {'name': self.save_minPeaks_str, 'type': 'int', 'value': self.minPeaks, 'tip': "Index only if there are more Bragg peaks found"}, {'name': self.save_maxPeaks_str, 'type': 'int', 'value': self.maxPeaks, 'tip': "Index only if there are less Bragg peaks found"}, {'name': self.save_minRes_str, 'type': 'int', 'value': self.minRes, 'tip': "Index only if Bragg peak resolution is at least this"}, {'name': self.save_sample_str, 'type': 'str', 'value': self.sample, 'tip': "Sample name saved inside cxi"}, {'name': self.hitParam_outDir_str, 'type': 'str', 'value': self.hitParam_outDir}, {'name': self.hitParam_runs_str, 'type': 'str', 'value': self.hitParam_runs}, {'name': self.hitParam_queue_str, 'type': 'list', 'values': {self.hitParam_psfehhiprioq_str: 'psfehhiprioq', self.hitParam_psnehhiprioq_str: 'psnehhiprioq', self.hitParam_psfehprioq_str: 'psfehprioq', self.hitParam_psnehprioq_str: 'psnehprioq', self.hitParam_psfehq_str: 'psfehq', self.hitParam_psnehq_str: 'psnehq', self.hitParam_psanaq_str: 'psanaq', self.hitParam_psdebugq_str: 'psdebugq'}, 'value': self.hitParam_queue, 'tip': "Choose queue"}, {'name': self.hitParam_cpu_str, 'type': 'int', 'value': self.hitParam_cpus}, {'name': self.hitParam_noe_str, 'type': 'int', 'value': self.hitParam_noe, 'tip': "number of events to process, default=-1 means process all events"}, {'name': self.hitParam_extra_str, 'type': 'str', 'value': self.hitParam_extra, 'tip': "Extra peak finding flags"}, {'name': self.hitParam_launch_str, 'type': 'action'}, ]}, ] self.p3 = Parameter.create(name='paramsPeakFinder', type='group', \ children=self.params, expanded=True) self.w10.setParameters(self.p3, showTop=False) self.p3.sigTreeStateChanged.connect(self.change)
class PeakFinding(object): def __init__(self, parent = None): self.parent = parent self.d9 = Dock("Peak Finder", size=(1, 1)) ## Dock 9: Peak finder self.w10 = ParameterTree() self.d9.addWidget(self.w10) #self.w11 = pg.LayoutWidget() #self.generatePowderBtn = QtGui.QPushButton('Generate Powder') #self.launchBtn = QtGui.QPushButton('Launch peak finder') #self.w11.addWidget(self.launchBtn, row=0,col=0) #self.w11.addWidget(self.generatePowderBtn, row=0, col=0) #self.d9.addWidget(self.w11) self.userUpdate = None self.doingUpdate = False # Peak finding self.hitParam_grp = 'Peak finder' self.hitParam_showPeaks_str = 'Show peaks found' self.hitParam_algorithm_str = 'Algorithm' # algorithm 0 self.hitParam_algorithm0_str = 'None' # algorithm 1 self.hitParam_alg1_npix_min_str = 'npix_min' self.hitParam_alg1_npix_max_str = 'npix_max' self.hitParam_alg1_amax_thr_str = 'amax_thr' self.hitParam_alg1_atot_thr_str = 'atot_thr' self.hitParam_alg1_son_min_str = 'son_min' self.hitParam_algorithm1_str = 'Droplet' self.hitParam_alg1_thr_low_str = 'thr_low' self.hitParam_alg1_thr_high_str = 'thr_high' self.hitParam_alg1_rank_str = 'rank' self.hitParam_alg1_radius_str = 'radius' self.hitParam_alg1_dr_str = 'dr' # algorithm 2 self.hitParam_alg2_npix_min_str = 'npix_min' self.hitParam_alg2_npix_max_str = 'npix_max' self.hitParam_alg2_amax_thr_str = 'amax_thr' self.hitParam_alg2_atot_thr_str = 'atot_thr' self.hitParam_alg2_son_min_str = 'son_min' self.hitParam_algorithm2_str = 'FloodFill' self.hitParam_alg2_thr_str = 'thr' self.hitParam_alg2_r0_str = 'r0' self.hitParam_alg2_dr_str = 'dr' # algorithm 3 self.hitParam_alg3_npix_min_str = 'npix_min' self.hitParam_alg3_npix_max_str = 'npix_max' self.hitParam_alg3_amax_thr_str = 'amax_thr' self.hitParam_alg3_atot_thr_str = 'atot_thr' self.hitParam_alg3_son_min_str = 'son_min' self.hitParam_algorithm3_str = 'Ranker' self.hitParam_alg3_rank_str = 'rank' self.hitParam_alg3_r0_str = 'r0' self.hitParam_alg3_dr_str = 'dr' # algorithm 4 self.hitParam_alg4_npix_min_str = 'npix_min' self.hitParam_alg4_npix_max_str = 'npix_max' self.hitParam_alg4_amax_thr_str = 'amax_thr' self.hitParam_alg4_atot_thr_str = 'atot_thr' self.hitParam_alg4_son_min_str = 'son_min' self.hitParam_algorithm4_str = 'iDroplet' self.hitParam_alg4_thr_low_str = 'thr_low' self.hitParam_alg4_thr_high_str = 'thr_high' self.hitParam_alg4_rank_str = 'rank' self.hitParam_alg4_r0_str = 'radius' self.hitParam_alg4_dr_str = 'dr' self.hitParam_outDir_str = 'Output directory' self.hitParam_runs_str = 'Run(s)' self.hitParam_queue_str = 'queue' self.hitParam_cpu_str = 'CPUs' self.hitParam_psanaq_str = 'psanaq' self.hitParam_psnehq_str = 'psnehq' self.hitParam_psfehq_str = 'psfehq' self.hitParam_psnehprioq_str = 'psnehprioq' self.hitParam_psfehprioq_str = 'psfehprioq' self.hitParam_psnehhiprioq_str = 'psnehhiprioq' self.hitParam_psfehhiprioq_str = 'psfehhiprioq' self.hitParam_psdebugq_str = 'psdebugq' self.hitParam_noe_str = 'Number of events to process' self.hitParam_threshold_str = 'Indexable number of peaks' self.hitParam_launch_str = 'Launch peak finder' self.hitParam_extra_str = 'Extra parameters' self.save_minPeaks_str = 'Minimum number of peaks' self.save_maxPeaks_str = 'Maximum number of peaks' self.save_minRes_str = 'Minimum resolution (pixels)' self.save_sample_str = 'Sample name' self.showPeaks = True self.peaks = None self.numPeaksFound = 0 self.algorithm = 0 self.algInitDone = False self.peaksMaxRes = 0 self.classify = False self.hitParam_alg1_npix_min = 2. self.hitParam_alg1_npix_max = 20. self.hitParam_alg1_amax_thr = 0. self.hitParam_alg1_atot_thr = 1000. self.hitParam_alg1_son_min = 7. self.hitParam_alg1_thr_low = 250. self.hitParam_alg1_thr_high = 600. self.hitParam_alg1_rank = 2 self.hitParam_alg1_radius = 2 self.hitParam_alg1_dr = 1 # self.hitParam_alg2_npix_min = 1. # self.hitParam_alg2_npix_max = 5000. # self.hitParam_alg2_amax_thr = 1. # self.hitParam_alg2_atot_thr = 1. # self.hitParam_alg2_son_min = 1. # self.hitParam_alg2_thr = 10. # self.hitParam_alg2_r0 = 1. # self.hitParam_alg2_dr = 0.05 # self.hitParam_alg3_npix_min = 5. # self.hitParam_alg3_npix_max = 5000. # self.hitParam_alg3_amax_thr = 0. # self.hitParam_alg3_atot_thr = 0. # self.hitParam_alg3_son_min = 4. # self.hitParam_alg3_rank = 3 # self.hitParam_alg3_r0 = 5. # self.hitParam_alg3_dr = 0.05 # self.hitParam_alg4_npix_min = 1. # self.hitParam_alg4_npix_max = 45. # self.hitParam_alg4_amax_thr = 800. # self.hitParam_alg4_atot_thr = 0 # self.hitParam_alg4_son_min = 7. # self.hitParam_alg4_thr_low = 200. # self.hitParam_alg4_thr_high = self.hitParam_alg1_thr_high # self.hitParam_alg4_rank = 3 # self.hitParam_alg4_r0 = 2 # self.hitParam_alg4_dr = 1 self.hitParam_outDir = self.parent.psocakeDir self.hitParam_outDir_overridden = False self.hitParam_runs = '' self.hitParam_queue = self.hitParam_psanaq_str self.hitParam_cpus = 24 self.hitParam_noe = -1 self.hitParam_threshold = 15 # usually crystals with less than 15 peaks are not indexable self.minPeaks = 15 self.maxPeaks = 2048 self.minRes = -1 self.sample = 'sample' self.profile = 0 self.hitParam_extra = '' self.params = [ {'name': self.hitParam_grp, 'type': 'group', 'children': [ {'name': self.hitParam_showPeaks_str, 'type': 'bool', 'value': self.showPeaks, 'tip': "Show peaks found shot-to-shot"}, {'name': self.hitParam_algorithm_str, 'type': 'list', 'values': {self.hitParam_algorithm1_str: 1, self.hitParam_algorithm0_str: 0}, 'value': self.algorithm}, {'name': self.hitParam_algorithm1_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "", 'readonly': True, 'children': [ {'name': self.hitParam_alg1_npix_min_str, 'type': 'float', 'value': self.hitParam_alg1_npix_min, 'tip': "Only keep the peak if number of pixels above thr_low is above this value"}, {'name': self.hitParam_alg1_npix_max_str, 'type': 'float', 'value': self.hitParam_alg1_npix_max, 'tip': "Only keep the peak if number of pixels above thr_low is below this value"}, {'name': self.hitParam_alg1_amax_thr_str, 'type': 'float', 'value': self.hitParam_alg1_amax_thr, 'tip': "Only keep the peak if max value is above this value"}, {'name': self.hitParam_alg1_atot_thr_str, 'type': 'float', 'value': self.hitParam_alg1_atot_thr, 'tip': "Only keep the peak if integral inside region of interest is above this value"}, {'name': self.hitParam_alg1_son_min_str, 'type': 'float', 'value': self.hitParam_alg1_son_min, 'tip': "Only keep the peak if signal-over-noise is above this value"}, {'name': self.hitParam_alg1_thr_low_str, 'type': 'float', 'value': self.hitParam_alg1_thr_low, 'tip': "Grow a seed peak if above this value"}, {'name': self.hitParam_alg1_thr_high_str, 'type': 'float', 'value': self.hitParam_alg1_thr_high, 'tip': "Start a seed peak if above this value"}, {'name': self.hitParam_alg1_rank_str, 'type': 'int', 'value': self.hitParam_alg1_rank, 'tip': "region of integration is a square, (2r+1)x(2r+1)"}, {'name': self.hitParam_alg1_radius_str, 'type': 'int', 'value': self.hitParam_alg1_radius, 'tip': "region inside the region of interest"}, {'name': self.hitParam_alg1_dr_str, 'type': 'float', 'value': self.hitParam_alg1_dr, 'tip': "background region outside the region of interest"}, ]}, {'name': self.save_minPeaks_str, 'type': 'int', 'value': self.minPeaks, 'tip': "Index only if there are more Bragg peaks found"}, {'name': self.save_maxPeaks_str, 'type': 'int', 'value': self.maxPeaks, 'tip': "Index only if there are less Bragg peaks found"}, {'name': self.save_minRes_str, 'type': 'int', 'value': self.minRes, 'tip': "Index only if Bragg peak resolution is at least this"}, {'name': self.save_sample_str, 'type': 'str', 'value': self.sample, 'tip': "Sample name saved inside cxi"}, {'name': self.hitParam_outDir_str, 'type': 'str', 'value': self.hitParam_outDir}, {'name': self.hitParam_runs_str, 'type': 'str', 'value': self.hitParam_runs}, {'name': self.hitParam_queue_str, 'type': 'list', 'values': {self.hitParam_psfehhiprioq_str: 'psfehhiprioq', self.hitParam_psnehhiprioq_str: 'psnehhiprioq', self.hitParam_psfehprioq_str: 'psfehprioq', self.hitParam_psnehprioq_str: 'psnehprioq', self.hitParam_psfehq_str: 'psfehq', self.hitParam_psnehq_str: 'psnehq', self.hitParam_psanaq_str: 'psanaq', self.hitParam_psdebugq_str: 'psdebugq'}, 'value': self.hitParam_queue, 'tip': "Choose queue"}, {'name': self.hitParam_cpu_str, 'type': 'int', 'value': self.hitParam_cpus}, {'name': self.hitParam_noe_str, 'type': 'int', 'value': self.hitParam_noe, 'tip': "number of events to process, default=-1 means process all events"}, {'name': self.hitParam_extra_str, 'type': 'str', 'value': self.hitParam_extra, 'tip': "Extra peak finding flags"}, {'name': self.hitParam_launch_str, 'type': 'action'}, ]}, ] self.p3 = Parameter.create(name='paramsPeakFinder', type='group', \ children=self.params, expanded=True) self.w10.setParameters(self.p3, showTop=False) self.p3.sigTreeStateChanged.connect(self.change) #self.parent.connect(self.launchBtn, QtCore.SIGNAL("clicked()"), self.findPeaks) def digestRunList(self, runList): runsToDo = [] if not runList: print "Run(s) is empty. Please type in the run number(s)." return runsToDo runLists = str(runList).split(",") for list in runLists: temp = list.split(":") if len(temp) == 2: for i in np.arange(int(temp[0]),int(temp[1])+1): runsToDo.append(i) elif len(temp) == 1: runsToDo.append(int(temp[0])) return runsToDo def updateParam(self): if self.userUpdate is None: if self.parent.psocakeRunDir is not None: peakParamFname = self.parent.psocakeRunDir + '/peakParam.json' if os.path.exists(peakParamFname): with open(peakParamFname) as infile: d = json.load(infile) if d[self.hitParam_algorithm_str] == 1: # Update variables try: self.hitParam_alg1_npix_min = d[self.hitParam_alg1_npix_min_str] self.hitParam_alg1_npix_max = d[self.hitParam_alg1_npix_max_str] self.hitParam_alg1_amax_thr = d[self.hitParam_alg1_amax_thr_str] self.hitParam_alg1_atot_thr = d[self.hitParam_alg1_atot_thr_str] self.hitParam_alg1_son_min = d[self.hitParam_alg1_son_min_str] self.hitParam_alg1_thr_low = d[self.hitParam_alg1_thr_low_str] self.hitParam_alg1_thr_high = d[self.hitParam_alg1_thr_high_str] self.hitParam_alg1_rank = int(d[self.hitParam_alg1_rank_str]) self.hitParam_alg1_radius = int(d[self.hitParam_alg1_radius_str]) self.hitParam_alg1_dr = d[self.hitParam_alg1_dr_str] # Update GUI self.doingUpdate = True #self.p3.param(self.hitParam_grp, self.hitParam_algorithm_str).setValue(self.algorithm) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_npix_min_str).setValue( self.hitParam_alg1_npix_min) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_npix_max_str).setValue( self.hitParam_alg1_npix_max) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_amax_thr_str).setValue( self.hitParam_alg1_amax_thr) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_atot_thr_str).setValue( self.hitParam_alg1_atot_thr) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_son_min_str).setValue( self.hitParam_alg1_son_min) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_thr_low_str).setValue( self.hitParam_alg1_thr_low) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_thr_high_str).setValue( self.hitParam_alg1_thr_high) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_rank_str).setValue( self.hitParam_alg1_rank) self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_radius_str).setValue( self.hitParam_alg1_radius) self.doingUpdate = False self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_dr_str).setValue( self.hitParam_alg1_dr) except: pass def writeStatus(self, fname, d): json.dump(d, open(fname, 'w')) # Launch peak finding def findPeaks(self): self.parent.thread.append(LaunchPeakFinder.LaunchPeakFinder(self.parent)) # send parent parameters with self self.parent.thread[self.parent.threadCounter].launch(self.parent.experimentName, self.parent.detInfo) self.parent.threadCounter+=1 # Save peak finding parameters runsToDo = self.digestRunList(self.hitParam_runs) for run in runsToDo: peakParamFname = self.parent.psocakeDir+'/r'+str(run).zfill(4)+'/peakParam.json' d = {self.hitParam_algorithm_str: self.algorithm, self.hitParam_alg1_npix_min_str: self.hitParam_alg1_npix_min, self.hitParam_alg1_npix_max_str: self.hitParam_alg1_npix_max, self.hitParam_alg1_amax_thr_str: self.hitParam_alg1_amax_thr, self.hitParam_alg1_atot_thr_str: self.hitParam_alg1_atot_thr, self.hitParam_alg1_son_min_str: self.hitParam_alg1_son_min, self.hitParam_alg1_thr_low_str: self.hitParam_alg1_thr_low, self.hitParam_alg1_thr_high_str: self.hitParam_alg1_thr_high, self.hitParam_alg1_rank_str: self.hitParam_alg1_rank, self.hitParam_alg1_radius_str: self.hitParam_alg1_radius, self.hitParam_alg1_dr_str: self.hitParam_alg1_dr} self.writeStatus(peakParamFname, d) # If anything changes in the parameter tree, print a message def change(self, panel, changes): for param, change, data in changes: path = panel.childPath(param) if self.parent.args.v >= 1: print(' path: %s' % path) print(' change: %s' % change) print(' data: %s' % str(data)) print(' ----------') self.paramUpdate(path, change, data) ############################## # Mandatory parameter update # ############################## def paramUpdate(self, path, change, data): if path[0] == self.hitParam_grp: if path[1] == self.hitParam_algorithm_str: self.algInitDone = False self.updateAlgorithm(data) elif path[1] == self.hitParam_showPeaks_str: self.showPeaks = data self.drawPeaks() elif path[1] == self.hitParam_outDir_str: self.hitParam_outDir = data self.hitParam_outDir_overridden = True elif path[1] == self.hitParam_runs_str: self.hitParam_runs = data elif path[1] == self.hitParam_queue_str: self.hitParam_queue = data elif path[1] == self.hitParam_cpu_str: self.hitParam_cpus = data elif path[1] == self.hitParam_noe_str: self.hitParam_noe = data elif path[1] == self.hitParam_threshold_str: self.hitParam_threshold = data elif path[1] == self.hitParam_launch_str: self.findPeaks() elif path[1] == self.save_minPeaks_str: self.minPeaks = data elif path[1] == self.save_maxPeaks_str: self.maxPeaks = data elif path[1] == self.save_minRes_str: self.minRes = data elif path[1] == self.save_sample_str: self.sample = data elif path[1] == self.hitParam_extra_str: self.hitParam_extra = data elif path[2] == self.hitParam_alg1_npix_min_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_npix_min = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_npix_max_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_npix_max = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_amax_thr_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_amax_thr = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_atot_thr_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_atot_thr = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_son_min_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_son_min = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_thr_low_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_thr_low = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_thr_high_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_thr_high = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_rank_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_rank = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_radius_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_radius = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() elif path[2] == self.hitParam_alg1_dr_str and path[1] == self.hitParam_algorithm1_str: self.hitParam_alg1_dr = data self.algInitDone = False self.userUpdate = True if self.showPeaks and self.doingUpdate is False: self.updateClassification() def updateAlgorithm(self, data): self.algorithm = data self.algInitDone = False self.updateClassification() if self.parent.args.v >= 1: print "##### Done updateAlgorithm: ", self.algorithm def saveCheetahFormat(self, arg): if arg == 'lcls': if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName: dim0 = 8 * 185 dim1 = 4 * 388 elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName: dim0 = 1920 #FIXME: rayonix can be binned dim1 = 1920 elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName: dim0 = 1920 #FIXME: rayonix can be binned dim1 = 1920 else: dim0 = 0 dim1 = 0 if dim0 > 0: maxNumPeaks = 2048 if self.parent.index.hiddenCXI is not None: myHdf5 = h5py.File(self.parent.index.hiddenCXI, 'w') grpName = "/entry_1/result_1" dset_nPeaks = "/nPeaks" dset_posX = "/peakXPosRaw" dset_posY = "/peakYPosRaw" dset_atot = "/peakTotalIntensity" if grpName in myHdf5: del myHdf5[grpName] grp = myHdf5.create_group(grpName) myHdf5.create_dataset(grpName + dset_nPeaks, (1,), dtype='int') myHdf5.create_dataset(grpName + dset_posX, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks)) myHdf5.create_dataset(grpName + dset_posY, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks)) myHdf5.create_dataset(grpName + dset_atot, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks)) myHdf5.create_dataset("/LCLS/detector_1/EncoderValue", (1,), dtype=float) myHdf5.create_dataset("/LCLS/photon_energy_eV", (1,), dtype=float) dset = myHdf5.create_dataset("/entry_1/data_1/data", (1, dim0, dim1), dtype=float) # Convert calib image to cheetah image img = np.zeros((dim0, dim1)) counter = 0 if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName: for quad in range(4): for seg in range(8): img[seg * 185:(seg + 1) * 185, quad * 388:(quad + 1) * 388] = self.parent.calib[counter, :, :] counter += 1 elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName: img = self.parent.calib[:, :] # psana format elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName: img = self.parent.calib[:, :] # psana format else: print "saveCheetahFormat not implemented" peaks = self.peaks.copy() nPeaks = peaks.shape[0] if nPeaks > maxNumPeaks: peaks = peaks[:maxNumPeaks] nPeaks = maxNumPeaks for i, peak in enumerate(peaks): seg, row, col, npix, amax, atot, rcent, ccent, rsigma, csigma, rmin, rmax, cmin, cmax, bkgd, rms, son = peak[0:17] if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName: cheetahRow, cheetahCol = self.convert_peaks_to_cheetah(seg, row, col) myHdf5[grpName + dset_posX][0, i] = cheetahCol myHdf5[grpName + dset_posY][0, i] = cheetahRow myHdf5[grpName + dset_atot][0, i] = atot elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName: myHdf5[grpName + dset_posX][0, i] = col myHdf5[grpName + dset_posY][0, i] = row myHdf5[grpName + dset_atot][0, i] = atot elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName: myHdf5[grpName + dset_posX][0, i] = col myHdf5[grpName + dset_posY][0, i] = row myHdf5[grpName + dset_atot][0, i] = atot myHdf5[grpName + dset_nPeaks][0] = nPeaks if self.parent.args.v >= 1: print "hiddenCXI clen (mm): ", self.parent.clen * 1000. myHdf5["/LCLS/detector_1/EncoderValue"][0] = self.parent.clen * 1000. # mm myHdf5["/LCLS/photon_energy_eV"][0] = self.parent.photonEnergy dset[0, :, :] = img myHdf5.close() def updateClassification(self): if self.parent.calib is not None: if self.parent.mk.streakMaskOn: self.parent.mk.initMask() self.parent.mk.streakMask = self.parent.mk.StreakMask.getStreakMaskCalib(self.parent.evt) if self.parent.mk.streakMask is None: self.parent.mk.streakMaskAssem = None else: self.parent.mk.streakMaskAssem = self.parent.det.image(self.parent.evt, self.parent.mk.streakMask) self.algInitDone = False self.parent.mk.displayMask() # update combined mask self.parent.mk.combinedMask = np.ones_like(self.parent.calib) if self.parent.mk.streakMask is not None and self.parent.mk.streakMaskOn is True: self.parent.mk.combinedMask *= self.parent.mk.streakMask if self.parent.mk.userMask is not None and self.parent.mk.userMaskOn is True: self.parent.mk.combinedMask *= self.parent.mk.userMask if self.parent.mk.psanaMask is not None and self.parent.mk.psanaMaskOn is True: self.parent.mk.combinedMask *= self.parent.mk.psanaMask # Peak output (0-16): # 0 seg # 1 row # 2 col # 3 npix: no. of pixels in the ROI intensities above threshold # 4 amp_max: max intensity # 5 amp_tot: sum of intensities # 6,7: row_cgrav: center of mass # 8,9: row_sigma # 10,11,12,13: minimum bounding box # 14: background # 15: noise # 16: signal over noise if self.algorithm == 0: # No peak algorithm self.peaks = None self.drawPeaks() else: # Only initialize the hit finder algorithm once if self.algInitDone is False: self.windows = None self.alg = [] self.alg = PyAlgos(windows=self.windows, mask=self.parent.mk.combinedMask, pbits=0) # set peak-selector parameters: if self.algorithm == 1: self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg1_npix_min, npix_max=self.hitParam_alg1_npix_max, \ amax_thr=self.hitParam_alg1_amax_thr, atot_thr=self.hitParam_alg1_atot_thr, \ son_min=self.hitParam_alg1_son_min) elif self.algorithm == 2: self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg2_npix_min, npix_max=self.hitParam_alg2_npix_max, \ amax_thr=self.hitParam_alg2_amax_thr, atot_thr=self.hitParam_alg2_atot_thr, \ son_min=self.hitParam_alg2_son_min) elif self.algorithm == 3: self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg3_npix_min, npix_max=self.hitParam_alg3_npix_max, \ amax_thr=self.hitParam_alg3_amax_thr, atot_thr=self.hitParam_alg3_atot_thr, \ son_min=self.hitParam_alg3_son_min) elif self.algorithm == 4: self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg4_npix_min, npix_max=self.hitParam_alg4_npix_max, \ amax_thr=self.hitParam_alg4_amax_thr, atot_thr=self.hitParam_alg4_atot_thr, \ son_min=self.hitParam_alg4_son_min) self.algInitDone = True self.parent.calib = self.parent.calib * 1.0 # Neccessary when int is returned if self.algorithm == 1: # v1 - aka Droplet Finder - two-threshold peak-finding algorithm in restricted region # around pixel with maximal intensity. self.peakRadius = int(self.hitParam_alg1_radius) self.peaks = self.alg.peak_finder_v4r2(self.parent.calib, thr_low=self.hitParam_alg1_thr_low, thr_high=self.hitParam_alg1_thr_high, rank=int(self.hitParam_alg1_rank), r0=self.peakRadius, dr=self.hitParam_alg1_dr) elif self.algorithm == 2: # v2 - define peaks for regions of connected pixels above threshold self.peakRadius = int(self.hitParam_alg2_r0) self.peaks = self.alg.peak_finder_v2(self.parent.calib, thr=self.hitParam_alg2_thr, r0=self.peakRadius, dr=self.hitParam_alg2_dr) elif self.algorithm == 3: self.peakRadius = int(self.hitParam_alg3_r0) self.peaks = self.alg.peak_finder_v3(self.parent.calib, rank=self.hitParam_alg3_rank, r0=self.peakRadius, dr=self.hitParam_alg3_dr) elif self.algorithm == 4: # v4 - aka Droplet Finder - the same as v1, but uses rank and r0 parameters in stead of common radius. self.peakRadius = int(self.hitParam_alg4_r0) self.peaks = self.alg.peak_finder_v4(self.parent.calib, thr_low=self.hitParam_alg4_thr_low, thr_high=self.hitParam_alg4_thr_high, rank=self.hitParam_alg4_rank, r0=self.peakRadius, dr=self.hitParam_alg4_dr) self.numPeaksFound = self.peaks.shape[0] if self.parent.args.v >= 1: print "Num peaks found: ", self.numPeaksFound, self.peaks.shape # update clen self.parent.geom.updateClen('lcls') self.parent.index.clearIndexedPeaks() # Save image and peaks in cheetah cxi file self.saveCheetahFormat('lcls') if self.parent.index.showIndexedPeaks: self.parent.index.updateIndex() self.drawPeaks() if self.parent.args.v >= 1: print "Done updateClassification" def convert_peaks_to_cheetah(self, s, r, c) : """Converts seg, row, col assuming (32,185,388) to cheetah 2-d table row and col (8*185, 4*388) """ segs, rows, cols = (32,185,388) row2d = (int(s)%8) * rows + int(r) # where s%8 is a segment in quad number [0,7] col2d = (int(s)/8) * cols + int(c) # where s/8 is a quad number [0,3] return row2d, col2d def getMaxRes(self, posX, posY, centerX, centerY): maxRes = np.max(np.sqrt((posX-centerX)**2 + (posY-centerY)**2)) if self.parent.args.v >= 1: print "maxRes: ", maxRes return maxRes # in pixels def drawPeaks(self): self.parent.img.clearPeakMessage() if self.showPeaks: if self.peaks is not None and self.numPeaksFound > 0: self.ix = self.parent.det.indexes_x(self.parent.evt) self.iy = self.parent.det.indexes_y(self.parent.evt) if self.ix is None: (_, dim0, dim1) = self.parent.calib.shape self.iy = np.tile(np.arange(dim0),[dim1, 1]) self.ix = np.transpose(self.iy) self.iX = np.array(self.ix, dtype=np.int64) self.iY = np.array(self.iy, dtype=np.int64) if len(self.iX.shape)==2: self.iX = np.expand_dims(self.iX,axis=0) self.iY = np.expand_dims(self.iY,axis=0) cenX = self.iX[np.array(self.peaks[:,0],dtype=np.int64),np.array(self.peaks[:,1],dtype=np.int64),np.array(self.peaks[:,2],dtype=np.int64)] + 0.5 cenY = self.iY[np.array(self.peaks[:,0],dtype=np.int64),np.array(self.peaks[:,1],dtype=np.int64),np.array(self.peaks[:,2],dtype=np.int64)] + 0.5 self.peaksMaxRes = self.getMaxRes(cenX, cenY, self.parent.cx, self.parent.cy) diameter = self.peakRadius*2+1 self.parent.img.peak_feature.setData(cenX, cenY, symbol='s', \ size=diameter, brush=(255,255,255,0), \ pen=pg.mkPen({'color': "c", 'width': 4}), pxMode=False) #FF0 # Write number of peaks found xMargin = 5 # pixels yMargin = 0 # pixels maxX = np.max(self.ix) + xMargin maxY = np.max(self.iy) - yMargin myMessage = '<div style="text-align: center"><span style="color: cyan; font-size: 12pt;">Peaks=' + \ str(self.numPeaksFound) + ' <br>Res=' + str(int(self.peaksMaxRes)) + '<br></span></div>' self.parent.img.peak_text = pg.TextItem(html=myMessage, anchor=(0, 0)) self.parent.img.w1.getView().addItem(self.parent.img.peak_text) self.parent.img.peak_text.setPos(maxX, maxY) else: self.parent.img.peak_feature.setData([], [], pxMode=False) self.parent.img.peak_text = pg.TextItem(html='', anchor=(0, 0)) self.parent.img.w1.getView().addItem(self.parent.img.peak_text) self.parent.img.peak_text.setPos(0,0) else: self.parent.img.peak_feature.setData([], [], pxMode=False) if self.parent.args.v >= 1: print "Done updatePeaks"
class ROIManager(QObject): ROI_changed = pyqtSignal() ROI_changed_finished = pyqtSignal() new_ROI_signal = pyqtSignal(int, str) remove_ROI_signal = pyqtSignal(str) roi_settings_changed = pyqtSignal(list) roi_update_children = pyqtSignal(list) color_list = np.array(plot_colors) def __init__(self, viewer_widget=None, ROI_type='1D'): super().__init__() self.ROI_type = ROI_type self.roiwidget = QtWidgets.QWidget() self.viewer_widget = viewer_widget # either a PlotWidget or a ImageWidget self.ROIs = OrderedDict([]) self.setupUI() def setupUI(self): vlayout = QtWidgets.QVBoxLayout() self.roiwidget.setLayout(vlayout) horwidget = QtWidgets.QWidget() horlayout = QtWidgets.QHBoxLayout() horwidget.setLayout(horlayout) self.save_ROI_pb = QtWidgets.QPushButton('Save ROIs') self.load_ROI_pb = QtWidgets.QPushButton('Load ROIs') self.clear_ROI_pb = QtWidgets.QPushButton('Clear ROIs') horlayout.addWidget(self.save_ROI_pb) horlayout.addWidget(self.load_ROI_pb) horlayout.addWidget(self.clear_ROI_pb) vlayout.addWidget(horwidget) self.roitree = ParameterTree() vlayout.addWidget(self.roitree) self.roiwidget.setMinimumWidth(100) self.roiwidget.setMaximumWidth(300) params = [{ 'title': 'Measurements:', 'name': 'measurements', 'type': 'table', 'value': OrderedDict([]), 'Ncol': 2, 'header': ["LO", "Value"] }, ROIScalableGroup(roi_type=self.ROI_type, name="ROIs")] self.settings = Parameter.create(title='ROIs Settings', name='rois_settings', type='group', children=params) self.roitree.setParameters(self.settings, showTop=False) self.settings.sigTreeStateChanged.connect(self.roi_tree_changed) self.save_ROI_pb.clicked.connect(self.save_ROI) self.load_ROI_pb.clicked.connect(lambda: self.load_ROI(None)) self.clear_ROI_pb.clicked.connect(self.clear_ROI) def roi_tree_changed(self, param, changes): for param, change, data in changes: path = self.settings.childPath(param) if path is not None: childName = '.'.join(path) else: childName = param.name() if change == 'childAdded': # new roi to create par = data[0] newindex = int(par.name()[-2:]) if par.child(('type')).value() == '1D': roi_type = '' pos = self.viewer_widget.plotItem.vb.viewRange()[0] newroi = LinearROI(index=newindex, pos=pos) newroi.setZValue(-10) newroi.setBrush(par.child(('Color')).value()) newroi.setOpacity(0.2) elif par.child(('type')).value() == '2D': roi_type = par.child(('roi_type')).value() xrange = self.viewer_widget.plotItem.vb.viewRange()[0] yrange = self.viewer_widget.plotItem.vb.viewRange()[1] width = np.max(((xrange[1] - xrange[0]) / 10, 2)) height = np.max(((yrange[1] - yrange[0]) / 10, 2)) pos = [ int(np.mean(xrange) - width / 2), int(np.mean(yrange) - width / 2) ] if roi_type == 'RectROI': newroi = RectROI(index=newindex, pos=pos, size=[width, height]) else: newroi = EllipseROI(index=newindex, pos=pos, size=[width, height]) newroi.setPen(par.child(('Color')).value()) newroi.sigRegionChanged.connect(self.ROI_changed.emit) newroi.sigRegionChangeFinished.connect( self.ROI_changed_finished.emit) newroi.index_signal[int].connect(self.update_roi_tree) try: self.settings.sigTreeStateChanged.disconnect() except Exception: pass self.settings.sigTreeStateChanged.connect( self.roi_tree_changed) self.viewer_widget.plotItem.addItem(newroi) self.ROIs["ROI_%02.0d" % newindex] = newroi self.new_ROI_signal.emit(newindex, roi_type) self.update_roi_tree(newindex) elif change == 'value': if param.name() in putils.iter_children( self.settings.child(('ROIs')), []): if param.name() == 'Color' or param.name() == 'angle': parent = param.parent().name() else: parent = param.parent().parent().name() self.update_roi(parent, param) elif change == 'parent': if 'ROI' in param.name(): roi = self.ROIs.pop(param.name()) self.viewer_widget.plotItem.removeItem(roi) self.remove_ROI_signal.emit(param.name()) if param.name() != 'measurements': self.roi_settings_changed.emit([(param, 'value', param.value()) ]) self.ROI_changed_finished.emit() def update_roi(self, roi_key, param): if param.name() == 'Color': self.ROIs[roi_key].setPen(param.value()) elif param.name() == 'left' or param.name() == 'x': pos = self.ROIs[roi_key].pos() poss = [param.value(), pos[1]] poss.sort() self.ROIs[roi_key].setPos(poss) elif param.name() == 'right' or param.name() == 'y': pos = self.ROIs[roi_key].pos() poss = [pos[0], param.value()] poss.sort() self.ROIs[roi_key].setPos(poss) elif param.name() == 'angle': self.ROIs[roi_key].setAngle(param.value()) elif param.name() == 'width': size = self.ROIs[roi_key].size() self.ROIs[roi_key].setSize((param.value(), size[1])) elif param.name() == 'height': size = self.ROIs[roi_key].size() self.ROIs[roi_key].setSize((size[0], param.value())) @pyqtSlot(int) def update_roi_tree(self, index): roi = self.ROIs['ROI_%02.0d' % index] par = self.settings.child(*('ROIs', 'ROI_%02.0d' % index)) if isinstance(roi, LinearROI): pos = roi.getRegion() else: pos = roi.pos() size = roi.size() angle = roi.angle() try: self.settings.sigTreeStateChanged.disconnect() except Exception: pass if isinstance(roi, LinearROI): par.child(*('position', 'left')).setValue(pos[0]) par.child(*('position', 'right')).setValue(pos[1]) if not isinstance(roi, LinearROI): par.child(*('position', 'x')).setValue(pos[0]) par.child(*('position', 'y')).setValue(pos[1]) par.child(*('size', 'width')).setValue(size[0]) par.child(*('size', 'height')).setValue(size[1]) par.child('angle').setValue(angle) self.settings.sigTreeStateChanged.connect(self.roi_tree_changed) def save_ROI(self): try: data = ioxml.parameter_to_xml_string(self.settings.child(('ROIs'))) path = select_file(start_path=Path.home(), ext='xml') if path != '': with open(path, 'wb') as f: f.write(data) except Exception as e: print(e) def clear_ROI(self): indexes = [roi.index for roi in self.ROIs.values()] for index in indexes: self.settings.child(*('ROIs', 'ROI_%02.0d' % index)).remove() # self.settings.sigTreeStateChanged.connect(self.roi_tree_changed) def load_ROI(self, path=None, params=None): try: if params is None: if path is None: path = select_file(start_path=Path.home(), save=False, ext='xml') if path != '': params = Parameter.create( title='Settings', name='settings', type='group', children=ioxml.XML_file_to_parameter(path)) if params is not None: self.clear_ROI() QtWidgets.QApplication.processEvents() for param in params: if 'roi_type' in putils.iter_children(param, []): self.settings.child(('ROIs')).addNew( param.child(('roi_type')).value()) else: self.settings.child(('ROIs')).addNew() # self.settings.child(('ROIs')).addChildren(params) QtWidgets.QApplication.processEvents() # settings = Parameter.create(title='Settings', name='settings', type='group') # # for param in params: # settings.addChildren(custom_tree.XML_string_to_parameter(custom_tree.parameter_to_xml_string(param))) self.set_roi(self.settings.child(('ROIs')).children(), params) except Exception as e: pass def set_roi(self, roi_params, roi_params_new): for child, new_child in zip(roi_params, roi_params_new): if 'group' not in child.opts['type']: child.setValue(new_child.value()) else: self.set_roi(child.children(), new_child.children())
class View(QtGui.QWidget): def __init__(self, parent=None, with_config=False, **kargs): QtGui.QWidget.__init__(self, parent) self.resize(800, 600) mainlayout = QtGui.QVBoxLayout() self.setLayout(mainlayout) self.glview = gl.GLViewWidget() mainlayout.addWidget(self.glview) self.glview.setCameraPosition(160, 160, 15) if with_config: h = QtGui.QHBoxLayout() mainlayout.addLayout(h) but = QtGui.QPushButton('Config', icon=QtGui.QIcon.fromTheme('configure')) h.addWidget(but) but.clicked.connect(self.open_params) but = QtGui.QPushButton('Save png', icon=QtGui.QIcon.fromTheme('save')) h.addWidget(but) but.clicked.connect(self.open_save_dialog) _params = [ { 'name': 'cortical_mesh', 'type': 'list', 'values': cortical_meshes.keys(), 'value': 'BrainMesh_ICBM152' }, { 'name': 'cortical_alpha', 'type': 'float', 'value': .1, 'limits': [0., 1.], 'step': .01 }, { 'name': 'cortical_color', 'type': 'color', 'value': 'w' }, { 'name': 'background_color', 'type': 'color', 'value': 'k' }, ] self.params = Parameter.create(name='params', type='group', children=_params) self.tree = ParameterTree(parent=self) self.tree.setParameters(self.params) self.tree.setWindowFlags(QtCore.Qt.Dialog) self.mesh = None for k, v in kargs.items(): self.params[k] = v self.change_background_color() self.plot_mesh() self.change_color_mesh() self.params.param('cortical_mesh').sigValueChanged.connect( self.plot_mesh) self.params.param('cortical_alpha').sigValueChanged.connect( self.change_color_mesh) self.params.param('cortical_color').sigValueChanged.connect( self.change_color_mesh) self.params.param('background_color').sigValueChanged.connect( self.change_background_color) self.glview.resizeGL(self.glview.width(), self.glview.height()) def open_params(self): self.tree.show() def change_background_color(self): background_color = self.params['background_color'] try: self.glview.setBackgroundColor(background_color) except: #~ #FIXME this is buggy in pyqtgrap0.9.8 bgcolor = pg.mkColor(QtGui.QColor(background_color)) glClearColor(bgcolor.red() / 255., bgcolor.green() / 255., bgcolor.blue() / 255., 1.0) glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT) self.glview.paintGL() self.glview.update() def plot_mesh(self): vertexes, faces = cortical_meshes[self.params['cortical_mesh']] alpha = self.params['cortical_alpha'] c = self.params['cortical_color'] color = (c.red() / 255., c.green() / 255., c.blue() / 255., alpha) if self.mesh is None: self.mesh = gl.GLMeshItem( vertexes=vertexes, faces=faces, smooth=True, drawFaces=True, drawEdges=False, edgeColor=(1., 1., 1., .2), color=color, computeNormals=False, glOptions='translucent', #~ shader='balloon', shader='shaded', ) self.glview.addItem(self.mesh) else: self.mesh.setMeshData(vertexes=vertexes, faces=faces) #~ self.mesh.set def change_color_mesh(self): alpha = self.params['cortical_alpha'] c = self.params['cortical_color'] color = (c.red() / 255., c.green() / 255., c.blue() / 255., alpha) self.mesh.setColor(color) def add_node(self, coords, color=(1, 1, 1, 0), size=5): sp1 = gl.GLScatterPlotItem(pos=coords, size=size, color=color, pxMode=False) self.glview.addItem(sp1) def add_edge(self, node_coords, connection_with, color=(1, 1, 1, 1)): for i in range(connection_with.shape[0]): for j in range(connection_with.shape[1]): if connection_with[i, j] == 0: continue plt = gl.GLLinePlotItem(pos=np.vstack( [node_coords[i], node_coords[j]]), color=color, width=connection_with[i, j]) self.glview.addItem(plt) def open_save_dialog(self): pathname = unicode( QtGui.QDesktopServices.storageLocation( QtGui.QDesktopServices.DesktopLocation)) filename = os.path.join(pathname, 'Il est beau le cerveau.png') filename = QtGui.QFileDialog.getSaveFileName(self, u'Save png', filename, 'PNG (*.png)') if filename: self.to_file(filename) def to_file(self, filename): self.glview.readQImage().save(filename)
class MainWindow(Qt.QWidget): ''' Main Window ''' def __init__(self): super(MainWindow, self).__init__() layout = Qt.QVBoxLayout(self) self.btnGen = Qt.QPushButton("Start Gen!") layout.addWidget(self.btnGen) self.StateParams = FileMod.SaveSateParameters(QTparent=self, name='State') self.Parameters = Parameter.create(name='params', type='group', children=(self.StateParams, )) self.NifGenParams = FMacq.NifGeneratorParameters(name='NifGenerator') self.Parameters.addChild(self.NifGenParams) self.NiScopeParams = FMacq.NiScopeParameters(name='Scope') self.Parameters.addChild(self.NiScopeParams) # self.FileParameters = FileMod.SaveFileParameters(QTparent=self, name='Record File') self.Parameters.addChild(self.FileParameters) self.PSDParams = PltMod.PSDParameters(name='PSD Options') self.PSDParams.param('Fs').setValue(self.NifGenParams.Fs.value()) self.PSDParams.param('Fmin').setValue(50) self.PSDParams.param('nAvg').setValue(50) self.PSDEnable = self.PSDParams.param('PSDEnable').value() self.Parameters.addChild(self.PSDParams) self.PlotParams = PltMod.PlotterParameters(name='Plot options') self.PlotParams.SetChannels(self.NiScopeParams.GetChannels()) self.PlotParams.param('Fs').setValue(self.NifGenParams.Fs.value()) self.PltEnable = self.PlotParams.param('PlotEnable').value() self.Parameters.addChild(self.PlotParams) self.Parameters.sigTreeStateChanged.connect(self.on_pars_changed) self.treepar = ParameterTree() self.treepar.setParameters(self.Parameters, showTop=False) self.treepar.setWindowTitle('pyqtgraph example: Parameter Tree') layout.addWidget(self.treepar) self.setGeometry(550, 10, 300, 700) self.setWindowTitle('MainWindow') self.btnGen.clicked.connect(self.on_btnGen) self.threadAqc = None self.threadSave = None self.threadPlotter = None self.threadPSDPlotter = None def on_pars_changed(self, param, changes): print("tree changes:") for param, change, data in changes: path = self.Parameters.childPath(param) if path is not None: childName = '.'.join(path) else: childName = param.name() print(' parameter: %s' % childName) print(' change: %s' % change) print(' data: %s' % str(data)) print(' ----------') if childName == 'NifGenerator.SamplingConfig.Fs': self.NiScopeParams.Fs.setValue(data) self.PlotParams.param('Fs').setValue(data) self.PSDParams.param('Fs').setValue(data) if childName == 'Scope.FetchConfig.NRow': self.PlotParams.SetChannels(self.NiScopeParams.GetChannels()) if childName == 'Plot options.RefreshTime': if self.threadPlotter is not None: self.threadPlotter.SetRefreshTime(data) if childName == 'Plot options.ViewTime': if self.threadPlotter is not None: self.threadPlotter.SetViewTime(data) if childName == 'Plot options.PlotEnable': self.PltEnable = data if self.threadAqc is not None: self.UpdatePlots() if childName == 'PSD Options.PSDEnable': self.PSDEnable = data if self.threadAqc is not None: self.UpdatePlots() def on_btnGen(self): print('h') if self.threadAqc is None: self.GenKwargs = self.NifGenParams.GetParams() self.ScopeKwargs = self.NiScopeParams.GetParams() self.threadAqc = FMacq.DataAcquisitionThread( **self.GenKwargs, **self.ScopeKwargs) self.threadAqc.NewData.connect(self.on_NewSample) self.SaveFiles() self.GenPlots() self.threadAqc.start() self.btnGen.setText("Stop Gen") self.OldTime = time.time() else: self.threadAqc.NewData.disconnect() self.threadAqc.stopSessions() self.threadAqc.terminate() self.threadAqc = None if self.threadSave is not None: self.threadSave.stop() self.threadSave = None self.DestroyPlotter() self.DestroyPSD() self.btnGen.setText("Start Gen") def on_NewSample(self): ''' Visualization of streaming data-WorkThread. ''' Ts = time.time() - self.OldTime self.OldTime = time.time() if self.threadSave is not None: self.threadSave.AddData(self.threadAqc.IntData) if self.threadPlotter is not None: self.threadPlotter.AddData(self.threadAqc.OutData) if self.threadPSDPlotter is not None: self.threadPSDPlotter.AddData(self.threadAqc.OutData) print('Sample time', Ts) def GenPlots(self): PlotterKwargs = self.PlotParams.GetParams() ScopeKwargs = self.NiScopeParams.GetParams() if self.threadPlotter is None: if self.PltEnable == True: self.threadPlotter = PltMod.Plotter(**PlotterKwargs) self.threadPlotter.start() if self.threadPSDPlotter is None: if self.PSDEnable == True: self.threadPSDPlotter = PltMod.PSDPlotter( ChannelConf=PlotterKwargs['ChannelConf'], nChannels=ScopeKwargs['NRow'], **self.PSDParams.GetParams()) self.threadPSDPlotter.start() def DestroyPlotter(self): if self.threadPlotter is not None: self.threadPlotter.stop() self.threadPlotter = None def DestroyPSD(self): if self.threadPSDPlotter is not None: self.threadPSDPlotter.stop() self.threadPSDPlotter = None def UpdatePlots(self): if self.PltEnable == False: self.DestroyPlotter() if self.PSDEnable == False: self.DestroyPSD() else: self.GenPlots() def SaveFiles(self): FileName = self.FileParameters.param('File Path').value() if FileName == '': print('No file') else: if os.path.isfile(FileName): print('Remove File') os.remove(FileName) MaxSize = self.FileParameters.param('MaxSize').value() self.threadSave = FileMod.DataSavingThread( FileName=FileName, nChannels=self.ScopeKwargs['NRow'], MaxSize=MaxSize) self.threadSave.start() GenName = FileName + '_GenConfig.dat' ScopeName = FileName + '_ScopeConfig.dat' if os.path.isfile(GenName): print('Overwriting file') OutGen = input('y/n + press(Enter)') if OutGen == 'y': self.GenArchivo(GenName, self.GenKwargs) else: self.GenArchivo(GenName, self.GenKwargs) if os.path.isfile(ScopeName): print('Overwriting file') OutScope = input('y/n + press(Enter)') if OutScope == 'y': self.GenArchivo(ScopeName, self.ScopeKwargs) else: self.GenArchivo(ScopeName, self.ScopeKwargs) def GenArchivo(self, name, dic2Save): with open(name, "wb") as f: pickle.dump(dic2Save, f)
def __init__(self, parent=None, with_config=False, **kargs): QtGui.QWidget.__init__(self, parent) self.resize(800, 600) mainlayout = QtGui.QVBoxLayout() self.setLayout(mainlayout) self.glview = gl.GLViewWidget() mainlayout.addWidget(self.glview) self.glview.setCameraPosition(160, 160, 15) if with_config: h = QtGui.QHBoxLayout() mainlayout.addLayout(h) but = QtGui.QPushButton('Config', icon=QtGui.QIcon.fromTheme('configure')) h.addWidget(but) but.clicked.connect(self.open_params) but = QtGui.QPushButton('Save png', icon=QtGui.QIcon.fromTheme('save')) h.addWidget(but) but.clicked.connect(self.open_save_dialog) _params = [ { 'name': 'cortical_mesh', 'type': 'list', 'values': cortical_meshes.keys(), 'value': 'BrainMesh_ICBM152' }, { 'name': 'cortical_alpha', 'type': 'float', 'value': .1, 'limits': [0., 1.], 'step': .01 }, { 'name': 'cortical_color', 'type': 'color', 'value': 'w' }, { 'name': 'background_color', 'type': 'color', 'value': 'k' }, ] self.params = Parameter.create(name='params', type='group', children=_params) self.tree = ParameterTree(parent=self) self.tree.setParameters(self.params) self.tree.setWindowFlags(QtCore.Qt.Dialog) self.mesh = None for k, v in kargs.items(): self.params[k] = v self.change_background_color() self.plot_mesh() self.change_color_mesh() self.params.param('cortical_mesh').sigValueChanged.connect( self.plot_mesh) self.params.param('cortical_alpha').sigValueChanged.connect( self.change_color_mesh) self.params.param('cortical_color').sigValueChanged.connect( self.change_color_mesh) self.params.param('background_color').sigValueChanged.connect( self.change_background_color) self.glview.resizeGL(self.glview.width(), self.glview.height())
def __init__(self, parent=None): self.parent = parent ## Dock: Hit finder self.dock = Dock("Hit Finder", size=(1, 1)) self.win = ParameterTree() self.dock.addWidget(self.win) self.winL = pg.LayoutWidget() self.dock.addWidget(self.winL) # Hit finding self.spiParam_grp = 'Hit finder' self.spiParam_algorithm_str = 'Algorithm' # algorithm 0 self.spiParam_algorithm0_str = 'None' # algorithm 1 self.spiParam_algorithm1_str = 'chiSquared' self.spiParam_alg1_pruneInterval_str = 'prune interval' # algorithm 2 self.spiParam_algorithm2_str = 'photonFinder' self.spiParam_alg2_threshold_str = 'ADUs per photon' self.spiParam_alg2_hitThreshold_str = 'Number of pixels for a hit' self.spiParam_outDir_str = 'Output directory' self.spiParam_runs_str = 'Run(s)' self.spiParam_queue_str = 'queue' self.spiParam_cpu_str = 'CPUs' self.spiParam_psanaq_str = 'psanaq' self.spiParam_psnehq_str = 'psnehq' self.spiParam_psfehq_str = 'psfehq' self.spiParam_psnehprioq_str = 'psnehprioq' self.spiParam_psfehprioq_str = 'psfehprioq' self.spiParam_psnehhiprioq_str = 'psnehhiprioq' self.spiParam_psfehhiprioq_str = 'psfehhiprioq' self.spiParam_psdebugq_str = 'psdebugq' self.spiParam_noe_str = 'Number of events to process' self.spiParam_launch_str = 'Launch hit finder' self.hitParam_grp = 'Find hits' self.hitParam_hitThresh_str = 'Hit threshold' self.hitParam_backgroundThresh_str = 'Background threshold' self.hitParam_sample_str = 'Sample name' self.hitParam_save_str = 'Save hits' # Init hit finding self.nPixels = 0 self.spiAlgorithm = 2 self.spiParam_alg1_pruneInterval = -1 self.spiParam_alg2_threshold = 30 self.spiParam_outDir = self.parent.psocakeDir self.spiParam_outDir_overridden = False self.spiParam_runs = '' self.spiParam_queue = self.spiParam_psanaq_str self.spiParam_cpus = 24 self.spiParam_noe = -1 self.hitParam_hitThresh = '-1' self.hitParam_backgroundThresh = '-1' self.hitParam_sample = "sample" self.params = [ { 'name': self.spiParam_grp, 'type': 'group', 'children': [ { 'name': self.spiParam_algorithm_str, 'type': 'list', 'values': { self.spiParam_algorithm2_str: 2, self.spiParam_algorithm0_str: 0 }, 'value': self.spiAlgorithm }, #{'name': self.spiParam_algorithm1_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "", # 'readonly': True, 'children': [ # {'name': self.spiParam_alg1_pruneInterval_str, 'type': 'float', 'value': self.spiParam_alg1_pruneInterval, # 'tip': "update running background"}, #]}, { 'name': self.spiParam_algorithm2_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "", 'readonly': True, 'children': [ { 'name': self.spiParam_alg2_threshold_str, 'type': 'float', 'value': self.spiParam_alg2_threshold, 'tip': "search for pixels above ADU per photon" }, ] }, { 'name': self.spiParam_outDir_str, 'type': 'str', 'value': self.spiParam_outDir }, { 'name': self.spiParam_runs_str, 'type': 'str', 'value': self.spiParam_runs, 'tip': "comma separated or use colon for a range, e.g. 1,3,5:7 = runs 1,3,5,6,7" }, { 'name': self.spiParam_queue_str, 'type': 'list', 'values': { self.spiParam_psfehhiprioq_str: 'psfehhiprioq', self.spiParam_psnehhiprioq_str: 'psnehhiprioq', self.spiParam_psfehprioq_str: 'psfehprioq', self.spiParam_psnehprioq_str: 'psnehprioq', self.spiParam_psfehq_str: 'psfehq', self.spiParam_psnehq_str: 'psnehq', self.spiParam_psanaq_str: 'psanaq', self.spiParam_psdebugq_str: 'psdebugq' }, 'value': self.spiParam_queue, 'tip': "Choose queue" }, { 'name': self.spiParam_cpu_str, 'type': 'int', 'value': self.spiParam_cpus }, { 'name': self.spiParam_noe_str, 'type': 'int', 'value': self.spiParam_noe, 'tip': "number of events to process, default=0 means process all events" }, { 'name': self.spiParam_launch_str, 'type': 'action' }, ] }, { 'name': self.hitParam_grp, 'type': 'group', 'children': [ { 'name': self.hitParam_hitThresh_str, 'type': 'str', 'value': self.hitParam_hitThresh, 'tip': "Set as hit if number of pixels with photons above this value. Or specify a range using a colon, e.g. 100:10000." }, { 'name': self.hitParam_backgroundThresh_str, 'type': 'str', 'value': self.hitParam_backgroundThresh, 'tip': "Use as background if number of pixels with photons below this value. Or specify a range using a colon, e.g. 100:10000." }, { 'name': self.hitParam_sample_str, 'type': 'str', 'value': self.hitParam_sample }, { 'name': self.hitParam_save_str, 'type': 'action' }, ] }, ] self.p8 = Parameter.create(name='paramsHitFinder', type='group', \ children=self.params, expanded=True) self.win.setParameters(self.p8, showTop=False) self.p8.sigTreeStateChanged.connect(self.change)
class RosBagWidget(QtGui.QWidget): ## # @brief # # @return def __init__(self): QtGui.QWidget.__init__(self) self.file_name = '' self.bag = None self.data = {} self.plot_data = {} self.gridLayout = None self.label1 = None self.loadBtn = None self.tree = None self.addBtn = None self.editBtn = None self.removeBtn = None self.plotBtn = None self.plotTree = None self.plotData = None self.plotwin = None self.plot_num = 1 self.params = [{ 'type': 'group', 'name': u'plot params', 'children': [{ 'type': 'str', 'name': 'x axis name', 'value': u'time(s)' }, { 'type': 'str', 'name': 'y axis name', 'value': u'position(m)' }, { 'type': 'str', 'name': 'plot name', 'value': u'plot name' }] }] self.line_mark_list = [ '+-', '*-', 'o-', '^-', 's-', 'x-', '.-', 'p-', 'h-', 'd-' ] self.msg_types = [] self.topics = {} self.topics_data = {} self.msg_types_blacklist = [ 'sensor_msgs/PointCloud', 'sensor_msgs/Image' ] self.setup_ui(self) ## # @brief # # @param Form # # @return def setup_ui(self, Form): self.setObjectName("Form") self.resize(217, 499) self.gridLayout = QtGui.QGridLayout(self) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setVerticalSpacing(0) self.gridLayout.setObjectName("gridLayout") self.label1 = QtGui.QLabel("") self.label1.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction) self.label1.setStyleSheet("border:1px solid black;") self.gridLayout.addWidget(self.label1, 0, 0) self.loadBtn = QtGui.QPushButton("...") self.loadBtn.setFixedWidth(20) self.gridLayout.addWidget(self.loadBtn, 0, 1) self.loadBtn.clicked.connect(self.load_file) self.tree = DataTreeWidget(data=self.data) self.gridLayout.addWidget(self.tree, 1, 0, 1, 2) self.addBtn = QtGui.QPushButton("") add_icon = QtGui.QIcon() add_icon.addPixmap(QtGui.QPixmap("resources/add.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.addBtn.setIcon(add_icon) self.addBtn.clicked.connect(self.add_plot) self.gridLayout.addWidget(self.addBtn, 0, 2) self.editBtn = QtGui.QPushButton("") edit_icon = QtGui.QIcon() edit_icon.addPixmap(QtGui.QPixmap("resources/edit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.editBtn.setIcon(edit_icon) self.editBtn.clicked.connect(self.edit_plot) self.gridLayout.addWidget(self.editBtn, 0, 3) self.removeBtn = QtGui.QPushButton("") remove_icon = QtGui.QIcon() remove_icon.addPixmap(QtGui.QPixmap("resources/remove.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.removeBtn.setIcon(remove_icon) self.removeBtn.clicked.connect(self.remove_plot) self.gridLayout.addWidget(self.removeBtn, 0, 4) self.plotBtn = QtGui.QPushButton("plot") # plot_icon = QtGui.QIcon() # plot_icon.addPixmap(QtGui.QPixmap("resources/plot.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) # self.plotBtn.setIcon(plot_icon) self.plotBtn.clicked.connect(self.plot) self.gridLayout.addWidget(self.plotBtn, 0, 5) self.plotTree = ParameterTree() self.plotData = Parameter.create(name='params', type='group', children=self.params) self.plotTree.setParameters(self.plotData, showTop=False) self.gridLayout.addWidget(self.plotTree, 1, 2, 1, 4) # self.tree2.setSizePolicity(self.tree1.width()/2, 499) # self.tree1.resize(setWidth(150) # self.tree2.setWidth(50) self.plotData.sigTreeStateChanged.connect(self.change) ## # @brief # # @param param # @param changes # # @return def change(self, param, changes): # todo change plot params print("tree changes:(to do)") for param, change, data in changes: path = self.plotData.childPath(param) print(path) if path is not None: childName = '.'.join(path) else: childName = param.name() print(' parameter: %s' % childName) print(' change: %s' % change) print(' data: %s' % str(data)) print(' ----------') ## # @brief # # @param file_name # @param start_dir # # @return def load_file(self, file_name=None, start_dir=None): """Load a rosbag (*.bag) file. """ start = time.clock() if not file_name: if not start_dir: start_dir = '.' self.file_dialog = FileDialog(None, "Load rosbag ..", start_dir, "rosbag (*.bag)") # file_dialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) self.file_dialog.show() self.file_dialog.fileSelected.connect(self.load_file) return file_name = unicode(file_name) self.file_name = file_name self.label1.setText(str(file_name)) self.file_info(file_name) end = time.clock() print("load file cost %s s" % (end - start)) ## # @brief # # @param file_name # # @return def file_info(self, file_name=None): if not file_name: self.data = {} else: self.bag = rosbag.Bag(file_name) self.tree.setData(self.bag.get_type_and_topic_info()[1]) # print(self.bag.get_type_and_topic_info()[1]) bag_length = self.get_bag_length( self.bag.get_type_and_topic_info()[1]) * 10 if len(file_name) * 8 > bag_length: bag_length = len(file_name) * 8 self.label1.setFixedWidth(bag_length) # clear data self.msg_types = [] self.topics = {} self.topics_data = {} # print(self.get_bag_length(self.bag.get_type_and_topic_info()[1])) for m in self.bag.get_type_and_topic_info()[0]: self.msg_types.append(m) for t in self.bag.get_type_and_topic_info()[1]: if self.bag.get_type_and_topic_info( )[1][t][0] not in self.msg_types_blacklist: get_topic_params_cmd = "rostopic echo -b " + file_name + " -n 1 -p " + t topic_parms = os.popen(get_topic_params_cmd).read() topic_parms_list = self.topic_str2list(topic_parms) self.topics[t] = topic_parms_list get_topic_data_cmd = "rostopic echo -b " + self.file_name + " -p " + t topic_data = os.popen(get_topic_data_cmd).read() topic_data_list = self.topic_data_str2list(topic_data[:-1]) self.topics_data[t] = topic_data_list else: print(t + "is not proper for plot") # print("topic_data_list", topic_data_list) # break @staticmethod ## # @brief # # @param data # # @return def get_bag_length(data): max_topic_len = 0 max_topic_type_len = 0 for topic in data: if len(topic) > max_topic_len: max_topic_len = len(topic) if len(data[topic][0]) > max_topic_type_len: max_topic_type_len = len(data[topic][0]) # print(max_topic_len, max_topic_type_len) return max_topic_len + max_topic_type_len @staticmethod ## # @brief # # @param topic_str # # @return def topic_str2list(topic_str): # print(len(topic_str)) # print(topic_str) topic_list = [] if len(topic_str) > 0: # print(topic_str[0]) out1 = re.split('\n', topic_str) params = re.split(',', out1[0]) values = re.split(',', out1[1]) # print(len(params), len(values)) for i in range(len(params)): if values[i].strip('-').replace(".", '').isdigit(): topic_list.append(params[i]) # print(topic_list) return topic_list @staticmethod ## # @brief # # @param topic_data_str # # @return def topic_data_str2list(topic_data_str): topic_data_list = [] if len(topic_data_str) > 0: out1 = re.split('\n', topic_data_str) for o in out1: data_list = re.split(',', o) topic_data_list.append(data_list) return topic_data_list ## # @brief # # @return def add_plot(self): if len(self.file_name): #print("add plot") self.plotwin = PlotWin(self.topics, self.plot_num) self.plotwin.setWindowModality(QtCore.Qt.ApplicationModal) self.plotwin.setGeometry(500, 500, 600, 150) if self.plotwin.exec_(): # accepted #print("ok") self.plot_num = self.plot_num + 1 if len(self.plotwin.plot_name.text()) > 0: self.plotwin.param['name'] = unicode( self.plotwin.plot_name.text()) + " " + unicode( self.plotwin.topic_name.currentText()) self.plotwin.param['type'] = 'group' x = { 'name': 'x', 'type': 'str', 'value': unicode(self.plotwin.field1.currentText()) } y = { 'name': 'y', 'type': 'str', 'value': unicode(self.plotwin.field2.currentText()) } color = self.plotwin.colorBtn.color(mode='byte') color_str = '' for i in color[:-1]: c = str(hex(i)).replace("0x", '') if len(c) < 2: c = '0' + c color_str = color_str + c # print(color, color_str) line_color = { 'name': 'line_color', 'type': 'color', 'value': color_str, 'tip': "This is a color button" } line_mark = { 'name': 'line_mark', 'type': 'list', 'values': self.line_mark_list, 'value': unicode(self.plotwin.line_mark.currentText()) } self.plotwin.param['children'] = [ x, y, line_color, line_mark ] self.params.append(self.plotwin.param) self.plotData = Parameter.create( name='params', type='group', children=[self.plotwin.param]) self.plotTree.addParameters(self.plotData, showTop=False) else: print("Please input the plot name first.") else: print("cancel") else: print("Please add bag file first!") ## # @brief # # @return def edit_plot(self): # print("edit plot", self.plotTree.selectedItems(), self.plotTree.currentItem()) if hasattr(self.plotTree.currentItem(), "param"): print("edit plot " + re.split( '\'', str(getattr(self.plotTree.currentItem(), "param")))[1] + "(to do)") # if hasattr(getattr(self.plotTree.currentItem(), "param"), "name"): # print(getattr(getattr(self.plotTree.currentItem(), "param"), "name")) # print("%x" % id(self.params[0])) ## # @brief # # @return def remove_plot(self): if hasattr(self.plotTree.currentItem(), "param"): print("remove plot " + re.split( '\'', str(getattr(self.plotTree.currentItem(), "param")))[1] + "(to do)") ## # @brief # # @return def plot(self): print("plot") plots = [] for p in self.params[1:]: topic_name = re.split(' ', p['name']) # print(topic_name[1]) x_name = None y_name = None line_color = None line_mark = None for c in p['children']: if c['name'] == 'x': x_name = c['value'] elif c['name'] == 'y': y_name = c['value'] elif c['name'] == 'line_color': line_color = c['value'] elif c['name'] == 'line_mark': line_mark = c['value'] plots.append([ topic_name[0], topic_name[1], x_name, y_name, line_color, line_mark ]) # print(plots) # plt.figure(figsize=(12, 10)) for p in plots: x, y = self.get_bag_data(p) plt.plot(x, y, p[5], color=("#" + p[4]), label=p[0]) plt.xlabel(self.params[0]['children'][0]['value']) plt.ylabel(self.params[0]['children'][1]['value']) plt.title(self.params[0]['children'][2]['value']) # plt.ylim(-1.2, 1.2) plt.legend(loc='upper right') plt.grid(True) # plt.savefig(gflags.FLAGS.title + '.svg', format= 'svg') plt.show() ## # @brief # # @param plot_info # # @return def get_bag_data(self, plot_info): x = [] y = [] plot_data = self.topics_data[plot_info[1]] x_index = plot_data[0].index(plot_info[2]) y_index = plot_data[0].index(plot_info[3]) # print(plot_data, x_index, y_index) for pd in plot_data[1:]: # print('len(pd)', len(pd)) # print('x_index', x_index) # print('y_index', y_index) x.append(pd[x_index]) y.append(pd[y_index]) # break return x, y
def create_contenu_dock_pg(self): self.obj_graph['param']['tree'] = ParameterTree() self.create_parameter() self.obj_graph['param']['dock'].addWidget(self.obj_graph['param'] ['tree'])
def create_widget(self): self.widget = ParameterTree(showHeader=False) self.widget.setParameters(self, showTop=True) size_policy_preferred = QtGui.QSizePolicy.Preferred self.widget.setSizePolicy(size_policy_preferred, size_policy_preferred) return self.widget
class JoystickButtonsSelection(QtWidgets.QDialog): def __init__(self): super().__init__() self.setupUI() self.selection = None pygame.init() pygame.joystick.init() # width, height = 64 * 10, 64 * 8 # self.screen = pygame.display.set_mode((width, height)) joystick_count = pygame.joystick.get_count() for ind in range(joystick_count): joystick = pygame.joystick.Joystick(ind) joystick.init() self.startTimer(10) def timerEvent(self, event): for event in pygame.event.get(): # User did something. if 'joy' in event.dict: self.settings.child(('joystickID')).setValue(event.joy) self.selection = dict(joy=event.joy) if event.type == pygame.QUIT: # If user clicked close. self.reject() elif event.type == pygame.JOYBUTTONDOWN or event.type == pygame.JOYBUTTONUP: self.settings.child(('buttonID')).show(True) self.settings.child(('axisID')).show(False) self.settings.child(('hatID')).show(False) self.settings.child(('axis_value')).show(False) self.settings.child(('hat_value1')).show(False) self.settings.child(('hat_value2')).show(False) self.settings.child(('buttonID')).setValue(event.button) self.selection.update(dict(button=event.button)) elif event.type == pygame.JOYAXISMOTION: self.settings.child(('buttonID')).show(False) self.settings.child(('axisID')).show(True) self.settings.child(('hatID')).show(False) self.settings.child(('axis_value')).show(True) self.settings.child(('axisID')).setValue(event.axis) self.settings.child(('axis_value')).setValue(event.value) self.settings.child(('hat_value1')).show(False) self.settings.child(('hat_value2')).show(False) self.selection.update(dict(axis=event.axis, value=event.value)) elif event.type == pygame.JOYHATMOTION: self.settings.child(('buttonID')).show(False) self.settings.child(('axisID')).show(False) self.settings.child(('hatID')).show(True) self.settings.child(('axis_value')).show(True) self.settings.child(('hat_value1')).show(True) self.settings.child(('hat_value2')).show(True) self.settings.child(('hat_value1')).setValue(event.value[0]) self.settings.child(('hat_value2')).setValue(event.value[1]) self.selection.update(dict(hat=event.hat, value=event.value)) def setupUI(self): layout = QtWidgets.QVBoxLayout() self.setLayout(layout) label = QtWidgets.QLabel('Press a button or move an axis on the Joystick:') layout.addWidget(label) params = [{'title': 'Joystick ID', 'name': 'joystickID', 'type': 'int', 'value': -1}, {'title': 'Button ID', 'name': 'buttonID', 'type': 'int', 'value': -1, 'visible': False}, {'title': 'Axis ID', 'name': 'axisID', 'type': 'int', 'value': -1, 'visible': False}, {'title': 'Value:', 'name': 'axis_value', 'type': 'float', 'value': 0., 'visible': False}, {'title': 'Hat ID', 'name': 'hatID', 'type': 'int', 'value': -1, 'visible': False}, {'title': 'Value x:', 'name': 'hat_value1', 'type': 'int', 'value': 0, 'visible': False}, {'title': 'Value y:', 'name': 'hat_value2', 'type': 'int', 'value': 0, 'visible': False}, ] self.settings = Parameter.create(name='settings', type='group', children=params) self.settings_tree = ParameterTree() # tree.setMinimumWidth(400) # self.settings_tree.setMinimumHeight(500) self.settings_tree.setParameters(self.settings, showTop=False) layout.addWidget(self.settings_tree) buttonBox = QtWidgets.QDialogButtonBox() buttonBox.addButton(QtWidgets.QDialogButtonBox.Ok) buttonBox.addButton(QtWidgets.QDialogButtonBox.Cancel) layout.addWidget(buttonBox) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject)
def setupUi(self, ): """ """ self.gridLayout_2 = QtWidgets.QGridLayout(self) self.gridLayout_2.setObjectName("gridLayout_2") self.gridGeneral = QtWidgets.QGridLayout() self.gridGeneral.setObjectName("gridGeneral") self.toolBox = QtWidgets.QToolBox(self) self.toolBox.setFrameShadow(QtWidgets.QFrame.Plain) self.toolBox.setObjectName("toolBox") self.model = QtWidgets.QWidget() self.model.setGeometry(QtCore.QRect(0, 0, 558, 451)) self.model.setObjectName("model") self.gridLayout_4 = QtWidgets.QGridLayout(self.model) self.gridLayout_4.setContentsMargins(0, 0, 0, 0) self.gridLayout_4.setObjectName("gridLayout_4") self.gridModel = QtWidgets.QGridLayout() self.gridModel.setContentsMargins(5, 5, 5, 5) self.gridModel.setSpacing(5) self.gridModel.setObjectName("gridModel") self.line = QtWidgets.QFrame(self.model) self.line.setFrameShape(QtWidgets.QFrame.VLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.gridModel.addWidget(self.line, 0, 1, 1, 1) self.openGLWidget = QtWidgets.QOpenGLWidget(self.model) self.openGLWidget.setObjectName("openGLWidget") self.gridModel.addWidget(self.openGLWidget, 0, 2, 1, 1) self.ModelDescriptionTree = ParameterTree(self.model) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.ModelDescriptionTree.sizePolicy().hasHeightForWidth()) self.ModelDescriptionTree.setSizePolicy(sizePolicy) self.ModelDescriptionTree.setObjectName("ModelDescriptionTree") self.gridModel.addWidget(self.ModelDescriptionTree, 0, 0, 1, 1) self.gridLayout_4.addLayout(self.gridModel, 0, 1, 1, 1) self.toolBox.addItem(self.model, "") self.param = QtWidgets.QWidget() self.param.setGeometry(QtCore.QRect(0, 0, 558, 451)) self.param.setObjectName("param") self.gridLayout_6 = QtWidgets.QGridLayout(self.param) self.gridLayout_6.setContentsMargins(0, 0, 0, 0) self.gridLayout_6.setObjectName("gridLayout_6") self.gridParam = QtWidgets.QGridLayout() self.gridParam.setContentsMargins(5, 5, 5, 5) self.gridParam.setSpacing(5) self.gridParam.setObjectName("gridParam") self.ParametersTree = ParameterTree(self.param) self.ParametersTree.setObjectName("ParametersTree") self.gridParam.addWidget(self.ParametersTree, 0, 0, 1, 1) self.gridLayout_6.addLayout(self.gridParam, 0, 0, 1, 1) self.toolBox.addItem(self.param, "") self.result = QtWidgets.QWidget() self.result.setObjectName("result") self.gridLayout_8 = QtWidgets.QGridLayout(self.result) self.gridLayout_8.setContentsMargins(0, 0, 0, 0) self.gridLayout_8.setObjectName("gridLayout_8") self.gridRes = QtWidgets.QGridLayout() self.gridRes.setContentsMargins(5, 5, 5, 5) self.gridRes.setSpacing(5) self.gridRes.setObjectName("gridRes") self.ResTree = ParameterTree(self.result) self.ResTree.setObjectName("ResTree") self.gridRes.addWidget(self.ResTree, 0, 0, 1, 1) self.gridLayout_8.addLayout(self.gridRes, 0, 0, 1, 1) self.toolBox.addItem(self.result, "") self.gridGeneral.addWidget(self.toolBox, 0, 0, 1, 1) self.gridLayout_2.addLayout(self.gridGeneral, 0, 0, 1, 1) self.retranslateUi(self) self.toolBox.setCurrentIndex(2)
class RemoteManager(QObject): remote_changed = pyqtSignal(dict) def __init__(self, actuators=[], detectors=[], msgbox=False): super().__init__() self.actuators = actuators self.detectors = detectors if msgbox: msgBox = QtWidgets.QMessageBox() msgBox.setText("Preset Manager?") msgBox.setInformativeText("What do you want to do?") cancel_button = msgBox.addButton(QtWidgets.QMessageBox.Cancel) new_button = msgBox.addButton("New", QtWidgets.QMessageBox.ActionRole) modify_button = msgBox.addButton('Modify', QtWidgets.QMessageBox.AcceptRole) msgBox.setDefaultButton(QtWidgets.QMessageBox.Cancel) ret = msgBox.exec() if msgBox.clickedButton() == new_button: self.set_new_remote() elif msgBox.clickedButton() == modify_button: path = select_file(start_path=remote_path, save=False, ext='xml') if path != '': self.set_file_remote(str(path)) else: # cancel pass params = [{'title': 'Activate all', 'name': 'activate_all', 'type': 'action'}, {'title': 'Deactivate all', 'name': 'deactivate_all', 'type': 'action'}, {'title:': 'Actions', 'name': 'action_group', 'type': 'group'}] self.remote_actions = dict(shortcuts=dict([]), joysticks=dict([])) self.remote_settings = Parameter.create(title='Remote Settings', name='remote', type='group', children=params) self.remote_settings.sigTreeStateChanged.connect(self.remote_settings_changed) self.remote_settings_tree = ParameterTree() self.remote_settings_tree.setParameters(self.remote_settings, showTop=False) self.remote_settings.child(('activate_all')).sigActivated.connect(lambda: self.activate_all(True)) self.remote_settings.child(('deactivate_all')).sigActivated.connect(lambda: self.activate_all(False)) def activate_all(self, activate=True): for child in self.remote_settings.child(('action_group')).children(): child.setValue(activate) def set_remote_configuration(self): # remove existing shorcuts while len(self.remote_actions['shortcuts']): self.remote_actions['shortcuts'].pop(list(self.remote_actions['shortcuts'].keys())[0]) while len(self.remote_actions['joysticks']): self.remote_actions['joysticks'].pop(list(self.remote_actions['joysticks'].keys())[0]) all_actions = [] for child in self.remote_params.child('act_actions').children(): module_name = child.opts['title'].split('Actuator ')[1] module_type = 'act' for action in child.child(('actions')).children(): all_actions.append((module_name, action, module_type)) for child in self.remote_params.child('det_actions').children(): module_name = child.opts['title'].split('Detector ')[1] module_type = 'det' for action in child.child(('actions')).children(): all_actions.append((module_name, action, module_type)) for ind, action_tuple in enumerate(all_actions): module, action, module_type = action_tuple if action.child('remote_type').value() == 'Keyboard': # stc = QtWidgets.QShortcut(QtGui.QKeySequence(action.child(('shortcut')).value()), self.dockarea) self.remote_settings.child(('action_group')).addChild( {'title': f"{module}: {action.child(('action')).value()} " f"{action.child(('shortcut')).value()}:", 'name': f'shortcut{ind:02d}', 'type': 'led_push', 'value': False}) self.remote_actions['shortcuts'][f'shortcut{ind:02d}'] = \ dict(shortcut=action.child(('shortcut')).value(), activated=False, name=f'shortcut{ind:02d}', action=action.child(('action')).value(), module_name=module, module_type=module_type) else: self.remote_settings.child(('action_group')).addChild( {'title': f"{module}: {action.child(('action')).value()}=>" f"J{action.child(('joystickID')).value()}/" f"{action.child(('actionner_type')).value()}" f"{action.child(('actionnerID')).value()}:", 'name': f'joy{ind:02d}', 'type': 'led_push', 'value': False}) self.remote_actions['joysticks'][f'joy{ind:02d}'] = \ dict(joystickID=action.child(('joystickID')).value(), actionner_type=action.child(('actionner_type')).value(), actionnerID=action.child(('actionnerID')).value(), activated=False, name=f'joy{ind:02d}', action=action.child(('action')).value(), module_name=module, module_type=module_type) self.activate_all() def set_new_remote(self, file=None): if file is None: file = 'remote_default' param = [ {'title': 'Filename:', 'name': 'filename', 'type': 'str', 'value': file}, ] params_action = [{'title': 'Actuator Actions:', 'name': 'act_actions', 'type': 'groupmodules', 'addList': self.actuators, 'modtype': 'Actuator'}, {'title': 'Detector Actions:', 'name': 'det_actions', 'type': 'groupmodules', 'addList': self.detectors, 'modtype': 'Detector'} ] # PresetScalableGroupMove(name="Moves")] self.remote_params = Parameter.create(title='Preset', name='Preset', type='group', children=param + params_action) self.remote_params.sigTreeStateChanged.connect(self.parameter_tree_changed) logger.info('Creating a new remote file') self.show_remote() def parameter_tree_changed(self, param, changes): """ Check for changes in the given (parameter,change,information) tuple list. In case of value changed, update the DAQscan_settings tree consequently. =============== ============================================ ============================== **Parameters** **Type** **Description** *param* instance of pyqtgraph parameter the parameter to be checked *changes* (parameter,change,information) tuple list the current changes state =============== ============================================ ============================== """ for param, change, data in changes: path = self.remote_params.childPath(param) if change == 'childAdded': pass elif change == 'value': if param.name() == 'remote_type': status = data == 'Keyboard' param.parent().child(('set_shortcut')).show(status) param.parent().child(('shortcut')).show(status) param.parent().child(('set_joystick')).show(not status) param.parent().child(('joystickID')).show(not status) param.parent().child(('actionner_type')).show(not status) param.parent().child(('actionnerID')).show(not status) elif param.name() == 'set_shortcut': msgBox = ShortcutSelection() ret = msgBox.exec() if ret: param.parent().child(('shortcut')).setValue(msgBox.label.text()) elif param.name() == 'set_joystick': msgBox = JoystickButtonsSelection() ret = msgBox.exec() if ret: param.parent().child(('joystickID')).setValue(msgBox.selection['joy']) """ possible cases: ['Axis', 'Button', 'Hat'] """ if 'axis' in msgBox.selection: param.parent().child(('actionner_type')).setValue('Axis') param.parent().child(('actionnerID')).setValue(msgBox.selection['axis']) elif 'button' in msgBox.selection: param.parent().child(('actionner_type')).setValue('Button') param.parent().child(('actionnerID')).setValue(msgBox.selection['button']) elif 'hat' in msgBox.selection: param.parent().child(('actionner_type')).setValue('Hat') param.parent().child(('actionnerID')).setValue(msgBox.selection['hat']) elif change == 'parent': pass def remote_settings_changed(self, param, changes): for param, change, data in changes: path = self.remote_params.childPath(param) if change == 'childAdded': pass elif change == 'value': if 'shortcut' in param.name(): self.remote_actions['shortcuts'][param.name()]['activated'] = data self.remote_changed.emit(dict(action_type='shortcut', action_name=param.name(), action_dict=self.remote_actions['shortcuts'][param.name()])) elif 'joy' in param.name(): self.remote_actions['joysticks'][param.name()]['activated'] = data self.remote_changed.emit(dict(action_type='joystick', action_name=param.name(), action_dict=self.remote_actions['joysticks'][param.name()])) def set_file_remote(self, filename, show=True): """ """ children = ioxml.XML_file_to_parameter(filename) self.remote_params = Parameter.create(title='Shortcuts:', name='shortcuts', type='group', children=children) if show: self.show_remote() def show_remote(self): """ """ dialog = QtWidgets.QDialog() vlayout = QtWidgets.QVBoxLayout() tree = ParameterTree() # tree.setMinimumWidth(400) tree.setMinimumHeight(500) tree.setParameters(self.remote_params, showTop=False) vlayout.addWidget(tree) dialog.setLayout(vlayout) buttonBox = QtWidgets.QDialogButtonBox(parent=dialog) buttonBox.addButton('Save', buttonBox.AcceptRole) buttonBox.accepted.connect(dialog.accept) buttonBox.addButton('Cancel', buttonBox.RejectRole) buttonBox.rejected.connect(dialog.reject) vlayout.addWidget(buttonBox) dialog.setWindowTitle('Fill in information about the actions and their shortcuts') res = dialog.exec() if res == dialog.Accepted: # save preset parameters in a xml file ioxml.parameter_to_xml_file( self.remote_params, os.path.join(remote_path, self.remote_params.child('filename').value()))
def widget(self): widget = ParameterTree() widget.setParameters(self, showTop=False) return widget
class SmallData(object): def __init__(self, parent=None): self.parent = parent ## Dock: Quantifier self.dock = Dock("Small Data", size=(100, 100)) self.win = ParameterTree() self.dock.addWidget(self.win) self.winL = pg.LayoutWidget() self.refreshBtn = QtGui.QPushButton('Refresh') self.winL.addWidget(self.refreshBtn, row=0, col=0) self.peakogramBtn = QtGui.QPushButton('Peakogram') self.winL.addWidget(self.peakogramBtn, row=0, col=1) self.dock.addWidget(self.winL) # Add plot self.winP = pg.PlotWidget(title="Metric") self.dock.addWidget(self.winP) # Quantifier parameter tree self.quantifier_grp = 'Small data' self.quantifier_filename_str = 'filename' self.quantifier_dataset_str = 'dataset' self.quantifier_sort_str = 'sort' # Quantifier self.quantifier_filename = '' self.quantifier_dataset = '/entry_1/result_1/' self.quantifier_sort = False self.quantifierFileOpen = False self.quantifierHasData = False self.params = [ { 'name': self.quantifier_grp, 'type': 'group', 'children': [ { 'name': self.quantifier_filename_str, 'type': 'str', 'value': self.quantifier_filename, 'tip': "Full path Hdf5 filename" }, { 'name': self.quantifier_dataset_str, 'type': 'str', 'value': self.quantifier_dataset, 'tip': "Hdf5 dataset metric, nPeaksAll or nHitsAll" }, { 'name': self.quantifier_sort_str, 'type': 'bool', 'value': self.quantifier_sort, 'tip': "Descending sort metric" }, ] }, ] self.pSmall = Parameter.create(name='paramsQuantifier', type='group', \ children=self.params, expanded=True) self.win.setParameters(self.pSmall, showTop=False) self.pSmall.sigTreeStateChanged.connect(self.change) if using_pyqt4: self.parent.connect(self.refreshBtn, QtCore.SIGNAL("clicked()"), self.reloadQuantifier) self.parent.connect(self.peakogramBtn, QtCore.SIGNAL("clicked()"), self.showPeakogram) else: self.refreshBtn.clicked.connect(self.reloadQuantifier) self.peakogramBtn.clicked.connect(self.showPeakogram) # If anything changes in the parameter tree, print a message def change(self, panel, changes): for param, change, data in changes: path = panel.childPath(param) if self.parent.args.v >= 1: print(' path: %s' % path) print(' change: %s' % change) print(' data: %s' % str(data)) print(' ----------') self.paramUpdate(path, change, data) ############################## # Mandatory parameter update # ############################## def paramUpdate(self, path, change, data): if path[0] == self.quantifier_grp: if path[1] == self.quantifier_filename_str: self.updateQuantifierFilename(data) elif path[1] == self.quantifier_dataset_str: self.updateQuantifierDataset(data) elif path[1] == self.quantifier_sort_str: self.updateQuantifierSort(data) ################################## ########### Quantifier ########### ################################## def reloadQuantifier(self): self.updateQuantifierFilename(self.quantifier_filename) self.updateQuantifierDataset(self.quantifier_dataset) def updateQuantifierFilename(self, data): self.quantifier_filename = data if self.parent.args.v >= 1: print "Done opening metric" def updateQuantifierDataset(self, data): self.quantifier_dataset = data if os.path.isfile(self.quantifier_filename): try: self.quantifierFile = h5py.File(self.quantifier_filename, 'r') self.quantifierMetric = self.quantifierFile[ self.quantifier_dataset].value try: if self.quantifier_dataset[ 0] == '/': # dataset starts with "/" self.quantifier_eventDataset = self.quantifier_dataset.split( "/")[1] + "/event" else: # dataset does not start with "/" self.quantifier_eventDataset = "/" + self.quantifier_dataset.split( "/")[0] + "/event" self.quantifierEvent = self.quantifierFile[ self.quantifier_eventDataset].value except: if self.parent.args.v >= 1: print "Couldn't find /event dataset" self.quantifierEvent = np.arange(len( self.quantifierMetric)) self.quantifierFile.close() self.quantifierInd = np.arange(len(self.quantifierMetric)) self.updateQuantifierSort(self.quantifier_sort) except: print "Couldn't read metric" if self.parent.args.v >= 1: print "Done reading metric" def updateQuantifierSort(self, data): self.quantifier_sort = data try: if self.quantifier_sort is True: self.quantifierIndSorted = np.argsort( self.quantifierMetric)[::-1] self.quantifierMetricSorted = self.quantifierMetric[ self.quantifierIndSorted] #self.quantifierEventSorted = self.quantifierMetric[self.quantifierInd] self.updateQuantifierPlot(self.quantifierMetricSorted) else: self.updateQuantifierPlot(self.quantifierMetric) except: print "Couldn't sort data" pass def updateQuantifierPlot(self, metric): self.winP.getPlotItem().clear() if len(np.where(metric == -1)[0]) > 0: self.curve = self.winP.plot(metric, pen=(200, 200, 200), symbolBrush=(255, 0, 0), symbolPen='k') # red else: # Every event was processed self.curve = self.winP.plot(metric, pen=(200, 200, 200), symbolBrush=(0, 0, 255), symbolPen='k') # blue self.winP.setLabel('left', "Small data") if self.quantifier_sort: self.winP.setLabel('bottom', "Sorted Event Index") else: self.winP.setLabel('bottom', "Event Index") self.curve.curve.setClickable(True) self.curve.sigClicked.connect(self.clicked) def clicked(self, points): with pg.BusyCursor(): if self.parent.args.v >= 1: print("curve clicked", points) from pprint import pprint pprint(vars(points.scatter)) for i in range(len(points.scatter.data)): if points.scatter.ptsClicked[0] == points.scatter.data[i][7]: ind = i break indX = points.scatter.data[i][0] indY = points.scatter.data[i][1] if self.parent.args.v >= 1: print "x,y: ", indX, indY if self.quantifier_sort: ind = self.quantifierIndSorted[ind] if self.parent.eventNumber != self.quantifierEvent[ind]: self.parent.eventNumber = self.quantifierEvent[ind] self.parent.calib, self.parent.data = self.parent.img.getDetImage( self.parent.eventNumber) self.parent.img.win.setImage(self.parent.data, autoRange=False, autoLevels=False, autoHistogramRange=False) self.parent.exp.p.param(self.parent.exp.exp_grp, self.parent.exp.exp_evt_str).setValue( self.parent.eventNumber) def showPeakogram(self): if os.path.isfile(self.quantifier_filename): cmd = "peakogram -i " + self.quantifier_filename subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
def __init__(self): super(maintest, self).__init__() self.values = { 'module 1': module(1), 'module 2': module(2), 'module 3': module(3) } self.module = self.values['module 2'] p = [{ 'name': 'Module', 'type': 'list', 'values': self.values, 'set': self.setmodule, 'get': self.getmodule, 'childmode': "root", 'help': '%namehdr%Boatload of text is possible here. Can use markup too with external help window.' }, { 'name': 'Rocks to Skips', 'type': 'int', 'value': 0, 'help': 'Another help example', 'helpwnd': None, 'linked': ['1/Rocks to Skips'] }, { 'name': '1/Rocks to Skips', 'type': 'float', 'help': 'Another help example', 'helpwnd': None, 'get': self.getLinked }] self.params = Parameter(name='Root', type='group', children=p).register() self.params.init() self.t = ParameterTree() self.t.addParameters(self.params.getPyQtGraphParameter()) self.test = Parameter(name='Test', type='group') self.test.addChildren([{ 'name': 'baud', 'type': 'int', 'key': 'baud', 'limits': (500, 2000000), 'value': 38400 }]) self.params.append(self.test) self.test.remove() self.test.getChild("baud").setValue(500) self.params.append(self.test) self.t2 = ParameterTree() self.params2 = Parameter(name='Root', type='group') self.params.getChild("Module").stealDynamicParameters(self.params2) self.t2.addParameters(self.params2._PyQtGraphParameter) self.params.save("abcde.txt") self.params.load("abcde.txt")
def __init__(self, parent=None): self.parent = parent ## Dock: Quantifier self.dock = Dock("Small Data", size=(100, 100)) self.win = ParameterTree() self.dock.addWidget(self.win) self.winL = pg.LayoutWidget() self.refreshBtn = QtGui.QPushButton('Refresh') self.winL.addWidget(self.refreshBtn, row=0, col=0) self.peakogramBtn = QtGui.QPushButton('Peakogram') self.winL.addWidget(self.peakogramBtn, row=0, col=1) self.dock.addWidget(self.winL) # Add plot self.winP = pg.PlotWidget(title="Metric") self.dock.addWidget(self.winP) # Quantifier parameter tree self.quantifier_grp = 'Small data' self.quantifier_filename_str = 'filename' self.quantifier_dataset_str = 'dataset' self.quantifier_sort_str = 'sort' # Quantifier self.quantifier_filename = '' self.quantifier_dataset = '/entry_1/result_1/' self.quantifier_sort = False self.quantifierFileOpen = False self.quantifierHasData = False self.params = [ { 'name': self.quantifier_grp, 'type': 'group', 'children': [ { 'name': self.quantifier_filename_str, 'type': 'str', 'value': self.quantifier_filename, 'tip': "Full path Hdf5 filename" }, { 'name': self.quantifier_dataset_str, 'type': 'str', 'value': self.quantifier_dataset, 'tip': "Hdf5 dataset metric, nPeaksAll or nHitsAll" }, { 'name': self.quantifier_sort_str, 'type': 'bool', 'value': self.quantifier_sort, 'tip': "Descending sort metric" }, ] }, ] self.pSmall = Parameter.create(name='paramsQuantifier', type='group', \ children=self.params, expanded=True) self.win.setParameters(self.pSmall, showTop=False) self.pSmall.sigTreeStateChanged.connect(self.change) if using_pyqt4: self.parent.connect(self.refreshBtn, QtCore.SIGNAL("clicked()"), self.reloadQuantifier) self.parent.connect(self.peakogramBtn, QtCore.SIGNAL("clicked()"), self.showPeakogram) else: self.refreshBtn.clicked.connect(self.reloadQuantifier) self.peakogramBtn.clicked.connect(self.showPeakogram)
class HitFinder(object): def __init__(self, parent=None): self.parent = parent ## Dock: Hit finder self.dock = Dock("Hit Finder", size=(1, 1)) self.win = ParameterTree() self.dock.addWidget(self.win) self.winL = pg.LayoutWidget() self.dock.addWidget(self.winL) # Hit finding self.spiParam_grp = 'Hit finder' self.spiParam_algorithm_str = 'Algorithm' # algorithm 0 self.spiParam_algorithm0_str = 'None' # algorithm 1 self.spiParam_algorithm1_str = 'chiSquared' self.spiParam_alg1_pruneInterval_str = 'prune interval' # algorithm 2 self.spiParam_algorithm2_str = 'photonFinder' self.spiParam_alg2_threshold_str = 'ADUs per photon' self.spiParam_alg2_hitThreshold_str = 'Number of pixels for a hit' self.spiParam_outDir_str = 'Output directory' self.spiParam_runs_str = 'Run(s)' self.spiParam_queue_str = 'queue' self.spiParam_cpu_str = 'CPUs' self.spiParam_psanaq_str = 'psanaq' self.spiParam_psnehq_str = 'psnehq' self.spiParam_psfehq_str = 'psfehq' self.spiParam_psnehprioq_str = 'psnehprioq' self.spiParam_psfehprioq_str = 'psfehprioq' self.spiParam_psnehhiprioq_str = 'psnehhiprioq' self.spiParam_psfehhiprioq_str = 'psfehhiprioq' self.spiParam_psdebugq_str = 'psdebugq' self.spiParam_noe_str = 'Number of events to process' self.spiParam_launch_str = 'Launch hit finder' self.hitParam_grp = 'Find hits' self.hitParam_hitThresh_str = 'Hit threshold' self.hitParam_backgroundThresh_str = 'Background threshold' self.hitParam_sample_str = 'Sample name' self.hitParam_save_str = 'Save hits' # Init hit finding self.nPixels = 0 self.spiAlgorithm = 2 self.spiParam_alg1_pruneInterval = -1 self.spiParam_alg2_threshold = 30 self.spiParam_outDir = self.parent.psocakeDir self.spiParam_outDir_overridden = False self.spiParam_runs = '' self.spiParam_queue = self.spiParam_psanaq_str self.spiParam_cpus = 24 self.spiParam_noe = -1 self.hitParam_hitThresh = '-1' self.hitParam_backgroundThresh = '-1' self.hitParam_sample = "sample" self.params = [ { 'name': self.spiParam_grp, 'type': 'group', 'children': [ { 'name': self.spiParam_algorithm_str, 'type': 'list', 'values': { self.spiParam_algorithm2_str: 2, self.spiParam_algorithm0_str: 0 }, 'value': self.spiAlgorithm }, #{'name': self.spiParam_algorithm1_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "", # 'readonly': True, 'children': [ # {'name': self.spiParam_alg1_pruneInterval_str, 'type': 'float', 'value': self.spiParam_alg1_pruneInterval, # 'tip': "update running background"}, #]}, { 'name': self.spiParam_algorithm2_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "", 'readonly': True, 'children': [ { 'name': self.spiParam_alg2_threshold_str, 'type': 'float', 'value': self.spiParam_alg2_threshold, 'tip': "search for pixels above ADU per photon" }, ] }, { 'name': self.spiParam_outDir_str, 'type': 'str', 'value': self.spiParam_outDir }, { 'name': self.spiParam_runs_str, 'type': 'str', 'value': self.spiParam_runs, 'tip': "comma separated or use colon for a range, e.g. 1,3,5:7 = runs 1,3,5,6,7" }, { 'name': self.spiParam_queue_str, 'type': 'list', 'values': { self.spiParam_psfehhiprioq_str: 'psfehhiprioq', self.spiParam_psnehhiprioq_str: 'psnehhiprioq', self.spiParam_psfehprioq_str: 'psfehprioq', self.spiParam_psnehprioq_str: 'psnehprioq', self.spiParam_psfehq_str: 'psfehq', self.spiParam_psnehq_str: 'psnehq', self.spiParam_psanaq_str: 'psanaq', self.spiParam_psdebugq_str: 'psdebugq' }, 'value': self.spiParam_queue, 'tip': "Choose queue" }, { 'name': self.spiParam_cpu_str, 'type': 'int', 'value': self.spiParam_cpus }, { 'name': self.spiParam_noe_str, 'type': 'int', 'value': self.spiParam_noe, 'tip': "number of events to process, default=0 means process all events" }, { 'name': self.spiParam_launch_str, 'type': 'action' }, ] }, { 'name': self.hitParam_grp, 'type': 'group', 'children': [ { 'name': self.hitParam_hitThresh_str, 'type': 'str', 'value': self.hitParam_hitThresh, 'tip': "Set as hit if number of pixels with photons above this value. Or specify a range using a colon, e.g. 100:10000." }, { 'name': self.hitParam_backgroundThresh_str, 'type': 'str', 'value': self.hitParam_backgroundThresh, 'tip': "Use as background if number of pixels with photons below this value. Or specify a range using a colon, e.g. 100:10000." }, { 'name': self.hitParam_sample_str, 'type': 'str', 'value': self.hitParam_sample }, { 'name': self.hitParam_save_str, 'type': 'action' }, ] }, ] self.p8 = Parameter.create(name='paramsHitFinder', type='group', \ children=self.params, expanded=True) self.win.setParameters(self.p8, showTop=False) self.p8.sigTreeStateChanged.connect(self.change) # Launch hit finding def findHits(self): self.parent.thread.append(LaunchHitFinder.HitFinder( self.parent)) # send parent parameters with self self.parent.thread[self.parent.threadCounter].findHits( self.parent.experimentName, self.parent.runNumber, self.parent.detInfo) self.parent.threadCounter += 1 def setThreshold(self): self.parent.thread.append( LaunchHitConverter.LaunchHitConverter( self.parent)) # send parent parameters with self self.parent.thread[self.parent.threadCounter].launch( self.parent.experimentName, self.parent.detInfo) self.parent.threadCounter += 1 # If anything changes in the parameter tree, print a message def change(self, panel, changes): for param, change, data in changes: path = panel.childPath(param) if self.parent.args.v >= 1: print(' path: %s' % path) print(' change: %s' % change) print(' data: %s' % str(data)) print(' ----------') self.paramUpdate(path, change, data) ############################## # Mandatory parameter update # ############################## def paramUpdate(self, path, change, data): if path[0] == self.spiParam_grp: if path[1] == self.spiParam_algorithm_str: self.spiAlgorithm = data elif path[1] == self.spiParam_outDir_str: self.spiParam_outDir = data self.spiParam_outDir_overridden = True elif path[1] == self.spiParam_runs_str: self.spiParam_runs = data elif path[1] == self.spiParam_queue_str: self.spiParam_queue = data elif path[1] == self.spiParam_cpu_str: self.spiParam_cpus = data elif path[1] == self.spiParam_noe_str: self.spiParam_noe = data elif path[1] == self.spiParam_launch_str: self.findHits() elif path[2] == self.spiParam_alg1_pruneInterval_str and path[ 1] == self.spiParam_algorithm1_str: self.spiParam_alg1_pruneInterval = data self.updateHit() elif path[2] == self.spiParam_alg2_threshold_str and path[ 1] == self.spiParam_algorithm2_str: self.spiParam_alg2_threshold = data self.updateHit() elif path[0] == self.hitParam_grp: if path[1] == self.hitParam_hitThresh_str: self.hitParam_hitThresh = data elif path[1] == self.hitParam_backgroundThresh_str: self.hitParam_backgroundThresh = data elif path[1] == self.hitParam_sample_str: self.hitParam_sample = data elif path[1] == self.hitParam_save_str: self.setThreshold() def updateHit(self): # Save a temporary mask if self.parent.mk.userMask is None: userMask = None else: userMask = self.parent.psocakeDir + "/r" + str( self.parent.runNumber).zfill(4) + "/tempUserMask.npy" np.save(userMask, self.parent.mk.userMask) worker = alg.HitFinder( self.parent.experimentName, self.parent.runNumber, self.parent.detInfo, self.parent.evt, self.parent.det, self.spiParam_alg2_threshold, streakMask_on=str(self.parent.mk.streakMaskOn), streakMask_sigma=self.parent.mk.streak_sigma, streakMask_width=self.parent.mk.streak_width, userMask_path=userMask, psanaMask_on=str(self.parent.mk.psanaMaskOn), psanaMask_calib=str(self.parent.mk.mask_calibOn), psanaMask_status=str(self.parent.mk.mask_statusOn), psanaMask_edges=str(self.parent.mk.mask_edgesOn), psanaMask_central=str(self.parent.mk.mask_centralOn), psanaMask_unbond=str(self.parent.mk.mask_unbondOn), psanaMask_unbondnrs=str(self.parent.mk.mask_unbondnrsOn)) worker.findHits(self.parent.calib, self.parent.evt) self.nPixels = worker.nPixels self.indicatePhotons() if self.parent.args.v >= 1: print "self.nPixels: ", self.nPixels def indicatePhotons(self): self.parent.img.clearPeakMessage() self.parent.mk.displayMask() # Write number of pixels found containing photons xMargin = 5 # pixels yMargin = 0 # pixels maxX = np.max(self.parent.det.indexes_x(self.parent.evt)) + xMargin maxY = np.max(self.parent.det.indexes_y(self.parent.evt)) - yMargin myMessage = '<div style="text-align: center"><span style="color: cyan; font-size: 12pt;">Pixels=' + \ str(self.nPixels) + ' <br></span></div>' self.parent.img.peak_text = pg.TextItem(html=myMessage, anchor=(0, 0)) self.parent.img.w1.getView().addItem(self.parent.img.peak_text) self.parent.img.peak_text.setPos(maxX, maxY)
else: childName = param.name() print(' parameter: %s' % childName) print(' change: %s' % change) print(' data: %s' % str(data)) print(' ----------') if childName == 'Tacq': print "data: ", data timer.stop() timer.setInterval(int(data * 1000) + 10) Tacq = data timer.start() p.sigTreeStateChanged.connect(change) t = ParameterTree() t.setParameters(p, showTop=False) ############### if True: win = QtGui.QMainWindow() win.resize(1600, 600) win.setWindowTitle('window title') glw = QtGui.QWidget() #glw = pg.GraphicsLayoutWidget() l = QtGui.QGridLayout() glw.setLayout(l) win.setCentralWidget(glw)