예제 #1
0
 def __init__(self):
     super().__init__()
     # Properties
     self.title = "Sequence Manager"
     # Layout
     self.resize(640, 480)
     self._sequence_tree = ui.Tree(header=("Name", "Filename"),
                                   indentation=0,
                                   selected=self.on_sequence_tree_selected)
     self._add_button = ui.Button(text="&Add", clicked=self.on_add_sequence)
     self._remove_button = ui.Button(text="&Remove",
                                     enabled=False,
                                     clicked=self.on_remove_sequence)
     self._preview_tree = ui.Tree(header=["Key", "Value"])
     self.layout = ui.Column(ui.Row(ui.Column(self._sequence_tree,
                                              self._preview_tree,
                                              stretch=(4, 3)),
                                    ui.Column(self._add_button,
                                              self._remove_button,
                                              ui.Spacer()),
                                    stretch=(1, 0)),
                             ui.DialogButtonBox(buttons=("ok", "cancel"),
                                                accepted=self.accept,
                                                rejected=self.reject),
                             stretch=(1, 0))
예제 #2
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title = "IV Ramp"

        self.register_vsource()
        self.register_environment()

        self.plot = ui.Plot(height=300, legend="right")
        self.plot.add_axis("x", align="bottom", text="Voltage [V] (abs)")
        self.plot.add_axis("y", align="right", text="Current [uA]")
        self.plot.add_series("hvsrc", "x", "y", text="HV Source", color="red")
        self.plot.add_series("xfit", "x", "y", text="Fit", color="magenta")
        self.data_tabs.insert(0, ui.Tab(title="IV Curve", layout=self.plot))

        self.voltage_start = ui.Number(decimals=3, suffix="V")
        self.voltage_stop = ui.Number(decimals=3, suffix="V")
        self.voltage_step = ui.Number(minimum=0, maximum=200, decimals=3, suffix="V")
        self.waiting_time = ui.Number(minimum=0, decimals=2, suffix="s")

        self.hvsrc_current_compliance = ui.Metric(minimum=0, decimals=3, prefixes='mun', unit="A")

        self.bind("voltage_start", self.voltage_start, 0, unit="V")
        self.bind("voltage_stop", self.voltage_stop, 100, unit="V")
        self.bind("voltage_step", self.voltage_step, 1, unit="V")
        self.bind("waiting_time", self.waiting_time, 1, unit="s")

        self.bind("hvsrc_current_compliance", self.hvsrc_current_compliance, 0, unit="A")

        self.general_tab.layout = ui.Row(
            ui.GroupBox(
                title="Ramp",
                layout=ui.Column(
                    ui.Label(text="Start"),
                    self.voltage_start,
                    ui.Label(text="Stop"),
                    self.voltage_stop,
                    ui.Label(text="Step"),
                    self.voltage_step,
                    ui.Label(text="Waiting Time"),
                    self.waiting_time,
                    ui.Spacer()
                )
            ),
            ui.GroupBox(
                title="HV Source",
                layout=ui.Column(
                    ui.Label(text="Compliance"),
                    self.hvsrc_current_compliance,
                    ui.Spacer()
                )
            ),
            ui.Spacer(),
            stretch=(1, 1, 1)
        )

        ampere = comet.ureg('A')
        volt = comet.ureg('V')

        self.series_transform['hvsrc'] = lambda x, y: ((x * volt).to('V').m, (y * ampere).to('uA').m)
        self.series_transform['xfit'] = self.series_transform.get('hvsrc')
예제 #3
0
 def __init__(self):
     super().__init__(title="Webserver")
     self._enabled_checkbox = ui.CheckBox(
         text="Enable Server"
     )
     self._host_text = ui.Text()
     self._port_number = ui.Number(
         minimum=0,
         maximum=99999,
         step=1
     )
     self.layout = ui.Column(
         ui.GroupBox(
                 title="JSON API",
                 layout=ui.Column(
                 self._enabled_checkbox,
                 ui.Row(
                     ui.Column(
                         ui.Label("Host"),
                         ui.Label("Port"),
                     ),
                     ui.Column(
                         self._host_text,
                         self._port_number,
                     ),
                     ui.Spacer()
                 ),
                 ui.Spacer(),
                 stretch=(0, 0, 1)
             )
         ),
         ui.Spacer(),
         stretch=(0, 1)
     )
예제 #4
0
파일: panel.py 프로젝트: mwulansa/comet-pqc
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._bindings = {}
        self.state_handlers = []
        self.data_panel = ui.Column()
        self.general_tab = ui.Tab(title="General", layout=ui.Row())
        self.control_tabs = ui.Tabs(self.general_tab)
        self.status_panel = ui.Column()
        self.control_panel = ui.Row(self.control_tabs,
                                    ui.Column(self.status_panel,
                                              ui.Spacer(horizontal=False)),
                                    stretch=(3, 1))
        self.layout.insert(2, self.data_panel)
        self.layout.insert(3, self.control_panel)
        self.layout.stretch = 0, 0, 0, 0, 1
        self.measurement = None
        self.data_tabs = ui.Tabs()
        self.data_panel.append(self.data_tabs)

        # Add analysis tab
        self.analysis_tree = ui.Tree(header=["Parameter", "Value"])
        self.data_tabs.insert(
            0, ui.Tab(title="Analysis", layout=self.analysis_tree))

        # Plots
        self.series_transform = {}
        self.series_transform_default = lambda x, y: (x, y)
예제 #5
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.matrix_enable = ui.CheckBox(text="Enable Switching")
        self.matrix_channels = MatrixChannelsText(
            tool_tip="Matrix card switching channels, comma separated list."
        )

        self.bind("matrix_enable", self.matrix_enable, False)
        self.bind("matrix_channels", self.matrix_channels, [])

        self.control_tabs.append(ui.Tab(
            title="Matrix",
            layout=ui.Column(
                ui.GroupBox(
                    title="Matrix",
                    layout=ui.Column(
                        self.matrix_enable,
                        ui.Label(text="Channels"),
                        ui.Row(
                            self.matrix_channels,
                            # ui.Button(text="Load from Matrix", clicked=self.load_matrix_channels)
                        )
                    )
                ),
                ui.Spacer(),
                stretch=(0, 1)
            )
        ))
예제 #6
0
 def __init__(self, sample_changed=None, **kwargs):
     super().__init__(**kwargs)
     # Properties
     self.title = "Sample"
     # Callbacks
     self.sample_changed = sample_changed
     # Layout
     self._sample_name_prefix_text = ui.Text(
         tool_tip="Sample name prefix",
         clearable=True,
         editing_finished=self.on_sample_name_edited)
     self._sample_name_infix_text = ui.Text(
         tool_tip="Sample name",
         clearable=True,
         editing_finished=self.on_sample_name_edited)
     self._sample_name_suffix_text = ui.Text(
         tool_tip="Sample name suffix",
         clearable=True,
         editing_finished=self.on_sample_name_edited)
     self._sample_type_text = ui.Text(
         tool_tip="Sample type",
         clearable=True,
         editing_finished=self.on_sample_name_edited)
     self._sample_position_text = ui.Text(
         tool_tip="Sample position on the chuck",
         clearable=True,
         editing_finished=self.on_sample_position_edited)
     self._sequence_text = ui.Text(readonly=True)
     self._sample_comment_text = ui.Text(
         tool_tip="Sample comment (optional)",
         clearable=True,
         editing_finished=self.on_sample_comment_edited)
     self._reload_button = ui.ToolButton(
         icon=make_path('assets', 'icons', 'reload.svg'),
         tool_tip="Reload sequence configuration from file.",
         clicked=self.on_reload_clicked)
     self._sequence_manager_button = ui.ToolButton(
         icon=make_path('assets', 'icons', 'gear.svg'),
         tool_tip="Open sequence manager",
         clicked=self.on_sequence_manager_clicked)
     self._sample_groupbox = ui.GroupBox(
         title="Sample",
         layout=ui.Row(ui.Column(ui.Label("Name"), ui.Label("Type"),
                                 ui.Label("Position"), ui.Label("Comment"),
                                 ui.Label("Sequence")),
                       ui.Column(
                           ui.Row(self._sample_name_prefix_text,
                                  self._sample_name_infix_text,
                                  self._sample_name_suffix_text,
                                  stretch=(3, 7, 3)),
                           self._sample_type_text,
                           self._sample_position_text,
                           self._sample_comment_text,
                           ui.Row(self._sequence_text,
                                  self._reload_button,
                                  self._sequence_manager_button,
                                  stretch=(1, 0))),
                       stretch=(0, 1)))
     self.layout.insert(2, self._sample_groupbox)
예제 #7
0
 def __init__(self):
     super().__init__(title="Options")
     self._png_plots_checkbox = ui.CheckBox("Save plots as PNG")
     self._points_in_plots_checkbox = ui.CheckBox("Show points in plots")
     self._png_analysis_checkbox = ui.CheckBox(
         "Add analysis preview to PNG")
     self._export_json_checkbox = ui.CheckBox("Write JSON data (*.json)")
     self._export_txt_checkbox = ui.CheckBox(
         "Write plain text data (*.txt)")
     self._write_logfiles_checkbox = ui.CheckBox(
         "Write measurement log files (*.log)")
     self._vsrc_instrument_combobox = ui.ComboBox(
         ["K2410", "K2470", "K2657A"])
     self._hvsrc_instrument_combobox = ui.ComboBox(
         ["K2410", "K2470", "K2657A"])
     self._retry_measurement_number = ui.Number(
         minimum=0,
         suffix="x",
         tool_tip="Number of retries for measurements with failed analysis."
     )
     self._retry_contact_number = ui.Number(
         minimum=0,
         suffix="x",
         tool_tip=
         "Number of re-contact retries for measurements with failed analysis."
     )
     self.layout = ui.Column(
         ui.Row(ui.GroupBox(title="Plots",
                            layout=ui.Column(
                                self._png_plots_checkbox,
                                self._points_in_plots_checkbox,
                            )),
                ui.GroupBox(title="Analysis",
                            layout=ui.Column(self._png_analysis_checkbox,
                                             ui.Spacer())),
                stretch=(0, 1)),
         ui.Row(ui.GroupBox(title="Formats",
                            layout=ui.Column(self._export_json_checkbox,
                                             self._export_txt_checkbox)),
                ui.GroupBox(title="Log files",
                            layout=ui.Column(self._write_logfiles_checkbox,
                                             ui.Spacer())),
                stretch=(0, 1)),
         ui.GroupBox(title="Instruments",
                     layout=ui.Row(ui.Column(ui.Label("V Source"),
                                             ui.Label("HV Source")),
                                   ui.Column(
                                       self._vsrc_instrument_combobox,
                                       self._hvsrc_instrument_combobox),
                                   ui.Spacer(vertical=False),
                                   stretch=(0, 0, 1))),
         ui.GroupBox(title="Auto Retry",
                     layout=ui.Row(
                         ui.Column(ui.Label("Retry Measurements"),
                                   ui.Label("Retry Contact")),
                         ui.Column(self._retry_measurement_number,
                                   self._retry_contact_number),
                         ui.Spacer())),
         ui.Spacer(),
         stretch=(0, 0, 0, 0, 1))
예제 #8
0
 def __init__(self, reload=None):
     super().__init__(title="Status")
     self.reload = reload
     self.matrix_model_text = ui.Text(readonly=True)
     self.matrix_channels_text = ui.Text(readonly=True)
     self.hvsrc_model_text = ui.Text(readonly=True)
     self.vsrc_model_text = ui.Text(readonly=True)
     self.lcr_model_text = ui.Text(readonly=True)
     self.elm_model_text = ui.Text(readonly=True)
     self.table_model_text = ui.Text(readonly=True)
     self.table_state_text = ui.Text(readonly=True)
     self.env_model_text = ui.Text(readonly=True)
     self.reload_status_button = ui.Button("&Reload",
                                           clicked=self.on_reload)
     self.layout = ui.Column(
         ui.GroupBox(title="Matrix",
                     layout=ui.Column(
                         ui.Row(ui.Label("Model:"),
                                self.matrix_model_text,
                                stretch=(1, 7)),
                         ui.Row(ui.Label("Closed channels:"),
                                self.matrix_channels_text,
                                stretch=(1, 7)))),
         ui.GroupBox(title="HVSource",
                     layout=ui.Row(ui.Label("Model:"),
                                   self.hvsrc_model_text,
                                   stretch=(1, 7))),
         ui.GroupBox(title="VSource",
                     layout=ui.Row(ui.Label("Model:"),
                                   self.vsrc_model_text,
                                   stretch=(1, 7))),
         ui.GroupBox(title="LCRMeter",
                     layout=ui.Row(ui.Label("Model:"),
                                   self.lcr_model_text,
                                   stretch=(1, 7))),
         ui.GroupBox(title="Electrometer",
                     layout=ui.Row(ui.Label("Model:"),
                                   self.elm_model_text,
                                   stretch=(1, 7))),
         ui.GroupBox(title="Table",
                     layout=ui.Column(
                         ui.Row(ui.Label("Model:"),
                                self.table_model_text,
                                stretch=(1, 7)),
                         ui.Row(ui.Label("State:"),
                                self.table_state_text,
                                stretch=(1, 7)))),
         ui.GroupBox(title="Environment Box",
                     layout=ui.Column(
                         ui.Row(ui.Label("Model:"),
                                self.env_model_text,
                                stretch=(1, 7)))), ui.Spacer(),
         self.reload_status_button)
예제 #9
0
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self.title = "Position"
     self._pos_x_label = PositionLabel()
     self._pos_y_label = PositionLabel()
     self._pos_z_label = PositionLabel()
     self.layout = ui.Row(ui.Column(
         ui.Label(text="X", tool_tip="X axis position."),
         ui.Label(text="Y", tool_tip="Y axis position."),
         ui.Label(text="Z", tool_tip="Z axis position.")),
                          ui.Column(self._pos_x_label, self._pos_y_label,
                                    self._pos_z_label),
                          stretch=(1, 1))
예제 #10
0
 def __init__(self, joystick_toggled=None, control_clicked=None, **kwargs):
     super().__init__(**kwargs)
     self.title = "Table"
     self.checkable = True
     self._joystick_button = ToggleButton(text="Joystick",
                                          tool_tip="Toggle table joystick",
                                          checkable=True,
                                          toggled=self.on_joystick_toggled)
     self._position_widget = PositionWidget()
     self._calibration_widget = CalibrationWidget()
     self._control_button = ui.Button(
         text="Control...",
         tool_tip="Open table controls dialog.",
         clicked=self.on_control_clicked)
     self.layout = ui.Row(self._position_widget,
                          self._calibration_widget,
                          ui.Spacer(),
                          ui.Column(ui.Spacer(), self._control_button,
                                    self._joystick_button, ui.Spacer()),
                          stretch=(0, 0, 1, 0))
     # Callbacks
     self.joystick_toggled = joystick_toggled
     self.control_clicked = control_clicked
     self._joystick_limits = [0, 0, 0]
     self.calibration_valid = False
예제 #11
0
 def __init__(self, position_picked=None, absolute_move=None):
     super().__init__()
     self.position_picked = position_picked
     self.absolute_move = absolute_move
     self.positions_tree = ui.Tree(
         header=("Name", "X", "Y", "Z", "Comment"),
         root_is_decorated=False,
         selected=self.on_position_selected,
         double_clicked=self.on_position_double_clicked)
     self.pick_button = ui.Button(
         text="Assign &Position",
         tool_tip="Assign current table position to selected position item",
         clicked=self.on_pick_position,
         enabled=False)
     self.add_button = ui.Button(text="&Add",
                                 tool_tip="Add new position item",
                                 clicked=self.on_add_position)
     self.edit_button = ui.Button(text="&Edit",
                                  tool_tip="Edit selected position item",
                                  clicked=self.on_edit_position,
                                  enabled=False)
     self.remove_button = ui.Button(
         text="&Remove",
         tool_tip="Remove selected position item",
         clicked=self.on_remove_position,
         enabled=False)
     self.move_button = ui.Button(text="&Move",
                                  tool_tip="Move to selected position",
                                  clicked=self.on_move,
                                  enabled=False)
     self.append(self.positions_tree)
     self.append(
         ui.Column(self.pick_button, self.move_button, ui.Spacer(),
                   self.add_button, self.edit_button, self.remove_button))
     self.stretch = 1, 0
예제 #12
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.name_text = ui.Text(value="Unnamed")
     self.x_number = ui.Number(value=0.,
                               minimum=0.,
                               maximum=1000.,
                               decimals=3,
                               suffix="mm")
     self.y_number = ui.Number(value=0.,
                               minimum=0.,
                               maximum=1000.,
                               decimals=3,
                               suffix="mm")
     self.z_number = ui.Number(value=0.,
                               minimum=0.,
                               maximum=1000.,
                               decimals=3,
                               suffix="mm")
     self.comment_text = ui.Text()
     self.button_box = ui.DialogButtonBox(buttons=("ok", "cancel"),
                                          accepted=self.accept,
                                          rejected=self.reject)
     self.layout = ui.Column(
         ui.Label("Name", tool_tip="Position name"), self.name_text,
         ui.Label("X", tool_tip="Position X coordinate"), self.x_number,
         ui.Label("Y", tool_tip="Position Y coordinate"), self.y_number,
         ui.Label("Z", tool_tip="Position Z coordinate"), self.z_number,
         ui.Label("Comment", tool_tip="Optional position comment"),
         self.comment_text, self.button_box)
예제 #13
0
 def __init__(self, position_picked=None, absolute_move=None):
     super().__init__()
     self.position_picked = position_picked
     self.absolute_move = absolute_move
     self.contacts_tree = ui.Tree(header=("Contact", "X", "Y", "Z", None),
                                  selected=self.on_contacts_selected)
     self.contacts_tree.fit()
     self.pick_button = ui.Button(
         text="Assign &Position",
         tool_tip="Assign current table position to selected position item",
         clicked=self.on_pick_position,
         enabled=False)
     self.calculate_button = ui.Button(text="&Calculate",
                                       clicked=self.on_calculate,
                                       enabled=False)
     self.move_button = ui.Button(text="&Move",
                                  tool_tip="Move to selected position",
                                  clicked=self.on_move,
                                  enabled=False)
     self.reset_button = ui.Button(text="&Reset",
                                   clicked=self.on_reset,
                                   enabled=False)
     self.reset_all_button = ui.Button(text="Reset &All",
                                       clicked=self.on_reset_all)
     self.append(self.contacts_tree)
     self.append(
         ui.Column(self.pick_button, self.move_button,
                   self.calculate_button, ui.Spacer(), self.reset_button,
                   self.reset_all_button))
     self.stretch = 1, 0
예제 #14
0
 def __init__(self, *args, table_move=None, table_contact=None, **kwargs):
     super().__init__(*args, **kwargs)
     self.table_move = table_move
     self.table_contact = table_contact
     self.use_table = False
     self._position_valid = False
     self.title = "Contact"
     self._position_widget = PositionWidget()
     self._position_widget.title = "Contact Position"
     self._move_button = ui.Button(
         text="Move",
         tool_tip="Move table to position with safe Z position.",
         clicked=self.on_move,
         enabled=False)
     self._contact_button = ui.Button(
         text="Contact",
         tool_tip="Move table to position and contact with sample.",
         clicked=self.on_contact,
         enabled=False)
     self.layout.insert(
         2,
         ui.Row(self._position_widget,
                ui.GroupBox(title="Table Control",
                            layout=ui.Column(self._move_button,
                                             self._contact_button,
                                             ui.Spacer())),
                ui.Spacer(vertical=False),
                stretch=(0, 0, 1)))
     self.layout.insert(3, ui.Spacer())
     self.layout.stretch = 0, 0, 0, 1
예제 #15
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self._step_size_number = ui.Number(value=0.,
                                        minimum=0.,
                                        maximum=1000.,
                                        decimals=3,
                                        suffix="mm")
     self._z_limit_number = ui.Number(value=0.,
                                      minimum=0.,
                                      maximum=1000.,
                                      decimals=3,
                                      suffix="mm",
                                      visible=False)
     self._step_color_text = ui.Text()
     self._button_box = ui.DialogButtonBox(buttons=("ok", "cancel"),
                                           accepted=self.accept,
                                           rejected=self.reject)
     self.layout = ui.Column(
         ui.Label("Size", tool_tip="Step size in millimeters"),
         self._step_size_number,
         ui.Label("Z-Limit",
                  tool_tip="Z-Limit in millimeters",
                  visible=False), self._z_limit_number,
         ui.Label("Color", tool_tip="Color code for step"),
         self._step_color_text, self._button_box)
예제 #16
0
    def __init__(self):
        super().__init__(title="Environment")

        # Data series
        self.box_temperature_series = []
        self.chuck_temperature_series = []
        self.box_humidity_series = []

        # Plot
        self.plot = ui.Plot(legend="right")
        self.plot.add_axis("x", align="bottom", type="datetime")
        self.plot.add_axis("y1",
                           align="left",
                           text="Temperature [°C]",
                           color="red")
        self.plot.add_axis("y2",
                           align="right",
                           text="Humidity [%rH]",
                           color="blue")
        self.plot.add_series("box_temperature",
                             "x",
                             "y1",
                             text="Box Temperature",
                             color="red")
        self.plot.add_series("chuck_temperature",
                             "x",
                             "y1",
                             text="Chuck Temperature",
                             color="magenta")
        self.plot.add_series("box_humidity",
                             "x",
                             "y2",
                             text="Box Humidity",
                             color="blue")

        # Inputs
        self.box_temperature_number = ui.Number(suffix="°C",
                                                decimals=1,
                                                readonly=True)
        self.box_humidity_number = ui.Number(suffix="%rH",
                                             decimals=1,
                                             readonly=True)
        self.chuck_temperature_number = ui.Number(suffix="°C",
                                                  decimals=1,
                                                  readonly=True)
        self.box_lux_number = ui.Number(suffix="Lux",
                                        decimals=1,
                                        readonly=True)
        self.box_light_text = ui.Text(readonly=True)
        self.box_door_text = ui.Text(readonly=True)

        # Layout
        self.layout = ui.Column(
            self.plot,
            ui.Label("Box Temperature"), self.box_temperature_number,
            ui.Label("Box Humidity"), self.box_humidity_number,
            ui.Label("Chuck Temperature"), self.chuck_temperature_number,
            ui.Label("Box Light"), self.box_lux_number,
            ui.Label("Box Light State"), self.box_light_text,
            ui.Label("Box Door State"), self.box_door_text, ui.Spacer())
예제 #17
0
파일: panel.py 프로젝트: mwulansa/comet-pqc
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.title_label = ui.Label(
         stylesheet="font-size: 16px; font-weight: bold; height: 32px;")
     self.title_label.qt.setTextFormat(QtCore.Qt.RichText)
     self.description_label = ui.Label()
     self.layout = ui.Column(self.title_label, self.description_label,
                             ui.Spacer())
예제 #18
0
 def __init__(self, *args, table_move_to=None, table_contact=None, **kwargs):
     super().__init__(*args, **kwargs)
     self.table_move_to = table_move_to
     self.table_contact = table_contact
     self.title = "Contact"
     self.pos_x_label = PositionLabel()
     self.pos_y_label = PositionLabel()
     self.pos_z_label = PositionLabel()
     # self.move_to_button = ui.Button(
     #     text="Move to",
     #     tool_tip="Move table to position with safe Z distance.",
     #     clicked=self.on_move_to,
     #     enabled=False
     # )
     self.contact_button = ui.Button(
         text="Contact",
         tool_tip="Move table to position and contact.",
         clicked=self.on_contact,
         enabled=False
     )
     self.layout.insert(2, ui.Row(
         ui.GroupBox(
             title="Position",
             layout=ui.Row(
                 ui.Column(
                     ui.Label("X"),
                     ui.Label("Y"),
                     ui.Label("Z")
                 ),
                 ui.Column(
                     self.pos_x_label,
                     self.pos_y_label,
                     self.pos_z_label,
                 )
             )
         ),
         ui.GroupBox(
             title="Table Actions",
             layout=ui.Column(
                 # self.move_to_button,
                 self.contact_button
             )
         ),
         ui.Spacer(vertical=False),
     ))
예제 #19
0
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self.title = "Calibration"
     self._cal_x_label = CalibrationLabel("cal")
     self._cal_y_label = CalibrationLabel("cal")
     self._cal_z_label = CalibrationLabel("cal")
     self._rm_x_label = CalibrationLabel("rm")
     self._rm_y_label = CalibrationLabel("rm")
     self._rm_z_label = CalibrationLabel("rm")
     self.layout = ui.Row(ui.Column(
         ui.Label(text="X", tool_tip="X axis calibration state."),
         ui.Label(text="Y", tool_tip="Y axis calibration state."),
         ui.Label(text="Z", tool_tip="Z axis calibration state.")),
                          ui.Column(self._cal_x_label, self._cal_y_label,
                                    self._cal_z_label),
                          ui.Column(self._rm_x_label, self._rm_y_label,
                                    self._rm_z_label),
                          stretch=(1, 1, 1))
예제 #20
0
 def __init__(self, position_picked=None, **kwargs):
     super().__init__(**kwargs)
     self.position_picked = position_picked
     self._name_text = ui.Text(value="Unnamed")
     self._x_number = ui.Number(value=0.,
                                minimum=0.,
                                maximum=1000.,
                                decimals=3,
                                suffix="mm")
     self._y_number = ui.Number(value=0.,
                                minimum=0.,
                                maximum=1000.,
                                decimals=3,
                                suffix="mm")
     self._z_number = ui.Number(value=0.,
                                minimum=0.,
                                maximum=1000.,
                                decimals=3,
                                suffix="mm")
     self._comment_text = ui.Text()
     self._assign_button = ui.Button(
         text="Assign Position",
         tool_tip="Assign current table position.",
         clicked=self.on_assign_clicked)
     self._button_box = ui.DialogButtonBox(buttons=("ok", "cancel"),
                                           accepted=self.accept,
                                           rejected=self.reject)
     self.layout = ui.Column(
         ui.Label("Name", tool_tip="Position name"), self._name_text,
         ui.Row(
             ui.Column(ui.Label("X", tool_tip="Position X coordinate"),
                       self._x_number),
             ui.Column(ui.Label("Y", tool_tip="Position Y coordinate"),
                       self._y_number),
             ui.Column(ui.Label("Z", tool_tip="Position Z coordinate"),
                       self._z_number),
             ui.Column(
                 ui.Spacer(),
                 self._assign_button,
             )), ui.Label("Comment", tool_tip="Optional position comment"),
         self._comment_text, ui.Spacer(), self._button_box)
예제 #21
0
    def register_environment(self):
        self.status_env_chuck_temperature = ui.Text(value=NO_VALUE,
                                                    readonly=True)
        self.status_env_box_temperature = ui.Text(value=NO_VALUE,
                                                  readonly=True)
        self.status_env_box_humidity = ui.Text(value=NO_VALUE, readonly=True)

        self.bind("status_env_chuck_temperature",
                  self.status_env_chuck_temperature, NO_VALUE)
        self.bind("status_env_box_temperature",
                  self.status_env_box_temperature, NO_VALUE)
        self.bind("status_env_box_humidity", self.status_env_box_humidity,
                  NO_VALUE)

        self.status_panel.append(
            ui.GroupBox(title="Environment Status",
                        layout=ui.Column(
                            ui.Row(
                                ui.Column(ui.Label("Chuck temp."),
                                          self.status_env_chuck_temperature),
                                ui.Column(ui.Label("Box temp."),
                                          self.status_env_box_temperature),
                                ui.Column(ui.Label("Box humid."),
                                          self.status_env_box_humidity)))))

        def handler(state):
            if 'env_chuck_temperature' in state:
                value = state.get('env_chuck_temperature', )
                self.status_env_chuck_temperature.value = format_metric(
                    value, "°C", decimals=2)
            if 'env_box_temperature' in state:
                value = state.get('env_box_temperature')
                self.status_env_box_temperature.value = format_metric(
                    value, "°C", decimals=2)
            if 'env_box_humidity' in state:
                value = state.get('env_box_humidity')
                self.status_env_box_humidity.value = format_metric(value,
                                                                   "%rH",
                                                                   decimals=2)

        self.state_handlers.append(handler)
예제 #22
0
def main():
    app = comet.Application()
    app.title = "Measurement"

    def on_finish():
        start_button.enabled = True
        stop_button.enabled = False
        current_number.value = 0

    def on_reading(value):
        print(value)
        current_number.value = value

    def on_start():
        start_button.enabled = False
        stop_button.enabled = True
        process = app.processes.get("measure")
        process.start()

    def on_stop():
        start_button.enabled = False
        stop_button.enabled = False
        process = app.processes.get("measure")
        process.stop()

    def on_voltage(value):
        process = app.processes.get("measure")
        process.set('voltage', value)

    process = comet.Process(target=measure)
    process.finished = on_finish
    process.failed = ui.show_exception
    process.reading = on_reading
    app.processes.add("measure", process)

    voltage_number = ui.Number(value=0, minimum=0, maximum=1000, decimals=1, suffix="V", changed=on_voltage)
    current_number = ui.Number(readonly=True, value=0, decimals=3, suffix="mA", stylesheet="color: red")
    start_button = ui.Button(text="Start", clicked=on_start)
    stop_button = ui.Button(text="Stop", enabled=False, clicked=on_stop)

    l = ui.Column(
        ui.Label("Voltage"),
        voltage_number,
        ui.Label("Current"),
        current_number,
        start_button,
        stop_button,
        ui.Spacer()
    )
    app.layout = l

    return app.run()
예제 #23
0
 def __init__(self, context, table_enabled):
     super().__init__()
     self.title = "Start Sequence"
     self._contact_checkbox = ui.CheckBox(
         text="Move table and contact with Probe Card",
         checked=True,
         enabled=table_enabled)
     self._position_checkbox = ui.CheckBox(
         text="Move table after measurements",
         checked=False,
         enabled=table_enabled,
         changed=self.on_position_checkbox_toggled)
     self._positions_combobox = PositionsComboBox(enabled=False)
     self._operator_combobox = OperatorWidget()
     self._output_combobox = WorkingDirectoryWidget()
     self._button_box = ui.DialogButtonBox(buttons=("yes", "no"),
                                           accepted=self.accept,
                                           rejected=self.reject)
     self._button_box.qt.button(
         self._button_box.QtClass.Yes).setAutoDefault(False)
     self._button_box.qt.button(
         self._button_box.QtClass.No).setDefault(True)
     self.layout = ui.Column(
         ui.Label(text=self._create_message(context)),
         ui.GroupBox(title="Table",
                     layout=ui.Column(
                         self._contact_checkbox,
                         ui.Row(self._position_checkbox,
                                self._positions_combobox), ui.Spacer())),
         ui.Row(ui.GroupBox(title="Operator",
                            layout=self._operator_combobox),
                ui.GroupBox(title="Working Directory",
                            layout=self._output_combobox),
                stretch=(2, 3)),
         self._button_box,
         stretch=(1, 0, 0, 0))
예제 #24
0
 def __init__(self, restore=None):
     super().__init__(title="Measurement")
     self.restore = restore
     self.panels = PanelStack()
     self.measure_restore_button = ui.Button(
         text="Restore Defaults",
         tool_tip="Restore default measurement parameters.",
         clicked=self.on_measure_restore
     )
     self.measure_controls = ui.Row(
         self.measure_restore_button,
         ui.Spacer(),
         visible=False
     )
     self.layout = ui.Column(
         self.panels,
         self.measure_controls,
         stretch=(1, 0)
     )
예제 #25
0
def main():
    app = comet.Application()
    app.title = "Plot"
    app.about = "An example plot application."

    def on_reset():
        for series in plot.series.values():
            series.clear()
        plot.fit()

    def on_reading(value):
        time, temp, humid = value
        plot.series.get("temp").append(time, temp)
        plot.series.get("humid").append(time, humid)
        if plot.zoomed:
            plot.update("x")
        else:
            plot.fit()

    plot = ui.Plot(legend="bottom")
    plot.add_axis("x", align="bottom", type="datetime")
    plot.add_axis("y1", align="left", text="Temperature [°C]", color="red")
    plot.add_axis("y2", align="right", text="Humidity [%rH]", color="blue")
    plot.add_series("temp", "x", "y1", text="Temperature", color="red")
    plot.add_series("humid", "x", "y2", text="Humidity", color="blue")

    reset_button = ui.Button(text="Reset", clicked=on_reset)

    app.layout = ui.Column(plot, reset_button)

    process = comet.Process(target=fake_data)
    process.reading = on_reading
    process.failed = ui.show_exception
    process.start()
    app.processes.add("process", process)

    return app.run()
예제 #26
0
    def __init__(self):
        super().__init__(title="Table")
        self.temporary_z_limit_changed = None
        self._steps_tree = ui.Tree(header=("Size", "Z-Limit", "Color"),
                                   root_is_decorated=False)
        # Hide Z-Limit column
        self._steps_tree.qt.setColumnHidden(1, True)
        self._steps_tree.selected = self.on_position_selected
        self._steps_tree.double_clicked = self.on_steps_tree_double_clicked
        self._steps_tree.qt.setItemDelegateForColumn(
            0, ItemDelegate(self._steps_tree.qt))
        self._steps_tree.qt.setItemDelegateForColumn(
            1, ItemDelegate(self._steps_tree.qt))
        self._add_step_button = ui.Button(text="&Add",
                                          tool_tip="Add table step",
                                          clicked=self.on_add_step_clicked)
        self._edit_step_button = ui.Button(text="&Edit",
                                           tool_tip="Edit selected table step",
                                           enabled=False,
                                           clicked=self.on_edit_step_clicked)
        self._remove_step_button = ui.Button(
            text="&Remove",
            tool_tip="Remove selected table step",
            enabled=False,
            clicked=self.on_remove_step_clicked)
        self._z_limit_movement_number = ui.Number(
            minimum=0,
            maximum=128.0,
            decimals=3,
            suffix="mm",
            changed=self.on_z_limit_movement_changed)

        def create_number():
            return ui.Number(minimum=0,
                             maximum=1000.0,
                             decimals=3,
                             suffix="mm")

        self._probecard_limit_x_maximum_number = create_number()
        self._probecard_limit_y_maximum_number = create_number()
        self._probecard_limit_z_maximum_number = create_number()
        self._probecard_limit_z_maximum_checkbox = ui.CheckBox(
            text="Temporary Z-Limit",
            tool_tip="Select to show temporary Z-Limit notice.")
        self._joystick_limit_x_maximum_number = create_number()
        self._joystick_limit_y_maximum_number = create_number()
        self._joystick_limit_z_maximum_number = create_number()
        self._probecard_contact_delay_number = ui.Number(minimum=0,
                                                         maximum=3600,
                                                         decimals=2,
                                                         step=.1,
                                                         suffix="s")
        self._recontact_overdrive_number = ui.Number(minimum=0,
                                                     maximum=0.025,
                                                     decimals=3,
                                                     step=.001,
                                                     suffix="mm")
        self.layout = ui.Column(
            ui.GroupBox(title="Control Steps (mm)",
                        layout=ui.Row(self._steps_tree,
                                      ui.Column(self._add_step_button,
                                                self._edit_step_button,
                                                self._remove_step_button,
                                                ui.Spacer()),
                                      stretch=(1, 0))),
            ui.GroupBox(title="Movement Z-Limit",
                        layout=ui.Column(self._z_limit_movement_number)),
            ui.GroupBox(title="Probe Card Limts",
                        layout=ui.Row(
                            ui.Column(ui.Label("X"),
                                      self._probecard_limit_x_maximum_number),
                            ui.Column(ui.Label("Y"),
                                      self._probecard_limit_y_maximum_number),
                            ui.Column(ui.Label("Z"),
                                      self._probecard_limit_z_maximum_number),
                            ui.Column(
                                ui.Label(),
                                ui.Label("Maximum"),
                            ), ui.Spacer(),
                            ui.Column(
                                ui.Label(),
                                self._probecard_limit_z_maximum_checkbox,
                            ))),
            ui.GroupBox(title="Joystick Limits",
                        layout=ui.Row(
                            ui.Column(ui.Label("X"),
                                      self._joystick_limit_x_maximum_number),
                            ui.Column(ui.Label("Y"),
                                      self._joystick_limit_y_maximum_number),
                            ui.Column(ui.Label("Z"),
                                      self._joystick_limit_z_maximum_number),
                            ui.Column(
                                ui.Label(),
                                ui.Label("Maximum"),
                            ), ui.Spacer())),
            ui.Row(ui.GroupBox(title="Probecard Contact Delay",
                               layout=ui.Row(
                                   self._probecard_contact_delay_number)),
                   ui.GroupBox(title="Re-Contact Z-Overdrive (1x)",
                               layout=ui.Row(
                                   self._recontact_overdrive_number)),
                   stretch=(0, 1)),
            stretch=(1, 0, 0, 0, 0))
예제 #27
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title = "Frequency Scan"

        self.register_vsource()
        self.register_lcr()
        self.register_environment()

        self.plot = ui.Plot(height=300, legend="right")
        self.plot.add_axis("x", align="bottom", text="Voltage [V] (abs)")
        self.plot.add_axis("y", align="right", text="Capacitance [pF]")
        self.plot.add_series("lcr", "x", "y", text="LCR", color="blue")
        self.data_tabs.insert(0, ui.Tab(title="CV Curve", layout=self.plot))

        self.bias_voltage = ui.Number(decimals=3, suffix="V")

        self.hvsrc_current_compliance = ui.Number(decimals=3, suffix="uA")

        self.lcr_frequency_start = ui.Number(minimum=0,
                                             decimals=3,
                                             suffix="Hz")
        self.lcr_frequency_stop = ui.Number(minimum=0,
                                            decimals=3,
                                            suffix="MHz")
        self.lcr_frequency_steps = ui.Number(minimum=1,
                                             maximum=1000,
                                             decimals=0)
        self.lcr_amplitude = ui.Number(minimum=0, decimals=3, suffix="mV")

        self.bind("bias_voltage", self.bias_voltage, 0, unit="V")
        self.bind("hvsrc_current_compliance",
                  self.hvsrc_current_compliance,
                  0,
                  unit="uA")
        self.bind("lcr_frequency_start",
                  self.lcr_frequency_start,
                  0,
                  unit="Hz")
        self.bind("lcr_frequency_stop", self.lcr_frequency_stop, 0, unit="MHz")
        self.bind("lcr_frequency_steps", self.lcr_frequency_steps, 1)
        self.bind("lcr_amplitude", self.lcr_amplitude, 0, unit="mV")

        self.general_tab.layout = ui.Row(
            ui.GroupBox(title="HV Source",
                        layout=ui.Column(ui.Label(text="Bias Voltage"),
                                         self.bias_voltage,
                                         ui.Label(text="Current Compliance"),
                                         self.hvsrc_current_compliance,
                                         ui.Spacer())),
            ui.GroupBox(title="LCR",
                        layout=ui.Column(
                            ui.Label(text="AC Frequency Start"),
                            self.lcr_frequency_start,
                            ui.Label(text="AC Frequency Stop"),
                            self.lcr_frequency_stop,
                            ui.Label(text="AC Frequency Steps (log10)"),
                            self.lcr_frequency_steps,
                            ui.Label(text="AC Amplitude"), self.lcr_amplitude,
                            ui.Spacer())),
            ui.Spacer(),
            stretch=(1, 1, 1))

        fahrad = comet.ureg('F')
        volt = comet.ureg('V')

        self.series_transform['lcr'] = lambda x, y: ((x * volt).to('V').m,
                                                     (y * fahrad).to('pF').m)
        self.series_transform['xfit'] = self.series_transform.get('lcr')
예제 #28
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title = "CV Ramp (V Source)"

        self.register_hvsource()
        self.register_lcr()
        self.register_environment()

        self.plot = ui.Plot(height=300, legend="right")
        self.plot.add_axis("x", align="bottom", text="Voltage [V] (abs)")
        self.plot.add_axis("y", align="right", text="Capacitance [pF]")
        self.plot.add_series("lcr", "x", "y", text="LCR Cp", color="blue")
        self.data_tabs.insert(0, ui.Tab(title="CV Curve", layout=self.plot))

        self.plot2 = ui.Plot(height=300, legend="right")
        self.plot2.add_axis("x", align="bottom", text="Voltage [V] (abs)")
        self.plot2.add_axis("y", align="right", text="1/Capacitance² [1/F²]")
        self.plot2.axes.get("y").qt.setLabelFormat("%G")
        self.plot2.add_series("lcr2", "x", "y", text="LCR Cp", color="blue")
        self.data_tabs.insert(1, ui.Tab(title="1/C² Curve", layout=self.plot2))

        self.voltage_start = ui.Number(decimals=3, suffix="V")
        self.voltage_stop = ui.Number(decimals=3, suffix="V")
        self.voltage_step = ui.Number(minimum=0,
                                      maximum=200,
                                      decimals=3,
                                      suffix="V")
        self.waiting_time = ui.Number(minimum=0, decimals=2, suffix="s")

        self.vsrc_current_compliance = ui.Number(decimals=3, suffix="uA")

        self.lcr_frequency = ui.Number(value=1,
                                       minimum=0.020,
                                       maximum=20e3,
                                       decimals=3,
                                       suffix="kHz")
        self.lcr_amplitude = ui.Number(minimum=0, decimals=3, suffix="mV")

        self.bind("bias_voltage_start", self.voltage_start, 0, unit="V")
        self.bind("bias_voltage_stop", self.voltage_stop, 100, unit="V")
        self.bind("bias_voltage_step", self.voltage_step, 1, unit="V")
        self.bind("waiting_time", self.waiting_time, 1, unit="s")
        self.bind("vsrc_current_compliance",
                  self.vsrc_current_compliance,
                  0,
                  unit="uA")
        self.bind("lcr_frequency", self.lcr_frequency, 1.0, unit="kHz")
        self.bind("lcr_amplitude", self.lcr_amplitude, 250, unit="mV")

        self.general_tab.layout = ui.Row(
            ui.GroupBox(title="V Source Ramp",
                        layout=ui.Column(ui.Label(text="Start"),
                                         self.voltage_start,
                                         ui.Label(text="Stop"),
                                         self.voltage_stop,
                                         ui.Label(text="Step"),
                                         self.voltage_step,
                                         ui.Label(text="Waiting Time"),
                                         self.waiting_time, ui.Spacer())),
            ui.GroupBox(title="V Source",
                        layout=ui.Column(ui.Label(text="Compliance"),
                                         self.vsrc_current_compliance,
                                         ui.Spacer())),
            ui.GroupBox(title="LCR",
                        layout=ui.Column(ui.Label(text="AC Frequency"),
                                         self.lcr_frequency,
                                         ui.Label(text="AC Amplitude"),
                                         self.lcr_amplitude, ui.Spacer())),
            stretch=(1, 1, 1))

        fahrad = comet.ureg('F')
        volt = comet.ureg('V')

        self.series_transform['lcr'] = lambda x, y: ((x * volt).to('V').m,
                                                     (y * fahrad).to('pF').m)
예제 #29
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title = "IV Ramp Bias Elm"

        self.register_vsource()
        self.register_hvsource()
        self.register_electrometer()
        self.register_environment()

        self.plot = ui.Plot(height=300, legend="right")
        self.plot.add_axis("x", align="bottom", text="Voltage [V]")
        self.plot.add_axis("y", align="right", text="Current [uA]")
        self.plot.add_series("elm",
                             "x",
                             "y",
                             text="Electrometer",
                             color="blue")
        self.plot.add_series("xfit", "x", "y", text="Fit", color="magenta")
        self.data_tabs.insert(0, ui.Tab(title="IV Curve", layout=self.plot))

        self.voltage_start = ui.Number(decimals=3, suffix="V")
        self.voltage_stop = ui.Number(decimals=3, suffix="V")
        self.voltage_step = ui.Number(minimum=0,
                                      maximum=200,
                                      decimals=3,
                                      suffix="V")
        self.waiting_time = ui.Number(minimum=0, decimals=2, suffix="s")
        self.bias_voltage = ui.Number(decimals=3, suffix="V")
        self.bias_mode = ui.ComboBox(["constant", "offset"])

        self.hvsrc_current_compliance = ui.Number(decimals=3, suffix="uA")
        self.hvsrc_accept_compliance = ui.CheckBox("Accept Compliance")
        self.vsrc_current_compliance = ui.Number(decimals=3, suffix="uA")
        self.vsrc_accept_compliance = ui.CheckBox("Accept Compliance")

        self.bind("voltage_start", self.voltage_start, 0, unit="V")
        self.bind("voltage_stop", self.voltage_stop, 0, unit="V")
        self.bind("voltage_step", self.voltage_step, 0, unit="V")
        self.bind("waiting_time", self.waiting_time, 1, unit="s")
        self.bind("bias_voltage", self.bias_voltage, 0, unit="V")
        self.bind("bias_mode", self.bias_mode, "constant")
        self.bind("hvsrc_current_compliance",
                  self.hvsrc_current_compliance,
                  0,
                  unit="uA")
        self.bind("hvsrc_accept_compliance", self.hvsrc_accept_compliance,
                  False)
        self.bind("vsrc_current_compliance",
                  self.vsrc_current_compliance,
                  0,
                  unit="uA")
        self.bind("vsrc_accept_compliance", self.vsrc_accept_compliance, False)

        self.general_tab.layout = ui.Row(
            ui.GroupBox(title="HV Source Ramp",
                        layout=ui.Column(ui.Label(text="Start"),
                                         self.voltage_start,
                                         ui.Label(text="Stop"),
                                         self.voltage_stop,
                                         ui.Label(text="Step"),
                                         self.voltage_step,
                                         ui.Label(text="Waiting Time"),
                                         self.waiting_time, ui.Spacer())),
            ui.GroupBox(title="V Source Bias",
                        layout=ui.Column(ui.Label(text="Bias Voltage"),
                                         self.bias_voltage,
                                         ui.Label(text="Bias Compliance"),
                                         self.vsrc_current_compliance,
                                         self.vsrc_accept_compliance,
                                         ui.Label(text="Bias Mode"),
                                         self.bias_mode, ui.Spacer())),
            ui.GroupBox(title="HV Source",
                        layout=ui.Column(ui.Label(text="Compliance"),
                                         self.hvsrc_current_compliance,
                                         self.hvsrc_accept_compliance,
                                         ui.Spacer())),
            stretch=(1, 1, 1))

        ampere = comet.ureg('A')
        volt = comet.ureg('V')

        self.series_transform['elm'] = lambda x, y: ((x * volt).to('V').m,
                                                     (y * ampere).to('uA').m)
        self.series_transform['xfit'] = self.series_transform.get('elm')
예제 #30
0
def main():
    app = comet.Application()

    def on_activated(item):
        ui.show_info(text=format(item.value))

    def on_selected(item):
        print("Item", format(item.value))

    table = ui.Table()
    table.header = "Name", "Status", "HV", "Current", "Temp.", "Calib."
    table.stretch = True
    table.activated = on_activated
    table.selected = on_selected
    for i in range(10):
        table.append([
            f"Unnamed{i}", "OK", "", "n/a", "n/a",
            f"{random.random()*1000:.0f} ohm"
        ])
        # First column user checkable
        table[i][0].checkable = True
        table[i][0].checked = random.choice([True, False])
        # First column editabled
        table[i][0].readonly = False

    table.qt.setCurrentItem(table[0][0].qt)
    table.fit()

    def on_activated(index, item):
        ui.show_info(text=format(item[index].value))

    def on_selected(item):
        print("Item", format(item[0].value))

    tree = ui.Tree()
    tree.header = "Measurement", "Status"
    tree.activated = on_activated
    tree.selected = on_selected
    tree.append(["Flute 1", "OK"])
    tree.clear()
    tree.append(["Flute 2", "OK"])
    tree.insert(0, ["Flute 3", "Meas..."])
    tree[0][0].checked = True
    tree[0][1].color = "red"
    tree[0][1].background = "blue"
    #tree[0][1].color = None
    tree[0][1].background = None

    tree.append(["Flute 4", "OK"])
    tree.append(["Flute 5", "OK"])
    tree.append(["Flute 6"])

    tree.qt.setCurrentItem(tree[2].qt)

    tree.remove(tree[3])

    for i, item in enumerate(tree):
        if i == 1:
            item.expanded = True
        item[0].checked = True
        item.append(["Test 1", "OK"])
        item.append(["Test 2", "OK"])
        item.insert(0, ["Test 3", "OK"])
        item.children[0][0].checked = True
        item.children[1][0].checked = False
        item.children[2][0].checked = True

    for item in tree:
        print(item[0].checked)
        for item in item.children:
            print(item[0].checked)

    def measure(process):
        while process.running:
            for i in range(10):
                value = random.choice([True, False])
                process.emit('hv', i, value)
                value = random.uniform(22., 24.)
                process.emit('temp', i, value)
            for i in range(2):
                value = random.choice(["OK", "FAIL"])
                process.emit('status', i, value)
            time.sleep(1)

    def on_hv(i, value):
        item = table[i][2]
        if table[i][0].checked:
            item.value = {True: "ON", False: "OFF"}[value]
            item.color = {True: "green", False: "red"}[value]
            item.bold = not value
        else:
            item.value = None

    def on_temp(i, value):
        item = table[i][4]
        if table[i][0].checked:
            item.value = value
            item.color = "green"
            if item.value < 22.5:
                item.color = "red"
        else:
            item.value = None

    def on_status(i, value):
        color = {"OK": "green", "FAIL": "red"}[value]
        tree[i][1].value = value
        tree[i][1].color = color
        tree[i][1].bold = value == "FAIL"
        for item in tree[i].children:
            if item[0].checked:
                item[1].value = value
                item[1].color = color
                item[1].bold = value == "FAIL"
            else:
                item[1].value = None

    app.layout = ui.Column(table, tree)

    process = comet.Process(target=measure)
    process.hv = on_hv
    process.temp = on_temp
    process.status = on_status
    app.processes.add("process", process)
    process.start()

    return app.run()