def test_parameters_8(): s1 = params.StormXMLObject() s2 = params.StormXMLObject() p1 = params.Parameter(name="aa", order=2) p2 = params.Parameter(name="bb", order=1) p3 = params.Parameter(name="cc", order=2) s1.addSubSection("dd", s2) s1.add(p1) s1.add(p2) s1.add(p3) assert (s1.getSortedAttrs() == ['dd', 'bb', 'aa', 'cc'])
def __init__(self, configuration=None, **kwds): super().__init__(**kwds) self.buttons = [] self.filter_fn = None self.parameters = params.StormXMLObject() self.scan_fn = None # Load UI self.ui = filterWheelUi.Ui_Dialog() self.ui.setupUi(self) # Create buttons. layout = QtWidgets.QHBoxLayout(self.ui.filtersGroupBox) layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(1) filter_names = configuration.get("filters").split(",") for name in filter_names: button = QtWidgets.QPushButton(name, self.ui.filtersGroupBox) button.setAutoExclusive(True) button.setCheckable(True) button.clicked.connect(self.handleClicked) layout.addWidget(button) self.buttons.append(button) # Set to minimum size & fix. self.adjustSize() self.setFixedSize(self.width(), self.height()) self.parameters.add( params.ParameterSetString(description="Current filter", name="current_filter", value=filter_names[0], allowed=filter_names)) self.setEnabled(False)
def test_parameters_7(): p1 = params.StormXMLObject() v1 = params.ParameterSimple("foo", "bar") p1.add(v1) p2 = params.StormXMLObject() p2.add("foo", p1.getp("foo")) p3 = params.StormXMLObject() p3.add("foo", p1.getp("foo").copy()) v1.setv("baz") assert (p1.get("foo") == "baz") assert (p2.get("foo") == "baz") assert (p3.get("foo") == "bar")
def __init__(self, configuration = None, **kwds): """ This initializes things and sets up the UI of the power control dialog box. """ super().__init__(**kwds) self.channels = False self.configuration = configuration self.directory = None self.exp_channels = None self.ilm_functionality = None self.linear_channels = None self.file_channels = None self.parameters = params.StormXMLObject() self.timing_functionality = None self.use_was_checked = False self.which_checked = [] # Add progression parameters. self.parameters.add(params.ParameterSetBoolean(name = "use_progressions", value = False, is_mutable = False)) self.parameters.add(params.ParameterStringFilename(description = "Progression file name", name = "pfile_name", value = "", use_save_dialog = False)) # UI setup self.ui = progressionUi.Ui_Dialog() self.ui.setupUi(self) self.ui.loadFileButton.clicked.connect(self.handleLoadFile) self.ui.progressionsCheckBox.stateChanged.connect(self.handleProgressionsCheck)
def __init__(self, configuration = None, **kwds): super().__init__(**kwds) self.parameters = params.StormXMLObject() self.retracted_z = configuration.get("retracted_z") self.z_stage_fn = None # Load UI self.ui = zStageUi.Ui_Dialog() self.ui.setupUi(self) self.ui.homeButton.clicked.connect(self.handleHomeButton) self.ui.retractButton.clicked.connect(self.handleRetractButton) self.ui.zeroButton.clicked.connect(self.handleZeroButton) self.ui.zPosDoubleSpinBox.valueChanged.connect(self.handleZValueChanged) self.setZStep(configuration.get("single_step")) # Set to minimum size & fix. self.adjustSize() self.setFixedSize(self.width(), self.height()) # Add parameters. self.parameters.add(params.ParameterRangeFloat(description ="Z Stage step size", name = "z_stage_step", value = configuration.get("single_step"), min_value = 0.001, max_value = 1.0)) self.setEnabled(False)
def __init__(self, module_params=None, qt_settings=None, **kwds): super().__init__(**kwds) self.analyzers = [] self.basename = None self.feed_names = [] self.number_fn_requested = 0 self.pixel_size = 0.1 self.shutters_info = None configuration = module_params.get("configuration") self.spot_counter = findSpots.SpotCounter( max_threads=configuration.get("max_threads"), max_size=configuration.get("max_size")) self.view = SpotCounterView(module_name=self.module_name, configuration=configuration) self.view.halDialogInit( qt_settings, module_params.get("setup_name") + " spot counter") # Spot counter parameters. self.parameters = params.StormXMLObject() self.parameters.add( params.ParameterRangeInt( description="Maximum counts for the spotcounter graph", name="max_spots", value=500, min_value=0, max_value=1000, is_mutable=False, is_saved=False)) self.parameters.add( params.ParameterRangeFloat(description="Scale bar length in nm", name="scale_bar_len", value=2000, min_value=100, max_value=10000)) self.parameters.add( params.ParameterRangeInt( description="Spot detection threshold (camera counts)", name="threshold", value=250, min_value=1, max_value=10000)) self.parameters.add( params.ParameterString(description="Which camera to display.", name="which_camera", value="", is_mutable=False, is_saved=False))
def __init__(self, module_params = None, qt_settings = None, **kwds): super().__init__(**kwds) self.timing_functionality = None self.parameters = params.StormXMLObject() self.parameters.add(params.ParameterSetString(description = "Feed to use as the time base when filming", name = "time_base", value = "", allowed = [""])) default_time_base = module_params.get("parameters").get("time_base") self.setAllowed([default_time_base]) self.parameters.setv("time_base", default_time_base)
def __init__(self, configuration=None, **kwds): super().__init__(**kwds) self.parameters = params.StormXMLObject() self.retracted_z = configuration.get("retracted_z") self.z_stage_fn = None # Load UI self.ui = zStageUi.Ui_Dialog() self.ui.setupUi(self) icon_path = os.path.join(os.path.dirname(__file__), "../icons/") self.ui.upLButton.setIcon( QtGui.QIcon(os.path.join(icon_path, "2uparrow-128.png"))) self.ui.upLButton.clicked.connect(self.handleUpLButton) self.ui.upSButton.setIcon( QtGui.QIcon(os.path.join(icon_path, "1uparrow-128.png"))) self.ui.upSButton.clicked.connect(self.handleUpSButton) self.ui.downSButton.setIcon( QtGui.QIcon(os.path.join(icon_path, "1downarrow-128.png"))) self.ui.downSButton.clicked.connect(self.handleDownSButton) self.ui.downLButton.setIcon( QtGui.QIcon(os.path.join(icon_path, "2downarrow-128.png"))) self.ui.downLButton.clicked.connect(self.handleDownLButton) self.ui.homeButton.clicked.connect(self.handleHomeButton) self.ui.retractButton.clicked.connect(self.handleRetractButton) self.ui.zeroButton.clicked.connect(self.handleZeroButton) self.ui.goButton.clicked.connect(self.handleGoButton) # Set to minimum size & fix. self.adjustSize() self.setFixedSize(self.width(), self.height()) # Add parameters. self.parameters.add( params.ParameterRangeFloat(description="Z Stage large step size", name="z_large_step", value=configuration.get("large_step"), min_value=0.001, max_value=100.0)) self.parameters.add( params.ParameterRangeFloat(description="Z Stage small step size", name="z_small_step", value=configuration.get("small_step"), min_value=0.001, max_value=10.0)) self.setEnabled(False)
def test_parameters_6(): p1 = params.StormXMLObject() s1 = p1.addSubSection("foo") s1.add("bar1", "foo1") s2 = p1.addSubSection("foo.bar") s2.add("bar2", "foo2") s3 = p1.addSubSection("bar.foo") s3.add("foo1", "bar1") assert (p1.get("foo.bar1") == "foo1") assert (p1.get("foo.bar.bar2") == "foo2") assert (p1.get("bar.foo.foo1") == "bar1")
def __init__(self, configuration=None, **kwds): super().__init__(**kwds) self.current_mode = None self.modes = [] self.parameters = params.StormXMLObject() self.ui = focuslockUi.Ui_Dialog() self.ui.setupUi(self) # Add parameters self.parameters.add( params.ParameterFloat(description="Z stage jump size", name="jump_size", value=0.1)) # Set up lock display. self.lock_display = lockDisplay.LockDisplay( configuration=configuration, jump_signal=self.jump, parent=self) layout = QtWidgets.QGridLayout(self.ui.lockDisplayWidget) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.lock_display) # Configure modes. lockModes.FindSumMixin.addParameters(self.parameters) lockModes.LockedMixin.addParameters(self.parameters) lockModes.ScanMixin.addParameters(self.parameters) for mode_class_name in configuration.get("lock_modes").split(","): a_class = getattr(lockModes, mode_class_name.strip()) a_object = a_class(parameters=self.parameters, parent=self) self.ui.modeComboBox.addItem(a_object.getName()) self.modes.append(a_object) # Set parameters values based on the config file parameters. c_params = configuration.get("parameters") for attr in params.difference(c_params, self.parameters): print(attr, c_params.get(attr)) self.parameters.setv(attr, c_params.get(attr)) self.newParameters(self.parameters) # Connect signals. self.ui.jumpNButton.clicked.connect(self.handleJumpNButton) self.ui.jumpPButton.clicked.connect(self.handleJumpPButton) self.ui.lockButton.clicked.connect(self.handleLockButton) self.ui.lockTargetSpinBox.valueChanged.connect(self.handleLockTarget) self.ui.modeComboBox.currentIndexChanged.connect( self.handleModeComboBox) self.setEnabled(False)
def test_parameters_3(): # Load parameters. p1 = params.parameters(test.xmlFilePathAndName("test_parameters.xml"), recurse=True) # Test sub-section creation. p2 = params.StormXMLObject() p2s = p2.addSubSection("camera1", p1.get("camera1").copy()) p2s.add(params.ParameterInt(name="test", value=5)) # p2 is different then p1 because it has 'test'. assert (params.difference(p2.get("camera1"), p1.get("camera1"))[0] == "test") # But p1 is not different from p2 because difference() only # checks p1 properties that exist in p1. assert (len(params.difference(p1.get("camera1"), p2.get("camera1"))) == 0)
def __init__(self, module_params=None, qt_settings=None, **kwds): super().__init__(**kwds) self.film_settings = None self.hardware_timing_functionality = None self.configuration = module_params.get("configuration") self.parameters = params.StormXMLObject() # # FIXME: The range would be better set by what the cameras allow # based on their current configuration. # self.parameters.add( params.ParameterRangeFloat( description="Frames per second", name="fps", value=self.configuration.get("fps", 0.1), min_value=self.configuration.get("fps_min", 0.001), max_value=self.configuration.get("fps_max", 10000.0)))
def test_parameters_4(): # Load parameters. p1 = params.parameters(test.xmlFilePathAndName("test_parameters.xml"), recurse=True) # Create another set of parameters with only 1 item. p2 = params.StormXMLObject() p2.add(params.ParameterString(name="test_param", value="bar")) p2s = p2.addSubSection("camera1") p2s.add(params.ParameterSetBoolean(name="flip_horizontal", value=True)) p2s.add(params.ParameterSetBoolean(name="flip_vertical", value=False)) # Test copy. [p3, ur] = params.copyParameters(p1, p2) # Their should be one un-recognized parameter, 'flip_vertical'. assert (len(ur) == 1) and (ur[0] == "flip_vertical") # 'camera1.flip_horizontal' in p3 should be True. assert p3.get("camera1.flip_horizontal") # 'test_param' should be 'bar'. assert (p3.get("test_param") == "bar")
def __init__(self, configuration=None, **kwds): super().__init__(**kwds) self.channel_name_to_id = {} self.channels = [] self.channels_by_name = {} self.parameters = params.StormXMLObject() self.power_fp = None self.running_shutters = False self.shutters_info = False self.timing_functionality = None self.waveforms = [] self.xml_directory = os.path.dirname(os.path.dirname(__file__)) # UI setup. self.ui = illuminationUi.Ui_Dialog() self.ui.setupUi(self) number_channels = len(configuration.getAttrs()) # Default power setting. # # FIXME: This assumes that all the channels are normalized # so that the maximum power is 1.0. # default_power = [] for i in range(number_channels): default_power.append(1.0) self.parameters.add( illuminationParameters.ParameterDefaultPowers(description="Power", name="default_power", value=default_power, is_mutable=False)) # Default on/off state. on_off_state = [] for i in range(number_channels): on_off_state.append(False) self.parameters.add( illuminationParameters.ParameterOnOffStates(description="On/Off", name="on_off_state", value=on_off_state, is_mutable=False)) # Default buttons. buttons = [] for i in range(number_channels): buttons.append([["Max", 1.0], ["Low", 0.1]]) self.parameters.add( illuminationParameters.ParameterPowerButtons(description="Buttons", name="power_buttons", value=buttons)) # Default shutters file. filename = os.path.join(self.xml_directory, "shutters_default.xml") self.parameters.add( params.ParameterStringFilename(description="Shutters file name", name="shutters", value=filename, use_save_dialog=False)) # Illumination channels setup. layout = QtWidgets.QHBoxLayout(self.ui.powerControlBox) layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(1) for i, cname in enumerate(sorted(configuration.getAttrs())): a_instance = illuminationChannel.Channel( channel_id=i, configuration=configuration.get(cname), parent=self.ui.powerControlBox) self.channel_name_to_id[a_instance.getName()] = i self.channels.append(a_instance) self.channels_by_name[a_instance.getName()] = a_instance layout.addWidget(a_instance.channel_ui)
def __init__(self, w1=None, configuration=None, **kwds): super().__init__(**kwds) self.w1 = w1 # Query W1 for it's maximum speed. max_speed = self.w1.commandResponse("MS_MAX,?") assert max_speed is not None # Create dictionaries for the configuration of the # filter wheels and two dichroic mirror sets. self.filter_wheel_1_config = {} values = configuration.get("filter_wheel_1") filter_names = values.split(",") for pos, filter_name in enumerate(filter_names): self.filter_wheel_1_config[filter_name] = pos + 1 self.filter_wheel_2_config = {} values = configuration.get("filter_wheel_2") filter_names = values.split(",") for pos, filter_name in enumerate(filter_names): self.filter_wheel_2_config[filter_name] = pos + 1 self.dichroic_mirror_config = {} values = configuration.get("dichroic_mirror") dichroic_names = values.split(",") for pos, dichroic_name in enumerate(dichroic_names): self.dichroic_mirror_config[dichroic_name] = pos + 1 self.camera_dichroic_config = {} values = configuration.get("camera_dichroic") camera_dichroic_names = values.split(",") for pos, camera_dichroic in enumerate(camera_dichroic_names): self.camera_dichroic_config[camera_dichroic] = pos + 1 # Create parameters self.parameters = params.StormXMLObject() self.parameters.add( params.ParameterSetBoolean( description="Bypass spinning disk for brightfield mode?", name="bright_field_bypass", value=False)) self.parameters.add( params.ParameterSetBoolean(description="Spin the disk?", name="spin_disk", value=True)) # Disk properties self.parameters.add( params.ParameterSetString( description="Disk pinhole size", name="disk", value="50-micron pinholes", allowed=["50-micron pinholes", "25-micron pinholes"])) self.parameters.add( params.ParameterRangeInt(description="Disk speed (RPM)", name="disk_speed", value=max_speed, min_value=1, max_value=max_speed)) # Dichroic mirror position values = sorted(self.dichroic_mirror_config.keys()) self.parameters.add( params.ParameterSetString(description="Dichroic mirror position", name="dichroic_mirror", value=values[0], allowed=values)) # Filter wheel positions values = sorted(self.filter_wheel_1_config.keys()) self.parameters.add( params.ParameterSetString( description="Camera 1 Filter Wheel Position (1-10)", name="filter_wheel_pos1", value=values[0], allowed=values)) values = sorted(self.filter_wheel_2_config.keys()) self.parameters.add( params.ParameterSetString( description="Camera 2 Filter Wheel Position (1-10)", name="filter_wheel_pos2", value=values[0], allowed=values)) # Camera dichroic positions values = sorted(self.camera_dichroic_config.keys()) self.parameters.add( params.ParameterSetString( description="Camera dichroic mirror position (1-3)", name="camera_dichroic_mirror", value=values[0], allowed=values)) # Aperature settings self.parameters.add( params.ParameterRangeInt( description="Aperture value (1-10; small to large)", name="aperture", value=10, min_value=1, max_value=10)) self.newParameters(self.parameters, initialization=True)
def __init__(self, **kwds): super().__init__(**kwds) self.directory = "" self.parameters = params.StormXMLObject() self.stage_functionality = None # Add stage UI parameters. self.parameters.add( params.ParameterRangeFloat(description="Large step size (microns)", name="large_step_size", value=200.0, min_value=1.0, max_value=1000.0)) self.parameters.add( params.ParameterRangeFloat(description="Small step size (microns)", name="small_step_size", value=10.0, min_value=1.0, max_value=100.0)) # UI setup. self.ui = stageUi.Ui_Dialog() self.ui.setupUi(self) # Configure all the stage movement buttons. icon_path = os.path.join(os.path.dirname(__file__), "../icons/") self.motion_buttons = [ MotionButton(button=self.ui.leftSButton, icon=os.path.join(icon_path, "1leftarrow-128.png"), button_type="small", xval=1, yval=0), MotionButton(button=self.ui.leftLButton, icon=os.path.join(icon_path, "2leftarrow-128.png"), button_type="large", xval=1, yval=0), MotionButton(button=self.ui.rightSButton, icon=os.path.join(icon_path, "1rightarrow-128.png"), button_type="small", xval=-1, yval=0), MotionButton(button=self.ui.rightLButton, icon=os.path.join(icon_path, "2rightarrow-128.png"), button_type="large", xval=-1, yval=0), MotionButton(button=self.ui.upSButton, icon=os.path.join(icon_path, "1uparrow-128.png"), button_type="small", xval=0, yval=1), MotionButton(button=self.ui.upLButton, icon=os.path.join(icon_path, "2uparrow-128.png"), button_type="large", xval=0, yval=1), MotionButton(button=self.ui.downSButton, icon=os.path.join(icon_path, "1downarrow-128.png"), button_type="small", xval=0, yval=-1), MotionButton(button=self.ui.downLButton, icon=os.path.join(icon_path, "2downarrow-128.png"), button_type="large", xval=0, yval=-1) ] for button in self.motion_buttons: button.motionClicked.connect(self.handleMotionClicked) # Connect the rest of the UI elements. self.ui.addButton.clicked.connect(self.handleAddButton) self.ui.clearButton.clicked.connect(self.handleClearButton) self.ui.goButton.clicked.connect(self.handleGoButton) self.ui.homeButton.clicked.connect(self.handleHomeButton) self.ui.loadButton.clicked.connect(self.handleLoadButton) self.ui.saveButton.clicked.connect(self.handleSaveButton) self.ui.saveComboBox.activated.connect(self.handleSaveComboBox) self.ui.zeroButton.clicked.connect(self.handleZeroButton) self.newParameters(self.parameters) # Disable UI until we get a stage functionality. self.setEnabled(False)
def __init__(self, camera_name=None, config=None, **kwds): """ camera_name - This is the name of this camera's section in the config XML file. config - These are the values in the parameters section as a StormXMLObject(). """ super().__init__(**kwds) # This is the hardware module that will actually control the camera. self.camera = None # Sub-classes should set this to a CameraFunctionality object. self.camera_functionality = None self.camera_name = camera_name # This is a flag for whether or not the camera is in a working state. # It might not be if for example the parameters were bad. self.camera_working = True # The length of a fixed length film. self.film_length = None # The current frame number, this gets reset by startCamera(). self.frame_number = 0 # The camera parameters. self.parameters = params.StormXMLObject() # This is how we tell the thread that is handling actually talking # to the camera hardware to stop. self.running = False # This is how we know that the camera thread that is talking to the # camera actually started. self.thread_started = False # # These are the minimal parameters that every camera must provide # to work with HAL. # # The exposure time. self.parameters.add( params.ParameterFloat(description="Exposure time (seconds)", name="exposure_time", value=1.0)) # This is frames per second as reported by the camera. It is used # for hardware timed waveforms (if any). self.parameters.add( params.ParameterFloat(name="fps", value=0, is_mutable=False)) # # Chip size, ROI of the chip and the well depth. # x_size = 256 y_size = 256 self.parameters.add( params.ParameterInt(name="x_chip", value=x_size, is_mutable=False, is_saved=False)) self.parameters.add( params.ParameterInt(name="y_chip", value=y_size, is_mutable=False, is_saved=False)) self.parameters.add( params.ParameterInt(name="max_intensity", value=128, is_mutable=False, is_saved=False)) # # Note: These are all expected to be in units of binned pixels. For # example if the camera is 512 x 512 and we are binning by 2s then # the maximum value of these would 256 x 256. # self.parameters.add( params.ParameterRangeInt(description="AOI X start", name="x_start", value=1, min_value=1, max_value=x_size)) self.parameters.add( params.ParameterRangeInt(description="AOI X end", name="x_end", value=x_size, min_value=1, max_value=x_size)) self.parameters.add( params.ParameterRangeInt(description="AOI Y start", name="y_start", value=1, min_value=1, max_value=y_size)) self.parameters.add( params.ParameterRangeInt(description="AOI Y end", name="y_end", value=y_size, min_value=1, max_value=y_size)) self.parameters.add( params.ParameterInt(name="x_pixels", value=0, is_mutable=False)) self.parameters.add( params.ParameterInt(name="y_pixels", value=0, is_mutable=False)) self.parameters.add( params.ParameterRangeInt(description="Binning in X", name="x_bin", value=1, min_value=1, max_value=4)) self.parameters.add( params.ParameterRangeInt(description="Binning in Y", name="y_bin", value=1, min_value=1, max_value=4)) # Frame size in bytes. self.parameters.add( params.ParameterInt(name="bytes_per_frame", value=x_size * y_size * 2, is_mutable=False, is_saved=False)) # # How/if data from this camera is saved. # self.parameters.add( params.ParameterString( description="Camera save filename extension", name="extension", value="")) self.parameters.add( params.ParameterSetBoolean( description="Save data from this camera when filming", name="saved", value=True)) self.parameters.set("extension", config.get("extension", "")) self.parameters.set("saved", config.get("saved", True)) # # Camera display orientation. Values can only be changed by # changing the config.xml file. # self.parameters.add( params.ParameterSetBoolean(name="flip_horizontal", value=False, is_mutable=False)) self.parameters.add( params.ParameterSetBoolean(name="flip_vertical", value=False, is_mutable=False)) self.parameters.add( params.ParameterSetBoolean(name="transpose", value=False, is_mutable=False)) self.parameters.set("flip_horizontal", config.get("flip_horizontal", False)) self.parameters.set("flip_vertical", config.get("flip_vertical", False)) self.parameters.set("transpose", config.get("transpose", False)) # # Camera default display minimum and maximum. # # These are the values the display will use by default. They can # only be changed by changing the config.xml file. # self.parameters.add( params.ParameterInt(name="default_max", value=2000, is_mutable=False)) self.parameters.add( params.ParameterInt(name="default_min", value=100, is_mutable=False)) self.parameters.set("default_max", config.get("default_max", 2000)) self.parameters.set("default_min", config.get("default_min", 100)) self.finished.connect(self.handleFinished) self.newData.connect(self.handleNewData)
def __init__(self, display_name = None, feed_name = "camera1", default_colortable = None, **kwds): super().__init__(**kwds) # General (alphabetically ordered). self.cam_fn = None self.cfv_functionality = CameraFrameViewerFunctionality() self.color_gradient = None self.color_tables = colorTables.ColorTables(os.path.dirname(__file__) + "/../colorTables/all_tables/") self.cycle_length = 0 self.default_colortable = default_colortable self.default_parameters = params.StormXMLObject(validate = False) self.display_name = display_name self.display_timer = QtCore.QTimer(self) self.filming = False self.frame = False self.parameters = False self.rubber_band_rect = None self.show_grid = False self.show_info = True self.show_target = False self.stage_functionality = None # # Keep track of the default feed_name in the default parameters, these # are the parameters that will be used when we change parameter files # and the parameters file doesn't specify anything for this view. # self.default_parameters.add(params.ParameterString(name = "feed_name", value = feed_name, is_mutable = False)) # Set current parameters to default parameters. self.parameters = self.default_parameters.copy() # UI setup. self.ui = cameraDisplayUi.Ui_Frame() self.ui.setupUi(self) # Camera frame display. self.camera_view = self.ui.cameraGraphicsView self.camera_scene = qtCameraGraphicsScene.QtCameraGraphicsScene(parent = self) self.camera_widget = qtCameraGraphicsScene.QtCameraGraphicsItem() self.camera_scene.addItem(self.camera_widget) self.camera_view.setScene(self.camera_scene) self.camera_view.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(0,0,0))) # Display range slider. self.ui.rangeSlider = qtRangeSlider.QVRangeSlider() layout = QtWidgets.QGridLayout(self.ui.rangeSliderWidget) layout.setContentsMargins(1,1,1,1) layout.addWidget(self.ui.rangeSlider) self.ui.rangeSliderWidget.setLayout(layout) self.ui.rangeSlider.setEmitWhileMoving(True) # Color tables combo box. for color_name in sorted(self.color_tables.getColorTableNames()): self.ui.colorComboBox.addItem(color_name[:-5]) self.ui.gridAct = QtWidgets.QAction(self.tr("Show Grid"), self) self.ui.infoAct = QtWidgets.QAction(self.tr("Hide Info"), self) self.ui.targetAct = QtWidgets.QAction(self.tr("Show Target"), self) # The default is not to show the shutter or the record button. self.ui.recordButton.hide() self.ui.shutterButton.hide() # These are always hidden unless we are filming. self.ui.syncLabel.hide() self.ui.syncSpinBox.hide() # FIXME: This only sort of works, the text is still getting cut-off. self.ui.feedComboBox.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) # Connect signals. self.camera_view.horizontalScrollBar().sliderReleased.connect(self.handleScrollBar) self.camera_view.newCenter.connect(self.handleNewCenter) self.camera_view.newScale.connect(self.handleNewScale) self.camera_view.verticalScrollBar().sliderReleased.connect(self.handleScrollBar) self.camera_view.dragMove.connect(self.handleDragMove) self.camera_view.dragStart.connect(self.handleDragStart) self.camera_view.rubberBandChanged.connect(self.handleRubberBandChanged) self.ui.autoScaleButton.clicked.connect(self.handleAutoScale) self.ui.colorComboBox.currentIndexChanged[str].connect(self.handleColorTableChange) self.ui.feedComboBox.currentIndexChanged[str].connect(self.handleFeedChange) self.ui.gridAct.triggered.connect(self.handleGrid) self.ui.infoAct.triggered.connect(self.handleInfo) self.ui.rangeSlider.doubleClick.connect(self.handleAutoScale) self.ui.rangeSlider.rangeChanged.connect(self.handleRangeChange) self.ui.syncSpinBox.valueChanged.connect(self.handleSync) self.ui.targetAct.triggered.connect(self.handleTarget) # Display timer, the display updates at approximately 10Hz. self.display_timer.setInterval(100) self.display_timer.timeout.connect(self.handleDisplayTimer) self.display_timer.start()
def __init__(self, joystick=None, joystick_gains=None, **kwds): super().__init__(**kwds) self.button_timer = QtCore.QTimer(self) self.joystick = joystick self.joystick_gains = joystick_gains # XML should be [25.0, 250.0, 2500.0] self.old_right_joystick = [0, 0] self.old_left_joystick = [0, 0] self.stage_functionality = None self.to_emit = False # The joystick parameters. self.parameters = params.StormXMLObject() self.parameters.add( params.ParameterInt(name="joystick_gain_index", value=0, is_mutable=False, is_saved=False)) self.parameters.add( params.ParameterInt(name="multiplier", value=1, is_mutable=False, is_saved=False)) self.parameters.add( params.ParameterRangeFloat( description="Step size in um for hat button press", name="hat_step", value=1.0, min_value=0.0, max_value=10.0)) self.parameters.add( params.ParameterRangeFloat( description="X button multiplier for joystick and focus lock", name="joystick_multiplier_value", value=5.0, min_value=0.0, max_value=50.0)) self.parameters.add( params.ParameterSetString(description="Response mode", name="joystick_mode", value="quadratic", allowed=["linear", "quadratic"])) self.parameters.add( params.ParameterSetFloat(description="Sign for x motion", name="joystick_signx", value=1.0, allowed=[-1.0, 1.0])) self.parameters.add( params.ParameterSetFloat(description="Sign for y motion", name="joystick_signy", value=1.0, allowed=[-1.0, 1.0])) self.parameters.add( params.ParameterRangeFloat( description="Focus lock step size in um", name="lockt_step", value=0.025, min_value=0.0, max_value=1.0)) self.parameters.add( params.ParameterRangeFloat( description="Minimum joystick offset to be non-zero", name="min_offset", value=0.1, min_value=0.0, max_value=1.0)) self.parameters.add( params.ParameterSetBoolean(description="Swap x and y axises", name="xy_swap", value=False)) self.joystick.start(self.joystickHandler) self.button_timer.setInterval(100) self.button_timer.setSingleShot(True) self.button_timer.timeout.connect(self.buttonDownHandler)
def __init__(self, config = None, **kwds): super().__init__(**kwds) self.cfv_fn = None self.click_step = 1.0 self.click_timer = QtCore.QTimer(self) self.click_x = 0.0 self.click_y = 0.0 self.client_sock = False self.connected = False self.default_image = QtGui.QImage("bt_image.png") self.drag_gain = 1.0 self.drag_x = 0.0 self.drag_y = 0.0 self.filming = False self.image_is_new = True self.images_sent = 0 self.is_down = False self.is_drag = False self.messages = [] self.mutex = QtCore.QMutex() self.offset_min = None self.offset_max = None self.parameters = params.StormXMLObject() self.qpd_fn = None self.running = False self.send_pictures = config.get("send_pictures") self.show_camera = True self.stage_fn = None self.start_time = 0 self.sum_min = None self.sum_max = None self.parameters.add(params.ParameterRangeFloat(description = "Drag multiplier", name = "d_mult", value = 100.0, min_value = 0.1, max_value = 1000.0)) self.parameters.add(params.ParameterRangeFloat(description = "Z step size in um", name = "z_step", value = 0.1, min_value = 0.0, max_value = 5.0)) # Set current image to default. self.current_image = self.default_image # Setup bluetooth socket. have_bluetooth = True try: self.server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM) self.server_sock.bind(("",bluetooth.PORT_ANY)) self.server_sock.listen(1) port = self.server_sock.getsockname()[1] print("Bluetooth: Listening on RFCOMM channel {0:d}".format(port)) uuid = "3e1f9ea8-9c11-11e3-b248-425861b86ab6" bluetooth.advertise_service(self.server_sock, "halServer", service_id = uuid, service_classes = [uuid, bluetooth.SERIAL_PORT_CLASS], profiles = [bluetooth.SERIAL_PORT_PROFILE]) except bluetooth.btcommon.BluetoothError: print(traceback.format_exc()) print("Failed to start Bluetooth") have_bluetooth = False if have_bluetooth: # Setup timer. self.click_timer.setInterval(200) self.click_timer.timeout.connect(self.handleClickTimer) self.click_timer.setSingleShot(True) # Connect signals. self.newMessage.connect(self.handleNewMessage) self.start(QtCore.QThread.NormalPriority)
def handleResponses(self, message): if message.isType("get functionality"): assert (len(message.getResponses()) == 1) for response in message.getResponses(): self.camera_functionalities.append(response.getData()["functionality"]) self.number_fn_requested -= 1 # And we are done with the parameter change. if self.parameter_change and (self.number_fn_requested == 0): self.parameter_change = False self.sendMessage(halMessage.HalMessage(m_type = "parameters changed")) # Modules that need additional time to get ready to film should # specify at start up that they need to be waited for. elif message.isType("start film"): # No modules requested waits, so start now. if (len(self.wait_for) == 0): self.startCameras() # Modules are expected to add their current parameters as responses # to the 'stop film' message. We save them in an xml file here. elif message.isType("stop film"): self.film_state = "idle" acq_p = None notes = "" film_settings = message.getData()["film settings"] number_frames = message.getData()["number frames"] if film_settings.isSaved(): to_save = params.StormXMLObject() acq_p = to_save.addSubSection("acquisition") acq_p.add(params.ParameterString(name = "version", value = hgit.getVersion())) acq_p.add(params.ParameterInt(name = "number_frames", value = number_frames)) for response in message.getResponses(): data = response.getData() # Add general parameters 'en-bloc'. if "parameters" in data: to_save.addSubSection(response.source, svalue = data["parameters"]) # Add any acquisition parameters, these will be a list. if "acquisition" in data: for p in data["acquisition"]: acq_p.addParameter(p.getName(), p) if (p.getName() == "notes"): notes = p.getv() to_save.saveToFile(film_settings.getBasename() + ".xml") if self.logfile_fp is not None: msg = ",".join([str(datetime.datetime.now()), film_settings.getBasename(), notes]) msg += "\r\n" self.logfile_fp.write(msg) self.logfile_fp.flush() # Now that everything is complete end the filming lock out. self.setLockout(False, acquisition_parameters = acq_p)
def infToStormXML(inf_filename): """ Creates a StormXMLObject from a .inf file that can be used by Steve. Note that this object is missing many of the properties of the standard object created from a setting xml file. """ xml = parameters.StormXMLObject([]) # Mark as "fake". xml.set("faked_xml", True) # Add acquisition sub-object. xml.set("acquisition", parameters.StormXMLObject([])) xml.set("acquisition.camera", "camera1") # Add camera1 sub-object. xml.set("camera1", parameters.StormXMLObject([])) # Add film sub-object. xml.set("film", parameters.StormXMLObject([])) # Add mosaic sub-object with fake objective. xml.set("mosaic", parameters.StormXMLObject([])) xml.set("mosaic.objective", "fake") # Figure out movie type. no_ext_name = os.path.splitext(inf_filename)[0] if os.path.exists(no_ext_name + ".dax"): xml.set("film.filetype", ".dax") elif os.path.exists(no_ext_name + ".tif"): xml.set("film.filetype", ".tif") else: raise IOError("only .dax and .tif are supported (case sensitive..)") # Extract the movie information from the associated inf file. size_re = re.compile(r'frame dimensions = ([\d]+) x ([\d]+)') length_re = re.compile(r'number of frames = ([\d]+)') endian_re = re.compile(r' (big|little) endian') stagex_re = re.compile(r'Stage X = ([\d\.\-]+)') stagey_re = re.compile(r'Stage Y = ([\d\.\-]+)') scalemax_re = re.compile(r'scalemax = ([\d\.\-]+)') scalemin_re = re.compile(r'scalemin = ([\d\.\-]+)') parameters_re = re.compile(r'parameters file = (.+)') with open(inf_filename) as fp: for line in fp: m = size_re.match(line) if m: # y_pixels = height, x_pixels = width. xml.set("camera1.y_pixels", int(m.group(2))) xml.set("camera1.x_pixels", int(m.group(1))) m = length_re.match(line) if m: xml.set("acquisition.number_frames", int(m.group(1))) m = endian_re.search(line) if m: if (m.group(1) == "big"): xml.set("film.want_big_endian", True) else: xml.set("film.want_big_endian", False) m = stagex_re.match(line) if m: stage_x = float(m.group(1)) m = stagey_re.match(line) if m: stage_y = float(m.group(1)) m = scalemax_re.match(line) if m: xml.set("display00.camera1.scalemax", int(m.group(1))) m = scalemin_re.match(line) if m: xml.set("display00.camera1.scalemin", int(m.group(1))) m = parameters_re.match(line) if m: xml.set("parameters_file", m.group(1)) pos_string = "{0:.2f},{1:.2f},0.00".format(stage_x, stage_y) xml.set("acquisition.stage_position", pos_string) return xml
def __init__(self, w1=None, configuration=None, **kwds): super().__init__(**kwds) self.w1 = w1 # assert max_speed is not None # Create dictionaries for the configuration of the # filter wheels and two dichroic mirror sets. self.filter_wheel_config = {} values = configuration.get("filter_wheel") filter_names = values.split(",") for pos, filter_name in enumerate(filter_names): self.filter_wheel_config[filter_name] = pos + 1 self.dichroic_mirror_config = {} values = configuration.get("dichroic_mirror") dichroic_names = values.split(",") for pos, dichroic_name in enumerate(dichroic_names): self.dichroic_mirror_config[dichroic_name] = pos + 1 # Create parameters self.parameters = params.StormXMLObject() self.parameters.add( params.ParameterSetBoolean( description="Bypass spinning disk for brightfield mode?", name="bright_field_bypass", value=False)) self.parameters.add( params.ParameterSetBoolean(description="Spin the disk?", name="spin_disk", value=True)) # Disk properties self.parameters.add( params.ParameterSetString( description="Disk pinhole size", name="disk", value="70-micron pinholes", allowed=["70-micron pinholes", "40-micron pinholes"])) # Dichroic mirror position values = sorted(self.dichroic_mirror_config.keys()) self.parameters.add( params.ParameterSetString( description="Dichroic mirror position (1-5)", name="dichroic_mirror", value=values[0], allowed=values)) # Filter wheel positions values = sorted(self.filter_wheel_config.keys()) self.parameters.add( params.ParameterSetString( description="Camera 1 Filter Wheel Position (1-8)", name="filter_wheel", value=values[0], allowed=values)) self.newParameters(self.parameters, initialization=True)
def __init__(self, module_params=None, qt_settings=None, **kwds): super().__init__(**kwds) self.locked_out = False self.wait_for = [] self.waiting_on = [] self.view = parametersBox.ParametersBox(module_params=module_params, qt_settings=qt_settings) self.view.editParameters.connect(self.handleEditParameters) self.view.newParameters.connect(self.handleNewParameters) p = params.StormXMLObject() p.set("parameters_file", os.path.join(module_params.get("directory"), "default.xml")) # # Add parameter to record whether or not these parameters have actually # been used (as opposed to just appearing in the list view). # # They should be initialized since this is what we are starting with.. # p.add( params.ParameterSetBoolean(name="initialized", value=False, is_mutable=False, is_saved=False)) self.view.addParameters(p, is_default=True) self.configure_dict = { "ui_order": 0, "ui_parent": "hal.containerWidget", "ui_widget": self.view } # This message marks the beginning and the end of the parameter change # life cycle. halMessage.addMessage("changing parameters", validator={ "data": { "changing": [True, bool] }, "resp": None }) # Other modules should respond to this message with their current # parameters. halMessage.addMessage("current parameters", validator={ "data": None, "resp": { "parameters": [False, params.StormXMLObject] } }) # A request from another module for one of the sets of parameters. halMessage.addMessage("get parameters", validator={ "data": { "index or name": [True, (str, int)] }, "resp": { "parameters": [False, params.StormXMLObject], "found": [True, bool] } }) # The current parameters have changed. # # Data includes a copy of the desired new parameters. Other modules # should at least check if the new parameters are okay. They may # defer actually re-configuring until they receive the # 'updated parameters' message. # # Other modules that respond should send two response: # 1. A response with a copy of their old parameter as "old parameters". # 2. A response with their updated parameters as "new parameters". # # The response is structured this way so that if an error occurs # during the parameter update we still have a record of the last # good state in "old parameters". # # Notes: # 1. We send a copy of the parameters in the listview, so if the # module wants to it can just use these as the parameters without # copying them again. # # 2. The 'old parameters' response should be a copy. # # 3. The 'new parameters' response does not need to be a copy. # halMessage.addMessage("new parameters", validator={ "data": { "parameters": [True, params.StormXMLObject], "is_edit": [True, bool] }, "resp": { "new parameters": [False, params.StormXMLObject], "old parameters": [False, params.StormXMLObject] } }) # This comes from other modules that requested "wait for" at startup. # # Modules may respond with their new parameters here if they did not know # the final values for the parameters at 'new parameters'. At this point # however the modules cannot complain that the parameters they were given # were invalid, this has to be done at 'new parameters'. # halMessage.addMessage("parameters changed", validator={ "data": { "new parameters": [False, params.StormXMLObject] }, "resp": None }) # A request from another module to set the current parameters. halMessage.addMessage("set parameters", validator={ "data": { "index or name": [True, (str, int)] }, "resp": { "found": [True, bool], "current": [True, bool] } }) # The updated parameters. # # These are the updated values of parameters of all of the modules. # This is sent immediately after all of the modules respond to # the 'new parameters' message. # # The parameter change cycle won't actually complete till all the # modules that requested a wait send the "parameters changed" message. # halMessage.addMessage( "updated parameters", validator={"data": { "parameters": [True, params.StormXMLObject] }})
def __init__(self, parameters = None, **kwds): """ parameters - This is just the 'feed' section of the parameters. """ super().__init__(**kwds) self.feeds = {} if parameters is None: return # Create the feeds. self.parameters = parameters for feed_name in self.parameters.getAttrs(): file_params = self.parameters.get(feed_name) # Create default feed parameters. max_value = 100000 feed_params = params.StormXMLObject() # Feeds are saved with their name as the extension. feed_params.add(params.ParameterString(name = "extension", value = feed_name, is_mutable = True)) feed_params.add(params.ParameterString(name = "feed_type", value = "", is_mutable = False)) feed_params.add(params.ParameterSetBoolean(name = "saved", value = False)) # This is the camera that drives the feed. feed_params.add(params.ParameterString(name = "source", value = "", is_mutable = False)) feed_params.add(params.ParameterRangeInt(description = "AOI X start.", name = "x_start", value = 1, min_value = 1, max_value = max_value)) feed_params.add(params.ParameterRangeInt(description = "AOI X end.", name = "x_end", value = 1, min_value = 1, max_value = max_value)) feed_params.add(params.ParameterRangeInt(description = "AOI Y start.", name = "y_start", value = 1, min_value = 1, max_value = max_value)) feed_params.add(params.ParameterRangeInt(description = "AOI Y end.", name = "y_end", value = 1, min_value = 1, max_value = max_value)) # Figure out what type of feed this is. fclass = None feed_type = file_params.get("feed_type") if (feed_type == "average"): fclass = FeedFunctionalityAverage feed_params.add(params.ParameterInt(description = "Number of frames to average.", name = "frames_to_average", value = 1)) elif (feed_type == "interval"): fclass = FeedFunctionalityInterval feed_params.add(params.ParameterInt(description = "Interval cycle length.", name = "cycle_length", value = 1)) feed_params.add(params.ParameterCustom(description = "Frames to capture.", name = "capture_frames", value = "1")) elif (feed_type == "slice"): fclass = FeedFunctionalitySlice else: raise FeedException("Unknown feed type '" + feed_type + "' in feed '" + feed_name + "'") # Update with values from the parameters file. Depending on the parameters # file it might include parameters that we don't have and which we silently # ignore. # for attr in file_params.getAttrs(): if feed_params.has(attr): feed_params.setv(attr, file_params.get(attr)) # Replace the values in the parameters that were read from a file with these values. self.parameters.addSubSection(feed_name, feed_params, overwrite = True) camera_name = feed_params.get("source") + "." + feed_name self.feeds[camera_name] = fclass(feed_name = feed_name, camera_name = camera_name, parameters = feed_params)