Example #1
0
    def _repaint_visible(self, drawing_context, visible_rect):
        if self.__delegate:
            canvas_bounds = self.canvas_bounds

            item_width = int(canvas_bounds.width)
            item_height = self.__item_height

            with drawing_context.saver():
                items = self.__delegate.items
                max_index = len(items)
                top_visible_row = visible_rect.top // item_height
                bottom_visible_row = visible_rect.bottom // item_height
                for index in range(top_visible_row, bottom_visible_row + 1):
                    if 0 <= index < max_index:
                        rect = Geometry.IntRect(origin=Geometry.IntPoint(y=index * item_height, x=0),
                                                size=Geometry.IntSize(width=item_width, height=item_height))
                        if rect.intersects_rect(visible_rect):
                            is_selected = self.__selection.contains(index)
                            if is_selected:
                                drawing_context.save()
                                drawing_context.begin_path()
                                drawing_context.rect(rect.left, rect.top, rect.width, rect.height)
                                drawing_context.fill_style = "#3875D6" if self.focused else "#DDD"
                                drawing_context.fill()
                                drawing_context.restore()
                            self.__delegate.paint_item(drawing_context, items[index], rect, is_selected)
Example #2
0
 def test_eels_data_camera_current_is_consistent(self):
     instrument = InstrumentDevice.Instrument("usim_stem_controller")
     # set up the scan context; these are here temporarily until the scan context architecture is fully implemented
     instrument._update_scan_context(Geometry.IntSize(256, 256),
                                     Geometry.FloatPoint(), 10, 0.0)
     instrument._set_scan_context_probe_position(
         instrument.scan_context, Geometry.FloatPoint(0.5, 0.5))
     # grab scan data
     instrument.get_scan_data(
         scan_base.ScanFrameParameters({
             "size": (256, 256),
             "pixel_time_us": 1,
             "fov_nm": 10
         }), 0)
     instrument.validate_probe_position()
     camera = instrument._get_camera_simulator("eels")
     camera_size = camera._camera_shape
     camera.noise.enabled = False
     readout_area = Geometry.IntRect(origin=Geometry.IntPoint(),
                                     size=camera_size)
     binning_shape = Geometry.IntSize(1, 1)
     # get the value at 200eV and ZLP offset of 0
     instrument.ZLPoffset = -20
     exposure_s = 0.01
     d = xd.sum(instrument.get_camera_data("eels", readout_area,
                                           binning_shape, exposure_s),
                axis=0).data
     # confirm it is a reasonable value
     camera_current_pA = numpy.sum(
         d) / exposure_s / instrument.counts_per_electron / 6.242e18 * 1e12
     # print(f"current {camera_current_pA :#.2f}pA")
     self.assertTrue(190 < camera_current_pA < 210)
Example #3
0
 def test_eels_data_is_consistent_when_energy_offset_changes(self):
     instrument = InstrumentDevice.Instrument("usim_stem_controller")
     instrument.get_scan_data(
         scan_base.ScanFrameParameters({
             "size": (256, 256),
             "pixel_time_us": 1,
             "fov_nm": 10
         }), 0)
     instrument.validate_probe_position()
     camera = instrument._get_camera_simulator("eels")
     camera_size = camera._camera_shape
     camera.noise.enabled = False
     readout_area = Geometry.IntRect(origin=Geometry.IntPoint(),
                                     size=camera_size)
     binning_shape = Geometry.IntSize(1, 1)
     # get the value at 200eV and ZLP offset of 0
     instrument.ZLPoffset = 0
     d = xd.sum(instrument.get_camera_data("eels", readout_area,
                                           binning_shape, 0.01),
                axis=0)
     index200_0 = int(
         d.dimensional_calibrations[-1].convert_from_calibrated_value(200))
     value200_0 = d.data[index200_0]
     # get the value at 200eV and ZLP offset of 100
     instrument.ZLPoffset = 100
     d = xd.sum(instrument.get_camera_data("eels", readout_area,
                                           binning_shape, 0.01),
                axis=0)
     index200_100 = int(
         d.dimensional_calibrations[-1].convert_from_calibrated_value(200))
     value200_100 = d.data[index200_100]
     self.assertEqual(int(value200_0 / 100), int(value200_100 / 100))
Example #4
0
 def draw_list_item(self, drawing_context: DrawingContext.DrawingContext,
                    rect: Geometry.IntRect) -> None:
     with drawing_context.saver():
         draw_rect = Geometry.IntRect(origin=rect.top_left +
                                      Geometry.IntPoint(y=4, x=4),
                                      size=Geometry.IntSize(h=72, w=72))
         drawing_context.add(self.__create_thumbnail(draw_rect))
         drawing_context.fill_style = "#000"
         drawing_context.font = "11px serif"
         drawing_context.fill_text(self.title_str, rect.left + 4 + 72 + 4,
                                   rect.top + 4 + 12)
         drawing_context.fill_text(self.format_str, rect.left + 4 + 72 + 4,
                                   rect.top + 4 + 12 + 15)
         drawing_context.fill_text(self.datetime_str,
                                   rect.left + 4 + 72 + 4,
                                   rect.top + 4 + 12 + 15 + 15)
         if self.status_str:
             drawing_context.fill_text(self.status_str,
                                       rect.left + 4 + 72 + 4,
                                       rect.top + 4 + 12 + 15 + 15 + 15)
         else:
             drawing_context.fill_style = "#888"
             drawing_context.fill_text(self.project_str,
                                       rect.left + 4 + 72 + 4,
                                       rect.top + 4 + 12 + 15 + 15 + 15)
Example #5
0
 def test_eels_data_thickness_is_consistent(self):
     instrument = InstrumentDevice.Instrument("usim_stem_controller")
     # use the flake sample
     instrument.sample_index = 0
     # set up the scan context; these are here temporarily until the scan context architecture is fully implemented
     instrument._update_scan_context(Geometry.IntSize(256, 256),
                                     Geometry.FloatPoint(), 10, 0.0)
     instrument._set_scan_context_probe_position(
         instrument.scan_context, Geometry.FloatPoint(0.5, 0.5))
     # grab scan data
     instrument.get_scan_data(
         scan_base.ScanFrameParameters({
             "size": (256, 256),
             "pixel_time_us": 1,
             "fov_nm": 10
         }), 0)
     instrument.validate_probe_position()
     camera = instrument._get_camera_simulator("eels")
     camera_size = camera._camera_shape
     camera.noise.enabled = False
     readout_area = Geometry.IntRect(origin=Geometry.IntPoint(),
                                     size=camera_size)
     binning_shape = Geometry.IntSize(1, 1)
     # get the value at 200eV and ZLP offset of 0
     instrument.ZLPoffset = -20
     d = xd.sum(instrument.get_camera_data("eels", readout_area,
                                           binning_shape, 0.01),
                axis=0).data
     # confirm it is a reasonable value
     # print(measure_thickness(d))
     self.assertTrue(0.40 < measure_thickness(d) < 1.00)
Example #6
0
    def __init__(self, instrument: InstrumentDevice.Instrument,
                 camera_type: str, sensor_dimensions: Geometry.IntSize,
                 counts_per_electron: int) -> None:
        self.__instrument = instrument
        self._camera_type = camera_type
        self._sensor_dimensions = sensor_dimensions
        self._counts_per_electron = counts_per_electron
        self._needs_recalculation = True
        self._last_frame_settings = [
            Geometry.IntRect((0, 0), (0, 0)),
            Geometry.IntSize(), 0.0, None
        ]

        def property_changed(name: str) -> None:
            if name in self.depends_on:
                self._needs_recalculation = True

        self.__property_changed_event_listener = instrument.property_changed_event.listen(
            property_changed)

        # we also need to inform the cameras about changes to the (parked) probe position
        def probe_state_changed(
                probe_state: str,
                probe_position: typing.Optional[Geometry.FloatPoint]) -> None:
            property_changed("probe_state")
            property_changed("probe_position")

        self.__probe_state_changed_event_listener = instrument.probe_state_changed_event.listen(
            probe_state_changed)
Example #7
0
 def plot(self, data: numpy.ndarray, offset_m: Geometry.FloatPoint, fov_nm: Geometry.FloatSize,
          center_nm: Geometry.FloatPoint, shape: Geometry.IntSize) -> int:
     # TODO: how does center_nm interact with stage position?
     # TODO: take into account feature angle
     # TODO: take into account frame parameters angle
     # TODO: expand features to other shapes than rectangle
     scan_rect_m = self.get_scan_rect_m(offset_m, fov_nm, center_nm)
     feature_rect_m = self.get_feature_rect_m()
     sum = 0
     if scan_rect_m.intersects_rect(feature_rect_m):
         feature_rect_top_px = int(shape[0] * (feature_rect_m.top - scan_rect_m.top) / scan_rect_m.height)
         feature_rect_left_px = int(shape[1] * (feature_rect_m.left - scan_rect_m.left) / scan_rect_m.width)
         feature_rect_height_px = int(shape[0] * feature_rect_m.height / scan_rect_m.height)
         feature_rect_width_px = int(shape[1] * feature_rect_m.width / scan_rect_m.width)
         if feature_rect_top_px < 0:
             feature_rect_height_px += feature_rect_top_px
             feature_rect_top_px = 0
         if feature_rect_left_px < 0:
             feature_rect_width_px += feature_rect_left_px
             feature_rect_left_px = 0
         if feature_rect_top_px + feature_rect_height_px > shape[0]:
             feature_rect_height_px = shape[0] - feature_rect_top_px
         if feature_rect_left_px + feature_rect_width_px > shape[1]:
             feature_rect_width_px = shape[1] - feature_rect_left_px
         feature_rect_origin_px = Geometry.IntPoint(y=feature_rect_top_px, x=feature_rect_left_px)
         feature_rect_size_px = Geometry.IntSize(height=feature_rect_height_px, width=feature_rect_width_px)
         feature_rect_px = Geometry.IntRect(feature_rect_origin_px, feature_rect_size_px)
         data[feature_rect_px.top:feature_rect_px.bottom, feature_rect_px.left:feature_rect_px.right] += 1.0
         sum += (feature_rect_px.bottom - feature_rect_px.top) * (feature_rect_px.right - feature_rect_px.left)
     return sum
Example #8
0
    def _repaint_visible(self, drawing_context: DrawingContext.DrawingContext, visible_rect: Geometry.IntRect) -> None:
        canvas_bounds = self.canvas_bounds
        if self.__delegate and canvas_bounds:
            item_width = canvas_bounds.width
            item_height = self.__item_height

            with drawing_context.saver():
                items = self.__delegate.items
                max_index = len(items)
                top_visible_row = visible_rect.top // item_height
                bottom_visible_row = visible_rect.bottom // item_height
                for index in range(top_visible_row, bottom_visible_row + 1):
                    if 0 <= index < max_index:
                        rect = Geometry.IntRect(origin=Geometry.IntPoint(y=index * item_height, x=0),
                                                size=Geometry.IntSize(width=item_width, height=item_height))
                        if rect.intersects_rect(visible_rect):
                            is_selected = self.__selection.contains(index)
                            if is_selected:
                                with drawing_context.saver():
                                    drawing_context.begin_path()
                                    drawing_context.rect(rect.left, rect.top, rect.width, rect.height)
                                    drawing_context.fill_style = "#3875D6" if self.focused else "#DDD"
                                    drawing_context.fill()
                            self.__delegate.paint_item(drawing_context, items[index], rect, is_selected)
                            if index == self.__drop_index:
                                with drawing_context.saver():
                                    drop_border_width = 2.5
                                    rect_in = rect.to_float_rect().inset(drop_border_width / 2, drop_border_width / 2).to_int_rect()
                                    drawing_context.begin_path()
                                    drawing_context.rect(rect_in.left, rect_in.top, rect_in.width, rect_in.height)
                                    drawing_context.line_width = drop_border_width
                                    drawing_context.stroke_style = "rgba(56, 117, 214, 0.8)"
                                    drawing_context.stroke()
Example #9
0
    def _repaint_visible(self, drawing_context: DrawingContext.DrawingContext, visible_rect: Geometry.IntRect) -> None:
        canvas_size = self.canvas_size
        if self.__delegate and canvas_size and canvas_size.height > 0 and canvas_size.width > 0:
            item_size = self.__calculate_item_size(canvas_size)
            items = self.__delegate.items if self.__delegate else list()
            item_count = len(items)
            items_per_row = max(1, int(canvas_size.width / item_size.width) if self.wrap else item_count)
            items_per_column = max(1, int(canvas_size.height / item_size.height) if self.wrap else item_count)

            with drawing_context.saver():
                top_visible_row = visible_rect.top // item_size.height
                bottom_visible_row = visible_rect.bottom // item_size.height
                left_visible_column = visible_rect.left // item_size.width
                right_visible_column = visible_rect.right // item_size.width
                for row in range(top_visible_row, bottom_visible_row + 1):
                    for column in range(left_visible_column, right_visible_column + 1):
                        if self.direction == Direction.Row:
                            index = row * items_per_row + column
                        else:
                            index = row + column * items_per_column
                        if 0 <= index < item_count:
                            rect = Geometry.IntRect(origin=Geometry.IntPoint(y=row * item_size.height, x=column * item_size.width),
                                                    size=Geometry.IntSize(width=item_size.width, height=item_size.height))
                            if rect.intersects_rect(visible_rect):
                                is_selected = self.__selection.contains(index)
                                if is_selected:
                                    with drawing_context.saver():
                                        drawing_context.begin_path()
                                        drawing_context.rect(rect.left, rect.top, rect.width, rect.height)
                                        drawing_context.fill_style = "#3875D6" if self.focused else "#BBB"
                                        drawing_context.fill()
                                self.__delegate.paint_item(drawing_context, items[index], rect, is_selected)
Example #10
0
 def __rect_for_index(self, index: int) -> Geometry.IntRect:
     canvas_bounds = self.canvas_bounds
     if canvas_bounds:
         item_width = canvas_bounds.width
         item_height = self.__item_height
         return Geometry.IntRect(origin=Geometry.IntPoint(y=index * item_height, x=0),
                                 size=Geometry.IntSize(width=item_width, height=item_height))
     return Geometry.IntRect.empty_rect()
Example #11
0
 def __rect_for_index(self, index: int) -> Geometry.IntRect:
     canvas_size = self.canvas_size
     if canvas_size:
         item_size = self.__calculate_item_size(canvas_size)
         item_count = self.__delegate.item_count if self.__delegate else 0
         items_per_row = max(1, int(canvas_size.width / item_size.width) if self.wrap else item_count)
         items_per_column = max(1, int(canvas_size.height / item_size.height) if self.wrap else item_count)
         if self.direction == Direction.Row:
             row = index // items_per_row
             column = index - row * items_per_row
         else:
             column = index // items_per_column
             row = index - column * items_per_column
         return Geometry.IntRect(origin=Geometry.IntPoint(y=row * item_size.height, x=column * item_size.width), size=Geometry.IntSize(width=item_size.width, height=item_size.height))
     return Geometry.IntRect.empty_rect()
Example #12
0
 def test_eels_data_is_consistent_when_energy_offset_changes_with_negative_zlp_offset(
         self):
     instrument = InstrumentDevice.Instrument("usim_stem_controller")
     instrument.get_scan_data(
         scan_base.ScanFrameParameters({
             "size": (256, 256),
             "pixel_time_us": 1,
             "fov_nm": 10
         }), 0)
     instrument.validate_probe_position()
     camera = instrument._get_camera_simulator("eels")
     camera_size = camera._camera_shape
     camera.noise.enabled = False
     readout_area = Geometry.IntRect(origin=Geometry.IntPoint(),
                                     size=camera_size)
     binning_shape = Geometry.IntSize(1, 1)
     # get the value at 200eV and ZLP offset of 0
     instrument.ZLPoffset = -20
     instrument.get_camera_data("eels", readout_area, binning_shape, 0.01)
 def layout(self,
            canvas_origin,
            canvas_size,
            canvas_items,
            *,
            immediate=False):
     r = Geometry.IntRect(origin=canvas_origin, size=canvas_size)
     if canvas_size.width > canvas_size.height:
         r = Geometry.fit_to_size(
             r, Geometry.IntSize(w=canvas_size.height,
                                 h=canvas_size.height))
         super().layout(canvas_origin,
                        r.size,
                        canvas_items,
                        immediate=immediate)
     else:
         r = Geometry.fit_to_size(
             r, Geometry.IntSize(w=canvas_size.width, h=canvas_size.width))
         super().layout(canvas_origin,
                        r.size,
                        canvas_items,
                        immediate=immediate)
 def layout(self,
            canvas_origin: Geometry.IntPoint,
            canvas_size: Geometry.IntSize,
            canvas_items: typing.Sequence[CanvasItem.AbstractCanvasItem],
            *,
            immediate: bool = False) -> None:
     r = Geometry.IntRect(origin=canvas_origin, size=canvas_size)
     if canvas_size.width > canvas_size.height:
         r = Geometry.fit_to_size(
             r, Geometry.IntSize(w=canvas_size.height,
                                 h=canvas_size.height)).to_int_rect()
         super().layout(canvas_origin,
                        r.size,
                        canvas_items,
                        immediate=immediate)
     else:
         r = Geometry.fit_to_size(
             r, Geometry.IntSize(w=canvas_size.width,
                                 h=canvas_size.width)).to_int_rect()
         super().layout(canvas_origin,
                        r.size,
                        canvas_items,
                        immediate=immediate)