hyperspy icon indicating copy to clipboard operation
hyperspy copied to clipboard

Add get_line_profile method to BaseSignal

Open magnunor opened this issue 6 years ago • 6 comments

HyperSpy currently lacks an easy to use line profile tool, since the current way of doing it requires doing something like this:

s = hs.load("your_spectrum_file")
s.plot()
line_roi = hs.roi.Line2DROI(x1=1, y1=1, x2=2, y2=2, linewidth=1)
roi1d = line_roi.interactive(s)
roi1d.plot()

This pull requests add a new method to BaseSignal which uses the Line2DROI functionality: get_line_profile. If no arguments are given, it (should) automatically pick some reasonable values, meaning it should work for any signal type and signal size.

  • [x] Base implementation
  • [x] Add to user guide
  • [x] Add images to user guide
  • [x] Add tests
  • [x] ready for review.

To test it

import numpy as np
import hyperspy.api as hs
s = hs.signals.Signal2D(np.random.random((100, 50)))
s_line = s.get_line_profile()
s_line.plot()

magnunor avatar Dec 04 '17 21:12 magnunor

I opted to not make a more general method which works for all region of interest, since that would require a much more extensive checking of which initial values are relevant, and also a lot for testing to make sure it works for all of the ROIs.

Currently, using axes_type='sig' for signals with navigation dimensions does not seem work:

s = hs.signals.Signal2D(np.random.random((100, 50, 20, 30)))
s_line = s.get_line_profile(axes_type='sig') # Does not work
s_line = s.get_line_profile(axes_type='nav') # Works

For axes_type='sig' it gives the error: RuntimeError: xdata and ydata must be the same length

magnunor avatar Dec 04 '17 21:12 magnunor

I've improved the method, mostly by adding more checks for the input. Which means if people pass bad parameters, they'll get some sensible error message.

I've also added some unit test, so only missing user guide now!

As an aside, I'll (probably) add similar methods for measuring lengths, and for calibrating signal scales.

magnunor avatar Dec 16 '17 13:12 magnunor

I've added images of the functionality to the user guide. I also included the script used to generate the images, to make it easier to regenerate them when needed, and possibly if/when we make the user guide images using script (https://github.com/hyperspy/hyperspy/issues/1794#issuecomment-356915540).

Note that there is some bug in the interactive region of interest code, with the initial plot widget being rendered incorrectly. See https://github.com/hyperspy/hyperspy/pull/1785/files#diff-2098be524418bd1a785272e5f08be892 . This resolves itself when the ROI is moved, but I don't know how to do this through a script...

Also, get_line_profile does not currently work for ComplexSignal, but I'm not certain if that is due to my implementation here, or the ROI implementation.

magnunor avatar Jan 13 '18 12:01 magnunor

I've added this tentatively to the 1.4 milestone. However, I am not fully convinced that adding this feature is a good idea. On the one hand, users will love it. On the other hand, I would prefer to used this as a base to implement the feature for all ROIs using just one single method that takes as an argument a ROI instead of taking starting with this the path of adding a method per ROI.

Thoughts?

francisco-dlp avatar Jul 11 '18 08:07 francisco-dlp

Yes, I agree that we should find a better approach. Particularly, we should implement a way to add widgets interactively without having to initialise it first, as it is currently possible to do with the ModifiableSpanSelector and done with the span selector based tools. I am keen to get this done at some point soon.

ericpre avatar Aug 30 '18 13:08 ericpre

I wonder if this could be done in a way similar to what @ericpre did here https://github.com/pyxem/pyxem/pull/565/ ?

dnjohnstone avatar Aug 05 '20 07:08 dnjohnstone