Ejemplo n.º 1
0
    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)
Ejemplo n.º 3
0
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)