-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding an interactive way to slice HS over a wavelength range, and view the result spatially! #139
Comments
This makes sense to have such features; as an alternative of implementing new classes, I would suggest to use already existing functionalities using the following approach: # Step 1: find peak, use hyperspy find_peaks_ohaver?
peaks =...
width = ...
# Step 2: add roi to figure
# Initialise the roi with the value from the step 1 and the corresponding/given width
roi1_signal = hs.roi.SpanROI(peaks[0]-width/2, peaks[0]+width/2).interactive(s, color="red")
roi2_signal = hs.roi.SpanROI(peaks[1]-width/2, peaks[1]+width/2).interactive(s, color="red")
# Step 3: generate map from signal
map1 = hs.interactive(roi1_signal.sum)
map2 = hs.interactive(roi2_signal.sum)
# Step 4: generate overlay maps figure
hs.plot.plot_images([map1, map2], overlay=True) In the first two steps need the correct argument to be efficient (avoid redundant computation) and are very similar to: https://github.com/pyxem/pyxem/blob/996651e5c2ac22cbaf0e11fca1eed8cbd5a35616/pyxem/signals/common_diffraction.py#L76-L127 The last step is the overlay of the two (or more) maps and I am not sure if it would be interactive, if not, this should be fixed in hyperspy. This could be nicely wrapped up in a signal method, which could possibly go in hyperspy as this is a generic functionality and other spectroscopy technique could benefit from it. |
Great thanks so much for the feedback. Indeed the functionality I want to add looks very similar to the one you linked in I do think the ability to have multiple 'channels' would be quite beneficial, and I think interactivity is a must for this to be useful for people to quickly use this tool. I do think such a thing could be widely useful, but I don't know what the philosophy is hyperspy is in terms of stacking more functionality into the signal classes. I'm super impressed it looks like this can be accomplished with Sadly I have tried to get the snippet you have suggested working, I'm not sure where I'm going wrong:
From that I get:
Using the latest What's worse, I just updated from a dev version of |
Ok, I've kept going with the branch here: https://github.com/0Hughman0/lumispy/blob/auto_peak_map/lumispy/utils/analysis.py I am trying to make a bit more use of the roi functionality. I did try chaining together events using |
Following the approach used in https://github.com/pyxem/pyxem/blob/996651e5c2ac22cbaf0e11fca1eed8cbd5a35616/pyxem/signals/common_diffraction.py#L76-L127, below is an example that works ignoring the part with import hyperspy.api as hs
import numpy as np
# generate some appropriately shaped data
s = hs.signals.Signal1D(data=np.random.random((64, 64, 1024)),
axes=[{'name': 'x', 'size': 64},
{'name': 'y', 'size': 64},
{'name': 'sig', 'size': 1024}])
peaks = [350, 750]
widths = [100, 50]
s.plot()
# Initialise the roi with the value from the step 1 and the corresponding/given width
roi1 = hs.roi.SpanROI(peaks[0]-widths[0]/2, peaks[0]+widths[0]/2)
roi2 = hs.roi.SpanROI(peaks[1]-widths[1]/2, peaks[1]+widths[1]/2)
roi1_signal = roi1.interactive(s, color="red", axes=s.axes_manager.signal_axes)
roi2_signal = roi2.interactive(s, color="green", axes=s.axes_manager.signal_axes)
# placehodler for the sum
roi1_sum = roi1_signal.sum(axis=roi1_signal.axes_manager.signal_axes).T
roi2_sum = roi2_signal.sum(axis=roi2_signal.axes_manager.signal_axes).T
hs.interactive(
roi1_signal.nansum,
axis=roi1_signal.axes_manager.signal_axes,
event=roi1.events.changed,
recompute_out_event=None,
out=roi1_sum,
)
hs.interactive(
roi2_signal.nansum,
axis=roi2_signal.axes_manager.signal_axes,
event=roi2.events.changed,
recompute_out_event=None,
out=roi2_sum,
)
# # Plot the result
roi1_sum.plot()
roi2_sum.plot()
# This part is the one that needs improvement to be interactive
# hs.plot.plot_images([roi1_sum, roi1_sum]) |
Regarding implementing it in |
@0Hughman0 thanks for the contribution! Let us know if you managed to make it work using hyperspy interactive method with 2d images. I have also tried in the past and got very confused with the interactivity of 2 rois in parallel. |
Indeed, where possible to use existing HyperSpy functions that makes sense. As brought up by @jordiferrero in #55 we can consider to still have a set of dedicated plot functions in LumiSpy amending those of HyperSpy - just because it is easier for some types of plots to have a dedicated function and not to have to work with a complicated set of options to a more generic function. |
Thanks for the encouragement. I will have a go at achieving the same thing with built-in hyperspy functionality. Although it sounds like from what you are saying, @ericpre, it will not be possible to overlay the maps and have them automatically update until there's a some tweaks to the From briefly looking at the source, I think either I don't know how people feel about having a navigation plot (where you select your wavelength ranges), but multiple maps of the integrated counts for each 'channel'? It's not quite a 1 to 1 replication of the Dorset functionality, but probably still useful. |
ok please see #148, I haven't gone as far as writing tests and docstrings (excited to try pytest-mpl!) |
As it has been done for |
Upstreamed to hyperspy/hyperspy#3224 |
Closing as hyperspy/hyperspy#3224 was merged and is included in HyperSpy 2.0 |
Describe the functionality you would like to see.
In the context of taking hyperspectral maps, sometimes you may have a sample where in different regions one would expect peaks at different wavelengths to become dominant.
It's useful to be able to quickly scan over a given wavelength (or energy!) range, and see how the intensity of signals within that range vary spatially.
Describe the context
If implemented correctly, this could be used for a number of different hyperspectral signals.
The Dorset software for Chronos CL systems has this feature, but as far as I know this doesn't exist in Lumispy/ Hyperspy.
Proposed Solution
Perhaps this specific sort of analysis is outside of the scope of Lumispy. However, I thought something like this might fit well into the
utils
section of the library.I have put together a provisional implementation here:
https://github.com/0Hughman0/lumispy/blob/0fc6fa18e82069af116acdfdc066fb244da05387/lumispy/utils/analysis.py#L4
I've called the feature 'AutoPeakMap'... not sure if this is the best name!
An example would be:
Renders two plots, the 'navigator', in the hyperspy sense:
and the 'signal':
The ranges in the 'navigator' can be moved around interactively and the signal plot will update accordingly.
For more quick and dirty analysis I implemented a convenience method:
Which chooses sensible (enough) defaults for the
RangeChannel
s.If this is something you think could slot into LumiSpy, I'll go ahead and write the tests and expand the docstrings etc.
Feedback on the implementation/ naming more than welcome!
Thanks,
Hugh
The text was updated successfully, but these errors were encountered: