def setParameters(self, parameter: Parameter): parameter.blockSignals(True) for child in parameter.children(): child.blockSignals(True) self.processeditor.setParameters(parameter, showTop=False) QApplication.processEvents() parameter.blockSignals(False) for child in parameter.children(): child.blockSignals(False)
def wireup_parameter(self, parameter: Parameter): """Wire up a Parameter (created from an operation) to update the operation's state. Updates the operation's values (filled_values) if the Parameter values are changed. Updates the operatin's fixed state if the Parameter's fixed state is changed. This is useful when you want to interact with an operations inputs in a GUI by using something like a ParameterTree (see example). Parameters ---------- parameter : Parameter A pyqtgraph Parameter created from an operation (via `as_parameter()`) Example ------- >>> from pyqtgraph.parametertree import ParameterTree >>> from pyqtgraph.parametertree.parameterTypes import GroupParameter >>> from qtpy.QtWidgets import QApplication, QMainWindow >>> from xicam.plugins.operationplugin import operation, output_names >>> @operation >>> @output_names("sum") >>> def my_operation(x: float = 1.0, y: float = 2.0): >>> return x + y >>> qapp = QApplication([]) >>> parameter_tree = ParameterTree() >>> op = my_operation() >>> parameter = GroupParameter(name=op.name, children=op.as_parameter()) >>> op.wireup_parameter(parameter) >>> parameter_tree.addParameters(parameter) >>> window = QMainWindow() >>> window.setCentralWidget(parameter_tree) >>> window.show() >>> qapp.exec_() """ for child, param in zip(parameter.children(), self.as_parameter()): # wireup signals to update the workflow if param.get('fixable'): child.sigFixToggled.connect(self._set_fixed) msg.logMessage(child.name()) # child.sigValueChanged.connect(lambda *args: print(args)) child.sigValueChanged.connect(self._set_value) # We want to propagate changes to the operation's fixed/values state to the Parameter self._parameter = weakref.ref(parameter)
class DeviceProfiles(SettingsPlugin): sigRequestRedraw = Signal() sigRequestReduce = Signal() sigSimulateCalibrant = Signal() name = 'Device Profiles' def __init__(self): self.headermodel = None self.selectionmodel = None self.multiAI = MultiGeometry([]) self.AIs = dict() widget = ParameterTree() energy = SimpleParameter(name='Energy', type='float', value=10000, siPrefix=True, suffix='eV') wavelength = SimpleParameter(name='Wavelength', type='float', value=1.239842e-6 / 10000, siPrefix=True, suffix='m') self.parameter = Parameter(name="Device Profiles", type='group', children=[energy, wavelength]) widget.setParameters(self.parameter, showTop=False) icon = QIcon(str(path('icons/calibrate.png'))) super(DeviceProfiles, self).__init__(icon, "Device Profiles", widget) self.parameter.sigValueChanged.connect(self.sigRequestRedraw) self.parameter.sigValueChanged.connect(self.sigRequestReduce) self.parameter.sigTreeStateChanged.connect(self.simulateCalibrant) self.parameter.sigTreeStateChanged.connect(self.genAIs) self.parameter.sigValueChanged.connect(self.simulateCalibrant) def simulateCalibrant(self, *args): self.sigSimulateCalibrant.emit() def genAIs(self, parent, changes): for parameter, key, value in changes: if parameter.name == 'Wavelength': self.parameter.param('Energy').setValue( 1.239842e-6 / self.param('Wavelength').value(), blockSignal=self.parameter.sigTreeStateChanged) elif parameter.name == 'Energy': self.parameter.param('Wavelength').setValue( 1.239842e-6 / self.param('Energy').value(), blockSignal=self.WavelengthChanged) for parameter in self.parameter.children(): if isinstance(parameter, DeviceParameter): device = parameter.name() ai = self.AI(device) ai.set_wavelength(self.parameter['Wavelength']) ai.detector = parameter['Detector']() ai.detector.set_binning([parameter['Binning']] * 2) ai.detector.set_pixel1(parameter['Pixel Size X']) ai.detector.set_pixel2(parameter['Pixel Size Y']) fit2d = ai.getFit2D() fit2d['centerX'] = parameter['Center X'] fit2d['centerY'] = parameter['Center Y'] fit2d['directDist'] = parameter['Detector Distance'] * 1000 fit2d['tilt'] = parameter['Detector Tilt'] fit2d['tiltPlanRotation'] = parameter['Detector Rotation'] ai.setFit2D(**fit2d) def AI(self, device): if device not in self.AIs: self.addDevice(device) return self.AIs[device] def setAI(self, ai: AzimuthalIntegrator, device: str): self.AIs[device] = ai self.multiAI.ais = self.AIs.values() # propagate new ai to parameter fit2d = ai.getFit2D() try: self.setSilence(True) self.parameter.child(device, 'Detector').setValue(type(ai.detector)) self.parameter.child(device, 'Binning').setValue(ai.detector.binning[0]) self.parameter.child(device, 'Detector Tilt').setValue( fit2d['tiltPlanRotation']) self.parameter.child(device, 'Detector Rotation').setValue(fit2d['tilt']) self.parameter.child(device, 'Pixel Size X').setValue(ai.pixel1) self.parameter.child(device, 'Pixel Size Y').setValue(ai.pixel2) self.parameter.child(device, 'Center X').setValue(fit2d['centerX']) self.parameter.child(device, 'Center Y').setValue(fit2d['centerY']) self.parameter.child(device, 'Detector Distance').setValue( fit2d['directDist'] / 1000) self.parameter.child('Wavelength').setValue(ai.wavelength) finally: self.setSilence(False) self.simulateCalibrant() def setSilence(self, silence): if silence: self.parameter.sigTreeStateChanged.disconnect( self.simulateCalibrant) self.parameter.sigTreeStateChanged.disconnect(self.genAIs) else: self.parameter.sigTreeStateChanged.connect(self.simulateCalibrant) self.parameter.sigTreeStateChanged.connect(self.genAIs) def addDevice(self, device): try: self.setSilence(True) devicechild = DeviceParameter(device) self.parameter.addChild(devicechild) ai = AzimuthalIntegrator(wavelength=self.parameter['Wavelength']) self.AIs[device] = ai self.multiAI.ais = list(self.AIs.values()) finally: self.setSilence(False) def setModels(self, headermodel, selectionmodel): self.headermodel = headermodel self.headermodel.dataChanged.connect(self.dataChanged) self.selectionmodel = selectionmodel def dataChanged(self, start, end): devices = self.headermodel.item( self.selectionmodel.currentIndex()).header.devices() for device in devices: if device not in self.AIs: self.addDevice(device) def apply(self): AI = AzimuthalIntegrator( wavelength=self.parameter.child('Wavelength').value()) # if Calibration.isChecked(): # AI.setFit2D(self.getvalue('Detector Distance') * 1000., # self.getvalue('Center X'), # self.getvalue('Center Y'), # self.getvalue('Detector Tilt'), # 360. - self.getvalue('Detector Rotation'), # self.getvalue('Pixel Size Y') * 1.e6, # self.getvalue('Pixel Size X') * 1.e6) # elif self.wxdiffstyle.isChecked(): # AI.setFit2D(self.getvalue('Detector Distance') * 1000., # self.getvalue('Center X'), # self.getvalue('Center Y'), # self.getvalue('Detector Tilt') / 2. / np.pi * 360., # 360. - (2 * np.pi - self.getvalue('Detector Rotation')) / 2. / np.pi * 360., # self.getvalue('Pixel Size Y') * 1.e6, # self.getvalue('Pixel Size X') * 1.e6) # AI.set_wavelength(self.getvalue('Wavelength')) # # print AI activeCalibration = AI def save(self): self.apply() return self.parameter.saveState(filter='user') def restore(self, state): pass # self.parameter.restoreState(state, addChildren=False, removeChildren=False) def wavelengthChanged(self): self.param('Energy').setValue(1.239842e-6 / self.param('Wavelength').value(), blockSignal=self.EnergyChanged) def energyChanged(self): self.param('Wavelength').setValue(1.239842e-6 / self.param('Energy').value(), blockSignal=self.WavelengthChanged)