def test_chained_interactive(self): s = self.s e1, e2 = Event(), Event() ss = hs.interactive(s.sum, e1, axis=0) sss = hs.interactive(ss.sum, e2, axis=0) np.testing.assert_allclose(sss.data, np.sum(s.data, axis=(0, 1))) s.data += 3.2 nt.assert_false(np.allclose(ss.data, np.sum(s.data, axis=(1)))) e1.trigger() np.testing.assert_allclose(ss.data, np.sum(s.data, axis=(1))) nt.assert_false(np.allclose(sss.data, np.sum(s.data, axis=(0, 1)))) e2.trigger() np.testing.assert_allclose(sss.data, np.sum(s.data, axis=(0, 1)))
def test_interactive_sum_auto_event(self): s = self.s ss = hs.interactive(s.sum, axis=0) np.testing.assert_equal(ss.data, np.sum(s.data, axis=0)) s.data += 3.2 nt.assert_false(np.allclose(ss.data, np.sum(s.data, axis=0))) s.events.data_changed.trigger(s) np.testing.assert_array_equal(ss.data, np.sum(s.data, axis=0))
def test_interactive_sum(self): s = self.s e = Event() ss = hs.interactive(s.sum, e, axis=0) np.testing.assert_array_equal(ss.data, np.sum(s.data, axis=0)) s.data += 3.2 nt.assert_false(np.allclose(ss.data, np.sum(s.data, axis=0))) e.trigger() np.testing.assert_array_equal(ss.data, np.sum(s.data, axis=0))
def test_interactive_sum_no_out(self): s = self.s def sumf(axis): return s.sum(axis=axis) e = Event() ss = hs.interactive(sumf, e, axis=0) np.testing.assert_array_equal(ss.data, np.sum(s.data, axis=0)) s.data += 3.2 assert not np.allclose(ss.data, np.sum(s.data, axis=0)) e.trigger() np.testing.assert_array_equal(ss.data, np.sum(s.data, axis=0))
def test_interactive_sum_no_out(self): s = self.s def sumf(axis): return s.sum(axis=axis) e = Event() ss = hs.interactive(sumf, e, axis=0) np.testing.assert_array_equal(ss.data, np.sum(s.data, axis=0)) s.data += 3.2 nt.assert_false(np.allclose(ss.data, np.sum(s.data, axis=0))) e.trigger() np.testing.assert_array_equal(ss.data, np.sum(s.data, axis=0))
def test_recompute_auto_recompute(self): s = self.s ss = hs.interactive(s.sum, axis=0) # Check eveything as normal first np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) # Modify axes and data in-place m = mock.Mock() s.axes_manager.events.any_axis_changed.connect(m.changed) s.crop(1, 1) # data shape (2, 3, 50) nt.assert_true(m.changed.called) np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) # Finally, check that axes are updated as they should nt.assert_equal(ss.axes_manager.navigation_axes[0].offset, 1)
def test_recompute_auto_recompute(self): s = self.s ss = hs.interactive(s.sum, axis=0) # Check eveything as normal first np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) # Modify axes and data in-place m = mock.Mock() s.axes_manager.events.any_axis_changed.connect(m.changed) s.crop(1, 1) # data shape (2, 3, 50) assert m.changed.called np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) # Finally, check that axes are updated as they should assert ss.axes_manager.navigation_axes[0].offset == 1
def test_two_recompute_events(self): s = self.s e1 = Event() e2 = Event() ss = hs.interactive(s.sum, event=None, recompute_out_event=(e1, e2), axis=0) s.data[:] = 0 e1.trigger() np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) s.data[:] = 1 e2.trigger() np.testing.assert_equal(ss.data, np.sum(s.data, axis=1))
def plot_interactive_virtual_image(self, left, right, **kwargs): """Plots an interactive virtual image formed by integrating scatterered intensity over a specified range. Parameters ---------- left : float Lower bound of the data range to be plotted. right : float Upper bound of the data range to be plotted. **kwargs: Keyword arguments to be passed to `ElectronDiffractionProfile.plot` Examples -------- .. code-block:: python rp.plot_interactive_virtual_image(left=0.5, right=0.7) """ # Define ROI roi = SpanROI(left=left, right=right) # Plot signal self.plot(**kwargs) # Add the ROI to the appropriate signal axes. roi.add_widget(self, axes=self.axes_manager.signal_axes) # Create an output signal for the virtual dark-field calculation. dark_field = roi.interactive(self, navigation_signal='same') dark_field_placeholder = \ BaseSignal(np.zeros(self.axes_manager.navigation_shape[::-1])) # Create an interactive signal dark_field_sum = interactive( # Formed from the sum of the pixels in the dark-field signal dark_field.sum, # That updates whenever the widget is moved event=dark_field.axes_manager.events.any_axis_changed, axis=dark_field.axes_manager.signal_axes, # And outputs into the prepared placeholder. out=dark_field_placeholder, ) # Set the parameters dark_field_sum.axes_manager.update_axes_attributes_from( self.axes_manager.navigation_axes, ['scale', 'offset', 'units', 'name']) dark_field_sum.metadata.General.title = "Virtual Dark Field" # Plot the result dark_field_sum.plot()
def test_two_update_events(self): s = self.s e1 = Event() e2 = Event() ss = hs.interactive( s.sum, event=( e1, e2), recompute_out_event=None, axis=0) s.data[:] = 0 e1.trigger() np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) s.data[:] = 1 e2.trigger() np.testing.assert_equal(ss.data, np.sum(s.data, axis=1))
def test_recompute(self): s = self.s e1 = Event() e2 = Event() ss = hs.interactive(s.sum, e1, recompute_out_event=e2, axis=0) # Check eveything as normal first np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) # Modify axes and data in-place s.crop(1, 1) # data shape (2, 3, 50) # Check that data is no longer comparable nt.assert_not_equal(ss.data.shape, np.sum(s.data, axis=1).shape) # Check that normal event raises an exception due to the invalid shape nt.assert_raises(ValueError, e1.trigger) # Check that recompute event fixes issue e2.trigger() np.testing.assert_equal(ss.data, np.sum(s.data, axis=1)) # Finally, check that axes are updated as they should nt.assert_equal(ss.axes_manager.navigation_axes[0].offset, 1)
def live_fft(self, signals=None, shift=True, power_spectrum=True): """ The live FFT dynamically calculates the FFT as the user navigates. """ if signals is None: signals = self.ui.get_selected_signals() if signals is None: return # Make sure we can iterate if isinstance(signals, hs.signals.BaseSignal): signals = (signals, ) if len(signals) < 1: return s = signals[0] if isinstance(s, hs.signals.Signal2D): extent = s.axes_manager.signal_extent left = (extent[1] - extent[0]) / 4 + extent[0] right = 3 * (extent[1] - extent[0]) / 4 + extent[0] top = (extent[3] - extent[2]) / 4 + extent[2] bottom = 3 * (extent[3] - extent[2]) / 4 + extent[2] roi = hs.roi.RectangularROI(left, top, right, bottom) elif isinstance(s, hs.signals.Signal1D): extent = s.axes_manager.signal_extent half_range = (extent[1] - extent[0]) / 4 roi = hs.roi.SpanROI(half_range + extent[0], 3 * half_range + extent[0]) else: mb = QMessageBox(QMessageBox.Information, tr("Live FFT"), tr("Only Signal2D and Signal1D are supported."), QMessageBox.Ok) mb.exec_() roi.add_widget(s) roi_signal = roi.interactive(s, recompute_out_event=False) s_roi_fft = hs.interactive(roi_signal.fft, event=roi.events.changed, recompute_out_event=False, shift=shift) s_roi_fft.plot(power_spectrum=power_spectrum)
def plot_interactive_virtual_image(self, roi, **kwargs): """Plots an interactive virtual image formed with a specified and adjustable roi. Parameters ---------- roi : :obj:`hyperspy.roi.BaseInteractiveROI` Any interactive ROI detailed in HyperSpy. **kwargs: Keyword arguments to be passed to `Diffraction2D.plot` Examples -------- .. code-block:: python import hyperspy.api as hs roi = hs.roi.CircleROI(0, 0, 0.2) data.plot_interactive_virtual_image(roi) """ self.plot(**kwargs) roi.add_widget(self, axes=self.axes_manager.signal_axes) # Add the ROI to the appropriate signal axes. dark_field = roi.interactive(self, navigation_signal='same') dark_field_placeholder = \ BaseSignal(np.zeros(self.axes_manager.navigation_shape[::-1])) # Create an output signal for the virtual dark-field calculation. dark_field_sum = interactive( # Create an interactive signal dark_field.sum, # Formed from the sum of the pixels in the dark-field signal event=dark_field.axes_manager.events.any_axis_changed, # That updates whenever the widget is moved axis=dark_field.axes_manager.signal_axes, out=dark_field_placeholder, # And outputs into the prepared placeholder. ) dark_field_sum.axes_manager.update_axes_attributes_from( self.axes_manager.navigation_axes, ['scale', 'offset', 'units', 'name']) dark_field_sum.metadata.General.title = "Virtual Dark Field" # Set the parameters dark_field_sum.plot() # Plot the result
def plot_roi(self, noised=False): """Implements the Hyperspy tool to analyse regions of interest. Arguments --------- noised: optional, bool If True, the noised data is used. If False, the noise-free data is shown. Default is False. """ if noised and self.ndata is None: raise ValueError( 'Can not display noised data when snr has been set to None.') # Create Hyperspy data if noised: hs_data = hs.signals.Signal1D(self.ndata) else: hs_data = hs.signals.Signal1D(self.data) hs_data.axes_manager = self.hsdata.axes_manager hs_data.metadata = self.hsdata.metadata # Create ROI roi = hs.roi.RectangularROI(left=0, top=0, right=5, bottom=5) # Plot Signal hs_data.plot() hs_data._plot.navigator_plot.ax.images[-1].set_cmap("viridis") # Creates an interactively sliced Signal roi = roi.interactive(hs_data) # Computes the mean over the ROI mean_roi = hs.interactive( roi.mean, event=roi.axes_manager.events.any_axis_changed) # Plot ROI mean_roi.plot()
def virtual_aperture(self, signal=None, annulus=False, navigate=False): ui = self.ui if signal is None: signal = ui.get_selected_signal() dd = np.array([a.high_value + a.low_value for a in signal.axes_manager.signal_axes]) / 2.0 r = hs.roi.CircleROI(dd[0], dd[1], signal.axes_manager.signal_axes[0].scale*3) if annulus: r.r_inner = signal.axes_manager.signal_axes[0].scale*2 s_virtual = r.interactive(signal, None, axes=signal.axes_manager.signal_axes) s_nav = hs.interactive( s_virtual.mean, s_virtual.events.data_changed, axis=s_virtual.axes_manager.signal_axes) s_nav.axes_manager.set_signal_dimension(2) if navigate: signal.plot(navigator=s_nav) signal._plot.navigator_plot.update() s_nav.events.data_changed.connect( signal._plot.navigator_plot.update, []) utils.on_figure_window_close( signal._plot.navigator_plot.figure, partial(self._on_close, r)) else: s_nav.plot() utils.on_figure_window_close( s_nav._plot.signal_plot.figure, partial(self._on_close, r)) if navigate: r.add_widget(signal, axes=signal.axes_manager.signal_axes, color='darkorange') else: r.add_widget(signal, axes=signal.axes_manager.signal_axes) self._rois.append(r) self.record_code("<p>.virtual_aperture(navigate=%s)" % navigate)
def virtual_aperture(self, signal=None, annulus=False, navigate=False): ui = self.ui if signal is None: signal = ui.get_selected_signal() dd = np.array([ a.high_value + a.low_value for a in signal.axes_manager.signal_axes ]) / 2.0 r = hs.roi.CircleROI(dd[0], dd[1], signal.axes_manager.signal_axes[0].scale * 3) if annulus: r.r_inner = signal.axes_manager.signal_axes[0].scale * 2 s_virtual = r.interactive(signal, None, axes=signal.axes_manager.signal_axes) s_nav = hs.interactive(s_virtual.mean, s_virtual.events.data_changed, axis=s_virtual.axes_manager.signal_axes) s_nav.axes_manager.set_signal_dimension(2) if navigate: signal.plot(navigator=s_nav) signal._plot.navigator_plot.update() s_nav.events.data_changed.connect( signal._plot.navigator_plot.update, []) utils.on_figure_window_close(signal._plot.navigator_plot.figure, partial(self._on_close, r)) else: s_nav.plot() utils.on_figure_window_close(s_nav._plot.signal_plot.figure, partial(self._on_close, r)) if navigate: r.add_widget(signal, axes=signal.axes_manager.signal_axes, color='darkorange') else: r.add_widget(signal, axes=signal.axes_manager.signal_axes) self._rois.append(r) self.record_code("<p>.virtual_aperture(navigate=%s)" % navigate)
def plot_roi(self): """Implements the Hyperspy tool to analyse regions of interest. """ # Create Hyperspy data hs_data = hs.signals.Signal1D(self.hsdata.data) hs_data.axes_manager = self.hsdata.axes_manager hs_data.metadata = self.hsdata.metadata # Create ROI roi = hs.roi.RectangularROI(left=0, top=0, right=5, bottom=5) # Plot Signal hs_data.plot() # Creates an interactively sliced Signal roi = roi.interactive(hs_data) # Computes the mean over the ROI mean_roi = hs.interactive( roi.mean, event=roi.axes_manager.events.any_axis_changed) # Plot ROI mean_roi.plot()
def set_ROI(cls, s, shape="circle", color="r", interactive=False): """ Selects an interactive region of interst (ROI) to the signal :type s: hyperspy signal :param s: the signal of interest :type shape: string :param shape: the description of the ROI; circle, ring, rectangle :type interactive: boolean :param interactive: interactive if True, False if left blank :returns: hyperspy roi, hyperspy signal """ import hyperspy.api as hs if s.axes_manager.navigation_dimension < 2: axes = "sig" x_axis = s.axes_manager[s.axes_manager.signal_indices_in_array[1]] y_axis = s.axes_manager[s.axes_manager.signal_indices_in_array[0]] else: axes = "nav" x_axis = s.axes_manager[ s.axes_manager.navigation_indices_in_array[1]] y_axis = s.axes_manager[ s.axes_manager.navigation_indices_in_array[0]] if shape == "circle": x = x_axis.axis[round(x_axis.size / 2)] y = y_axis.axis[round(y_axis.size / 2)] r_outer = x_axis.axis[round(3 * x_axis.size / 4)] sroi = hs.roi.CircleROI(x, y, r=r_outer, color=color) """ s.plot() sroi= sroi.interactive(s) ss = hs.interactive(f=sroi.sum, event=sroi.events.data_changed) """ elif shape == "ring": x = x_axis.axis[round(x_axis.size / 2)] y = y_axis.axis[round(y_axis.size / 2)] r_outer = x_axis.axis[round(4 * x_axis.size / 5)] r_inner = x_axis.axis[round(3 * x_axis.size / 4)] sroi = hs.roi.CircleROI(x, y, r=r_outer, r_inner=r_inner, color=color) """ s.plot() sroi= sroi.interactive(s) ss = hs.interactive(f=sroi.sum, event=sroi.events.data_changed) """ else: if not shape == "rectangle": print("Did not recognize shape, using rectangle") x1 = x_axis.axis[1] x2 = x_axis.axis[round(x_axis.size / 10)] y1 = y_axis.axis[1] y2 = y_axis.axis[round(y_axis.size / 10)] sroi = hs.roi.RectangularROI(x1, y1, x2, y2) if interactive: s.plot() roi_signal = sroi.interactive(s) ss = hs.interactive(f=roi_signal.sum, event=roi_signal.events.data_changed) else: roi_signal = sroi(s) ss = roi_signal.sum() return sroi, ss
def test_interactive_function_return_None(self): e = Event() def function_return_None(): print('function called') hs.interactive(function_return_None, e) e.trigger()