コード例 #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
ファイル: positions.py プロジェクト: BogdanBintu/MERFISH5
 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
ファイル: objectives.py プロジェクト: BogdanBintu/MERFISH8
    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
ファイル: sections.py プロジェクト: BogdanBintu/MERFISH8
 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
ファイル: sections.py プロジェクト: BogdanBintu/MERFISH8
 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")