hyperspy
hyperspy copied to clipboard
Add get_line_profile method to BaseSignal
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()
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
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.
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.
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?
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.
I wonder if this could be done in a way similar to what @ericpre did here https://github.com/pyxem/pyxem/pull/565/ ?