Пример #1
0
    def __init__(self, data, size, params):
        self.camera = params.get("acquisition.camera", "camera1")
        self.data = data
        self.height = size[0]

        # Pre HAL2 movies.
        if params.has(self.camera + ".scalemin"):
            self.image_min = params.get(self.camera + ".scalemin")
            self.image_max = params.get(self.camera + ".scalemax")
        else:
            self.image_min = params.get("display00.camera1.display_min")
            self.image_max = params.get("display00.camera1.display_max")

        self.parameters = params
        self.parameters_file = params.get("parameters_file", "NA")
        self.width = size[1]

        location = list(
            map(float,
                params.get("acquisition.stage_position").split(",")))
        self.x_um = location[0]
        self.y_um = location[1]

        # Calculate location in pixels.
        a_point = coord.Point(self.x_um, self.y_um, "um")
        self.x_pix = a_point.x_pix
        self.y_pix = a_point.y_pix
Пример #2
0
 def loadFromMosaicFileData(self, data, directory):
     if (data[0] == "section"):
         self.addSection(coord.Point(float(data[2]), float(data[3]), "um"),
                         float(data[4]))
         return True
     else:
         return False
Пример #3
0
 def loadPositions(self, filename):
     pos_fp = open(filename, "r")
     while 1:
         line = pos_fp.readline()
         if not line: break
         [x, y] = line.split(",")
         self.addPosition(coord.Point(float(x), float(y), "um"))
Пример #4
0
    def __init__(self, comm=None, item_store=None, parameters=None, **kwds):
        super().__init__(**kwds)

        self.comm = comm
        self.current_center = coord.Point(0.0, 0.0, "um")
        self.current_z = 0.0
        self.directory = parameters.get("directory")
        self.extrapolate_count = parameters.get("extrapolate_picture_count")
        self.filename = parameters.get("image_filename")
        self.fractional_overlap = parameters.get("fractional_overlap", 0.05)
        self.grid_size = []
        self.item_store = item_store
        self.last_image = None
        self.movie_queue = []
        self.objectives = None
        self.smc = None
        self.z_inc = 0.01

        # The idea is that in the future other modules might want to
        # change how movies are taken and loaded. This will hopefully
        # make this easier.
        #
        # This class handles creating a SteveItem() from the movie.
        self.movie_loader = None

        # This class handles taking the movie.
        self.movie_taker = None
Пример #5
0
 def loadPositions(self, filename):
     with open(filename) as fp:
         for line in fp:
             try:
                 [x, y] = line.split(",")
                 self.addPosition(coord.Point(float(x), float(y), "um"))
             except ValueError:
                 pass
Пример #6
0
 def handleTakeMovie(self, ignored):
     """
     Handle movies triggered from the context menu and the space bar key.
     """
     self.image_capture.takeMovies([
         coord.Point(self.mosaic_event_coord.x_um,
                     self.mosaic_event_coord.y_um, "um")
     ])
Пример #7
0
    def handleMouseMove(self, a_point):

        # Not sure whether I should include the offset here.
        #        offset_point = coord.Point(a_point.x_um - self.current_offset.x_um,
        #                                   a_point.y_um - self.current_offset.y_um,
        #                                   "um")

        offset_point = coord.Point(a_point.x_um, a_point.y_um, "um")

        self.ui.mosaicLabel.setText("{0:.2f}, {1:.2f}".format(
            offset_point.x_um, offset_point.y_um))
Пример #8
0
    def getCurrentOffset(self):
        """
        Return the offset of the current objective. 

        The current objective should always be the one that was used to take the
        last movie and/or the one that was returned by HAL when queried.
        """
        objective_name = self.getCurrentName()
        if objective_name is not None:
            [obj_um_per_pix, x_offset_um,
             y_offset_um] = self.getData(objective_name)
            return coord.Point(x_offset_um, y_offset_um, "um")
Пример #9
0
 def handleGetPositionComplete(self, a_point):
     if not self.requested_stage_pos:
         # Update cross hair
         offset_point = coord.Point(a_point.x_um + self.current_offset.x_um,
                                    a_point.y_um + self.current_offset.y_um,
                                    "um")
         self.view.setCrosshairPosition(offset_point.x_pix,
                                        offset_point.y_pix)
     else:
         self.requested_stage_pos = False
         self.ui.xStartPosSpinBox.setValue(a_point.x_um)
         self.ui.yStartPosSpinBox.setValue(a_point.y_um)
         self.comm.commDisconnect()
Пример #10
0
    def handleTakeSpiral(self, n_pictures):
        """
        Handle taking a spiral pattern.
        """
        movie_queue = []

        # Starting point.
        movie_queue.append(
            coord.Point(self.mosaic_event_coord.x_um,
                        self.mosaic_event_coord.y_um, "um"))

        # Spiral.
        movie_queue += imageCapture.createSpiral(n_pictures)

        self.image_capture.takeMovies(movie_queue)
Пример #11
0
    def addImage(self, image):

        # If image is not an object then we are done.
        if not image:
            self.toggleTakingPicturesStatus(False)
            self.comm.commDisconnect()
            return

        objective = image.parameters.get(
            "mosaic." + image.parameters.get("mosaic.objective")).split(",")[0]
        [um_per_pixel, x_offset,
         y_offset] = self.ui.objectivesGroupBox.getData(objective)
        magnification = coord.Point.pixels_to_um / um_per_pixel
        self.current_offset = coord.Point(x_offset, y_offset, "um")
        self.view.addImage(image, objective, magnification,
                           self.current_offset)
        self.view.setCrosshairPosition(image.x_pix, image.y_pix)
        if (len(self.picture_queue) > 0):
            next_item = self.picture_queue[0]
            if (type(next_item) == type(coord.Point(0, 0, "um"))):
                self.setCenter(next_item)
                next_x_um = self.current_center.x_um
                next_y_um = self.current_center.y_um
            else:
                [tx, ty] = next_item
                next_x_um = self.current_center.x_um + 0.95 * float(
                    image.width) * coord.Point.pixels_to_um * tx / magnification
                next_y_um = self.current_center.y_um + 0.95 * float(
                    image.height
                ) * coord.Point.pixels_to_um * ty / magnification
            self.picture_queue = self.picture_queue[1:]
            self.comm.captureStart(next_x_um, next_y_um)
        else:
            if self.taking_pictures:
                self.toggleTakingPicturesStatus(False)
                self.comm.commDisconnect()
Пример #12
0
    def handleImageGrid(self, dummy):
        if not self.taking_pictures:
            # Build position list
            pos_list = mosaicView.createGrid(self.ui.xSpinBox.value(),
                                             self.ui.ySpinBox.value())

            # Define first position
            first_pos = coord.Point(self.ui.xStartPosSpinBox.value(),
                                    self.ui.yStartPosSpinBox.value(), "um")
            pos_list.insert(0, first_pos)

            # Take pictures
            self.takePictures(pos_list)
        else:  # Abort button
            self.picture_queue = []
Пример #13
0
 def mousePressEvent(self, event):
     """
     If the left mouse button is pressed then the view is centered on the current cursor position.
     If the right mouse button is pressed then the current location of the cursor in the scene
     is recorded. If self.extrapolate_start exists then self.handleExtrapolatePict() is called,
     otherwise the popup menu is displayed.
     """
     if event.button() == QtCore.Qt.LeftButton:
         self.centerOn(self.mapToScene(event.pos()))
     elif event.button() == QtCore.Qt.RightButton:
         pointf = self.mapToScene(event.pos())
         a_coord = coord.Point(pointf.x(), pointf.y(), "pix")
         if self.extrapolate_start:
             self.extrapolateTakeMovie.emit(a_coord)
         else:
             self.mosaicViewContextMenuEvent.emit(event, a_coord)
Пример #14
0
    def handleTakeGrid(self):
        """
        Handle taking a grid pattern.
        """
        movie_queue = []

        # Starting point.
        movie_queue.append(
            coord.Point(self.mosaic_event_coord.x_um,
                        self.mosaic_event_coord.y_um, "um"))

        # Grid.
        movie_queue += imageCapture.createGrid(self.ui.xSpinBox.value(),
                                               self.ui.ySpinBox.value())

        self.image_capture.takeMovies(movie_queue)
Пример #15
0
    def handleMessageReceived(self, message):

        if message.hasError():
            hdebug.logText("tcp error: " + message.getErrorMessage())
            self.messages = []
            self.waiting_for_response = False
            return

        #
        # If the message does not involve taking a movie and there are no more
        # messages then emit the otherComplete signal.
        #
        if (message.getData("is_other") == True) and (len(self.messages) == 0):
            self.otherComplete.emit()

        if (message.getType() == "Get Mosaic Settings"):
            self.got_settings = True
            #coord.Point.pixels_to_um = message.getResponse("pixels_to_um")
            i = 1
            while message.getResponse("obj" + str(i)) is not None:
                self.newObjectiveData.emit(
                    message.getResponse("obj" + str(i)).split(","))
                i += 1

        if (message.getType() == "Get Objective"):
            if self.curr_objective is None or (
                    self.curr_objective != message.getResponse("objective")):
                self.curr_objective = message.getResponse("objective")
                self.changeObjective.emit(self.curr_objective)

        if (message.getType() == "Get Stage Position"):
            a_point = coord.Point(message.getResponse("stage_x"),
                                  message.getResponse("stage_y"), "um")
            self.getPositionComplete.emit(a_point)

        #
        # self.loadImage() will emit the captureComplete signal.
        #
        if (message.getType() == "Take Movie"):
            self.loadImage(self.directory + message.getData("name") + ".dax")

        if (len(self.messages) > 0):
            self.tcp_client.sendMessage(self.messages.pop(0))
        else:
            self.waiting_for_response = False
Пример #16
0
    def keyPressEvent(self, event):
        """
        Handles key press events. Valid events are:
        'space' Take a picture.
        '3' Take a 3 picture spiral.
        '5' Take a 5 picture spiral.
        '7' Take a 7 picture spiral.
        '9' Take a 9 picture spiral.
        'g' Take a grid of pictures.
        'p' Add the current cursor position to the list of positions.
        's' Add the current cursor position to the list of sections.
        """
        event_pos = self.mapFromGlobal(QtGui.QCursor.pos())
        pointf = self.mapToScene(event_pos)
        a_coord = coord.Point(pointf.x(), pointf.y(), "pix")
        self.mosaicViewKeyPressEvent.emit(event, a_coord)

        super().keyPressEvent(event)
Пример #17
0
    def handleExtrapolateTakeMovie(self, a_coord):
        """
        This is called on the next right click after the extrapolate action was selected.
        """
        movie_queue = []

        # Starting point.
        x_um = a_coord.x_um + (a_coord.x_um -
                               self.mosaic_view.extrapolate_start.x_um)
        y_um = a_coord.y_um + (a_coord.y_um -
                               self.mosaic_view.extrapolate_start.y_um)
        movie_queue.append(coord.Point(x_um, y_um, "um"))

        # Spiral.
        movie_queue += imageCapture.createSpiral(self.extrapolate_count)

        self.mosaic_view.extrapolate_start = None
        self.image_capture.takeMovies(movie_queue)
Пример #18
0
    def handleImageGridButton(self, ignored):
        """
        Handle taking a grid pattern when the 'Acquire' button is clicked.
        """
        movie_queue = []

        # Starting point.
        x_start_um = self.ui.xStartPosSpinBox.value()
        y_start_um = self.ui.yStartPosSpinBox.value()
        movie_queue.append(coord.Point(x_start_um, y_start_um, "um"))

        # Grid.
        movie_queue += imageCapture.createGrid(self.ui.xSpinBox.value(),
                                               self.ui.ySpinBox.value())

        self.ui.imageGridButton.setText("Abort")
        self.ui.imageGridButton.setStyleSheet("QPushButton { color: red }")

        self.image_capture.takeMovies(movie_queue)
Пример #19
0
    def takeSingleMovie(self, movie_pos):
        """
        This takes a single movie as the specified position corrected 
        for the current offset.

        Clients should not use this method, they should always takeMovies().
        """
        current_offset = self.objectives.getCurrentOffset()

        # Bail out if we don't have any objectives information. This
        # probably means HAL is not running or we can't talk to it.
        if current_offset is None:
            return

        pos = coord.Point(movie_pos.x_um - current_offset.x_um,
                          movie_pos.y_um - current_offset.y_um, "um")

        self.smc = self.movie_taker(comm_instance=self.comm,
                                    disconnect=False,
                                    directory=self.directory,
                                    filename=self.filename,
                                    finalizer_fn=self.handleMovieTaken,
                                    pos=pos)
        return self.smc.start()
Пример #20
0
    def nextMovie(self):
        """
        Take the next movie, or disconnect if there are no more movies to take.
        """
        if (len(self.movie_queue) > 0):

            # Figure out where to take the movie.
            elt = self.movie_queue[0]
            if isinstance(elt, list):
                [dx, dy] = elt
                [im_x_um, im_y_um] = self.last_image.getSizeUm()

                next_x_um = self.current_center.x_um + (
                    1.0 - self.fractional_overlap) * im_x_um * dx
                next_y_um = self.current_center.y_um + (
                    1.0 - self.fractional_overlap) * im_y_um * dy
                movie_pos = coord.Point(next_x_um, next_y_um, "um")

            else:
                self.current_center = elt
                movie_pos = elt

            # Remove from the queue.
            self.movie_queue = self.movie_queue[1:]

            # Take the movie, checking for failure to communicate with HAL.
            if not self.takeSingleMovie(movie_pos):
                self.movie_queue = []
                self.smc = None
                self.sequenceComplete.emit()

        else:
            self.comm.stopCommunication()
            self.smc = None

            self.sequenceComplete.emit()
Пример #21
0
 def mouseMoveEvent(self, event):
     """
     Tracks mouse movements across the view.
     """
     pointf = self.mapToScene(event.pos())
     self.mouseMove.emit(coord.Point(pointf.x(), pointf.y(), "pix"))
Пример #22
0
 def updateMosaicLabel(self, a_point):
     offset_point = coord.Point(a_point.x_um - self.current_offset.x_um,
                                a_point.y_um - self.current_offset.y_um,
                                "um")
     self.ui.mosaicLabel.setText("{0:.2f}, {1:.2f}".format(
         offset_point.x_um, offset_point.y_um))
Пример #23
0
    def __init__(self, parameters, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)

        # Coordinate system setup, the internal scale is 1 pixel is 100nm.
        coord.Point.pixels_to_um = 0.1

        # variables
        self.current_center = coord.Point(0.0, 0.0, "um")
        self.current_offset = coord.Point(0.0, 0.0, "um")
        self.debug = parameters.get("debug")
        self.file_filter = "\S+.dax"
        self.parameters = parameters
        self.picture_queue = []
        self.regexp_str = ""
        self.requested_stage_pos = False
        self.settings = QtCore.QSettings("storm-control", "steve")
        self.snapshot_directory = self.parameters.get("directory")
        self.spin_boxes = []
        self.stage_tracking_timer = QtCore.QTimer(self)
        self.taking_pictures = False

        self.stage_tracking_timer.setInterval(500)

        # ui setup
        self.ui = steveUi.Ui_MainWindow()
        self.ui.setupUi(self)

        self.move(self.settings.value("position", self.pos()))
        self.resize(self.settings.value("size", self.size()))

        # hide some things that we don't currently use & resize group-box.
        self.ui.backgroundComboBox.hide()
        self.ui.backgroundLabel.hide()
        self.ui.moveAllSectionsCheckBox.hide()
        self.ui.showFeaturesCheckBox.hide()
        self.ui.thresholdLabel.hide()
        self.ui.thresholdSlider.hide()
        self.ui.sectionViewSettingsGroupBox.setMaximumHeight(50)

        self.setWindowIcon(QtGui.QIcon("steve.ico"))

        # handling file drops
        self.ui.centralwidget.__class__.dragEnterEvent = self.dragEnterEvent
        self.ui.centralwidget.__class__.dropEvent = self.dropEvent
        self.ui.centralwidget.setAcceptDrops(True)

        # Create a validator for scaleLineEdit.
        self.scale_validator = QtGui.QDoubleValidator(1.0e-6, 1.0e+6, 6,
                                                      self.ui.scaleLineEdit)
        self.ui.scaleLineEdit.setValidator(self.scale_validator)

        # Initialize view.
        self.view = mosaicView.MosaicView(parameters, self.ui.mosaicFrame)
        layout = QtWidgets.QGridLayout(self.ui.mosaicFrame)
        layout.addWidget(self.view)
        self.ui.mosaicFrame.setLayout(layout)
        self.view.show()

        # Initialize positions list.
        self.positions = positions.Positions(parameters, self.view.getScene(),
                                             self.ui.positionsFrame)
        layout = QtWidgets.QGridLayout(self.ui.positionsFrame)
        layout.addWidget(self.positions)
        self.ui.positionsFrame.setLayout(layout)
        self.positions.show()

        # Initialize sections.
        self.sections = sections.Sections(parameters, self.view.getScene(),
                                          self.ui.sectionsDisplayFrame,
                                          self.ui.sectionsScrollArea,
                                          self.ui.sectionsTab)

        # Initialize communications.
        self.comm = capture.Capture(parameters)

        # signals
        self.ui.actionQuit.triggered.connect(self.quit)
        self.ui.actionAdjust_Contrast.triggered.connect(
            self.handleAdjustContrast)
        self.ui.actionDelete_Images.triggered.connect(self.handleDeleteImages)
        self.ui.actionLoad_Movie.triggered.connect(self.handleLoadMovie)
        self.ui.actionLoad_Mosaic.triggered.connect(self.handleLoadMosaic)
        self.ui.actionLoad_Positions.triggered.connect(
            self.handleLoadPositions)
        self.ui.actionSave_Mosaic.triggered.connect(self.handleSaveMosaic)
        self.ui.actionSave_Positions.triggered.connect(
            self.handleSavePositions)
        self.ui.actionSave_Snapshot.triggered.connect(self.handleSnapshot)
        self.ui.actionSet_Working_Directory.triggered.connect(
            self.handleSetWorkingDirectory)
        self.ui.foregroundOpacitySlider.valueChanged.connect(
            self.handleOpacityChange)
        self.ui.getStagePosButton.clicked.connect(self.handleGetStagePosButton)
        self.ui.imageGridButton.clicked.connect(self.handleImageGrid)
        self.ui.scaleLineEdit.textEdited.connect(self.handleScaleChange)
        self.ui.tabWidget.currentChanged.connect(self.handleTabChange)
        self.ui.trackStageCheckBox.stateChanged.connect(self.handleTrackStage)
        self.ui.xSpinBox.valueChanged.connect(self.handleGridChange)
        self.ui.ySpinBox.valueChanged.connect(self.handleGridChange)

        self.stage_tracking_timer.timeout.connect(
            self.handleStageTrackingTimer)

        self.view.addPosition.connect(self.addPositions)
        self.view.addSection.connect(self.addSection)
        self.view.getObjective.connect(self.handleGetObjective)
        self.view.gotoPosition.connect(self.gotoPosition)
        self.view.mouseMove.connect(self.updateMosaicLabel)
        self.view.scaleChange.connect(self.updateScaleLineEdit)
        self.view.takePictures.connect(self.takePictures)

        self.sections.addPositions.connect(self.addPositions)
        self.sections.takePictures.connect(self.takePictures)

        self.comm.captureComplete.connect(self.addImage)
        self.comm.changeObjective.connect(self.handleChangeObjective)
        self.comm.disconnected.connect(self.handleDisconnected)
        self.comm.getPositionComplete.connect(self.handleGetPositionComplete)
        self.comm.newObjectiveData.connect(self.handleNewObjectiveData)
        self.comm.otherComplete.connect(self.handleOtherComplete)

        self.ui.objectivesGroupBox.valueChanged.connect(
            self.handleMOValueChange)

        # Try and get settings from HAL.
        self.comm.commConnect()
        self.comm.getSettings()
Пример #24
0
 def currentLocation(self):
     return coord.Point(self.x_spin_box.value(), self.y_spin_box.value(),
                        "um")
Пример #25
0
 def load(self, directory, index, x, y, angle):
     section_item = SectionItem(
         a_point=coord.Point(float(x), float(y), "um"))
     section_item.setAngle(float(angle))
     return section_item
Пример #26
0
 def load(self, directory, x, y):
     return PositionItem(coord.Point(float(x), float(y), "um"))
Пример #27
0
 def handleChangeObjective(self, objective):
     self.ui.objectivesGroupBox.changeObjective(objective)
     [magnification, x_offset,
      y_offset] = self.ui.objectivesGroupBox.getData(objective)
     self.current_offset = coord.Point(x_offset, y_offset, "um")
Пример #28
0
 def setCenter(self, a_point):
     x_um = a_point.x_um - self.current_offset.x_um
     y_um = a_point.y_um - self.current_offset.y_um
     self.current_center = coord.Point(x_um, y_um, "um")
Пример #29
0
 def movePosition(self, dx_um, dy_um):
     a_point = coord.Point(self.a_point.x_um + dx_um,
                           self.a_point.y_um + dy_um, "um")
     self.setLocation(a_point)
Пример #30
0
 def handleExtrapolate(self, ignored):
     """
     This is called when the extrapolate action is selected from the context menu.
     """
     self.mosaic_view.extrapolate_start = coord.Point(
         self.mosaic_event_coord.x_um, self.mosaic_event_coord.y_um, "um")