Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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"))
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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")
     ])
Ejemplo n.º 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))
Ejemplo n.º 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")
Ejemplo n.º 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()
Ejemplo n.º 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)
Ejemplo n.º 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()
Ejemplo n.º 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 = []
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 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
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 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()
Ejemplo n.º 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()
Ejemplo n.º 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"))
Ejemplo n.º 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))
Ejemplo n.º 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()
Ejemplo n.º 24
0
 def currentLocation(self):
     return coord.Point(self.x_spin_box.value(), self.y_spin_box.value(),
                        "um")
Ejemplo n.º 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
Ejemplo n.º 26
0
 def load(self, directory, x, y):
     return PositionItem(coord.Point(float(x), float(y), "um"))
Ejemplo n.º 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")
Ejemplo n.º 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")
Ejemplo n.º 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)
Ejemplo n.º 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")