Skip to content
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

Functions adapted to hyperspy-based methods #44

Merged
merged 32 commits into from
Feb 21, 2021
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e0334e3
Clarification of grating shift correction
jordiferrero Nov 11, 2020
b4c6d13
Start with using hyperspy spikes finder
jordiferrero Nov 11, 2020
094dc38
Clean up
jordiferrero Nov 11, 2020
f445014
Add subtract background
jordiferrero Nov 11, 2020
35a82ca
Removed bkg_subtraction from the CommonLumi class
jordiferrero Nov 22, 2020
084162a
Generalised the background_subtraction_from_file function
jordiferrero Nov 22, 2020
5cd0a1f
Tests added for LumiSpectrum
jordiferrero Nov 22, 2020
8e5cc8c
Final fixes for the background_subtraction_from_file function
jordiferrero Nov 22, 2020
0b5a3ce
Merge branch 'master' into hyperspy_based
jordiferrero Jan 19, 2021
c0eb744
Comment out failing tests
jordiferrero Jan 21, 2021
4e3f03e
Fix on remove_background
jordiferrero Jan 21, 2021
e8955ba
Fix remove_background_from_file
jordiferrero Jan 21, 2021
df13df8
Adapted spike_removal
jordiferrero Jan 22, 2021
b99d8ee
Added signal_mask maker method
jordiferrero Jan 22, 2021
699b001
Docstrings for remove_spikes
jordiferrero Jan 22, 2021
29811d7
Remove old spike removal function
jordiferrero Jan 22, 2021
999be1e
Add test_cl_spectrum.py file
jordiferrero Jan 22, 2021
e47d993
Update test_cl_spectrum.py file
jordiferrero Jan 23, 2021
f600c5f
Added all tests for remove_spikes()
jordiferrero Jan 24, 2021
12d8f06
kwargs fix for remove_spikes()
jordiferrero Jan 24, 2021
fa01ca4
Reverse kwargs fix for remove_spikes()
jordiferrero Jan 24, 2021
dca5c7b
Trying to fix test build failing
jordiferrero Jan 24, 2021
7de7d00
Trying to fix test build failing
jordiferrero Jan 24, 2021
3e51296
Trying to fix test build failing
jordiferrero Jan 24, 2021
81aed73
Trying to fix test build failing
jordiferrero Jan 24, 2021
d2607c6
Trying to fix test build failing
jordiferrero Jan 24, 2021
e1e064d
Fixed and adapted spike removal
jordiferrero Feb 21, 2021
f0b45fa
Check for availability of parameter
jordiferrero Feb 21, 2021
e1ee260
Fix error
jordiferrero Feb 21, 2021
9ed6dda
Fix errors
jordiferrero Feb 21, 2021
7dc4995
Fix final errors
jordiferrero Feb 21, 2021
9606e2f
Fix final errors
jordiferrero Feb 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 10 additions & 4 deletions lumispy/signals/cl_sem_spectrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,20 @@
class CLSEMSpectrum(CLSpectrum):
_signal_type = "CL_SEM"

def correct_grating_shift(self, cal_factor_x_axis, corr_factor_grating, field_of_view):
def correct_grating_shift(self, cal_factor_x_axis, corr_factor_grating, sem_magnification, **kwargs):
""""
Applies shift caused by the grating offset wrt the scanning centre.
Authorship: Gunnar Kusch (gk419@cam.ac.uk)

:param cal_factor_x_axis: The navigation correction factor.
:param corr_factor_grating: The grating correction factor.
:param field_of_view: The SEM field of view (FOV).
:param sem_magnification: The SEM (real) magnification value.
For the Attolight original metadata, take the `SEM.Real_Magnification` value
:param kwargs: The parameters passed to `hyperspy.align1D()` function like:
interpolation_method ('linear', 'nearest', 'zero', 'slinear', 'quadratic, 'cubic')
parallel: Bool
crop, expand, fill_value ...

"""

# Avoid correcting for this shift twice (first time it fails, so except
Expand All @@ -47,7 +53,7 @@ def correct_grating_shift(self, cal_factor_x_axis, corr_factor_grating, field_of
# Get all relevant parameters
nx = self.axes_manager.navigation_shape[0]
ny = self.axes_manager.navigation_shape[1]
fov = field_of_view
fov = sem_magnification

# Correction of the Wavelength Shift along the X-Axis
calax = cal_factor_x_axis / (fov * nx)
Expand All @@ -57,7 +63,7 @@ def correct_grating_shift(self, cal_factor_x_axis, corr_factor_grating, field_of
corr_factor_grating * calax * 1000)
barray = np.full((ny, nx), garray)

self.shift1D(barray)
self.shift1D(barray, **kwargs)

# Store modification in metadata
self.metadata.set_item("Signal.grating_corrected", True)
Expand Down
118 changes: 81 additions & 37 deletions lumispy/signals/cl_spectrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

from hyperspy._signals.lazy import LazySignal
from lumispy.signals.luminescence_spectrum import LumiSpectrum
from hyperspy.signal_tools import SpikesRemoval
import warnings


class CLSpectrum(LumiSpectrum):
Expand All @@ -33,49 +35,91 @@ class CLSpectrum(LumiSpectrum):
_signal_type = "CL"
_signal_dimension = 1

def cosmic_rays_subtraction(self, extra_percent=50, inplace=False, **kwargs):
"""
Masks the cosmic rays away
def _make_signal_mask(self, luminescence_roi):

ax = self.axes_manager.signal_axes[0].axis
signal_mask = np.ones(np.shape(ax))

if len(np.shape(luminescence_roi)) == 1:
luminescence_roi = np.array([luminescence_roi])

Parameters
-----------
extra_percent : float
Extra percent of intensity added to the maximum value of the mean spectrum, which is used to threshold. Default is an extra 500% (x5) to the maximum intensity value of the mean spectrum.
for p in luminescence_roi:
x, w = p
x_min = x - w / 2
x_max = x + w / 2
index_min = np.abs(ax - x_min).argmin()
index_max = np.abs(ax - x_max).argmin()
signal_mask[index_min:index_max + 1] *= 0

inplace : bool
return np.invert(signal_mask.astype('bool'))

def remove_spikes(self, threshold='auto', add_noise=True, noise_type='poisson',
show_diagnosis_histogram=False, inplace=False, luminescence_roi=None, signal_mask=None,
navigation_mask=None, default_spike_width=5, **kwargs):
"""
Hyperspy-based spike removal function.
If a GUI interactive spike removal tool is desired, use `s.spikes_removal_tool()` instead.

:param threshold: 'auto' or int
The derivative magnitude threshold above which to find spikes.
If `int` set the threshold value use for the detecting the spikes.
If `auto`, determine the threshold value as being the first zero
value in the histogram obtained from the
:py:meth:`~hyperspy.signals._signal1d.Signal1D.spikes_diagnosis`
method.
:param add_noise: bool
Whether to add noise to the interpolated part of the spectrum.
The noise properties defined in the Signal metadata are used if present,
otherwise 'poisson' shot noise is used as a default.
:param noise_type: str
By default 'poission' shoot noise is used if `add_noise` is True.
Noise types: "white", "heteroscedastic" or "poisson".
:param show_diagnosis_histogram: bool
Plot or not the derivative histogram to show the magnitude of the spikes present.
:param inplace: bool
If False, a new signal object is created and returned. If True, the original signal object is modified.
:param luminescence_roi: array
The peak position and peak widths of the peaks in the luminescence spectrum.
In the form of an array of pairwise elements [[peak1_x, peak1_width], [peak2_x, peak2_width],...]
in the units of the signal axis. It creates a signal_mask protecting the peak regions.
To be used instead of `signal_mask`.
:param signal_mask: boolean array
Restricts the operation to the signal locations not marked as True (masked).
:param navigation_mask: boolean array
Restricts the operation to the navigation locations not marked as True (masked).
:param default_spike_width: int
Width over which to do the interpolation when removing all spike.
:param kwargs: dict
Keyword arguments pass to `hyperspy.signal.signal.BaseSignal.get_histogram`.

:return: None or CLSpectrum
Depends on inplace, returns or overwrites the CLSpectrum after spike removal.
"""
if luminescence_roi is not None and signal_mask is None:
signal_mask = self._make_signal_mask(luminescence_roi)

if show_diagnosis_histogram:
self.spikes_diagnosis(navigation_mask=navigation_mask, signal_mask=signal_mask,
**kwargs)
if inplace:
signal = self
else:
signal = self.deepcopy()

spikes_removal = SpikesRemoval(signal=signal, navigation_mask=navigation_mask, signal_mask=signal_mask,
jordiferrero marked this conversation as resolved.
Show resolved Hide resolved
threshold=threshold, default_spike_width=default_spike_width,
add_noise=add_noise,)

setattr(spikes_removal, 'noise_type', noise_type)
jordiferrero marked this conversation as resolved.
Show resolved Hide resolved

if threshold == 'auto':
warnings.warn('Threshold value found: {:.2f}'.format(spikes_removal.threshold), UserWarning)

def get_threshold(self, extra_percent):
# Get the max threshold from the mean spectrum maximum
max_threshold = max(self.mean().data)
# Add an extra % of threshold
max_threshold = max_threshold * extra_percent
return max_threshold

def remove_cosmic_ray(spectrum, threshold, mean_spectrum):
# Remove cosmic ray leaving the spectrum pixel as normal noise
# TO DO: Modify noise creation to be relative to actual real noise.
if max(spectrum.data) > threshold:
import statistics
mean = statistics.mean(mean_spectrum.data)
stdev = statistics.stdev(mean_spectrum.data)
noise = np.random.normal(mean, stdev, spectrum.shape[0])
spectrum.data = noise
return spectrum

threshold = get_threshold(self, extra_percent)
mean_spectrum = self.mean()

if not inplace:
signal_filtered = self.map(remove_cosmic_ray, threshold=threshold, mean_spectrum=mean_spectrum,
show_progressbar=True, inplace=False)
signal_filtered.metadata.set_item("Signal.cosmic_rays_subtracted_extra_percent", extra_percent)
return signal_filtered
spikes_removal.remove_all_spikes()
if inplace:
return
else:
self.metadata.set_item("Signal.cosmic_rays_subtracted_extra_percent", extra_percent)
return self.map(remove_cosmic_ray, threshold=threshold, mean_spectrum=mean_spectrum, show_progressbar=True,
inplace=True)
return signal


class LazyCLSpectrum(LazySignal, CLSpectrum):
Expand Down
3 changes: 1 addition & 2 deletions lumispy/signals/common_luminescence.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"""Signal class for Luminescence data (BaseSignal class).
"""


class CommonLumi:
"""General Luminescence signal class (dimensionless).
----------
Expand Down Expand Up @@ -55,5 +56,3 @@ def crop_edges(self, crop_px):
signal_cropped.metadata.set_item("Signal.cropped_edges", crop_px)

return signal_cropped