-
Notifications
You must be signed in to change notification settings - Fork 84
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
Large restructure of differential phase contrast class structure #1057
base: main
Are you sure you want to change the base?
Conversation
- All the DPCSignal functionality has been moved to the BeamShift class - BeamShift.plot() default plotting has been changed - Some unit tests with random numbers which were prone to failing randomly has been removed - Some rarely used functions has been removed
@magnunor I would rebase this based on PR that just got merged before you go too much further as that PR moves some things around. Let me know if you need any help here. I would like to make this a subclass of Vector1D but I might have to think about how to make that class a little more robust. |
Done! It was actually a lot less work than I feared :)
I haven't followed the vector signals development too closely, but I think it makes a lot of sense to utilize a signal optimized for vectors for |
- Make new _beam_shift_tools module - Remove Diffraction2D.center_of_mass: -- Move to get_direct_beam_position(method="center_of_mass") - Update many unit tests due to these changes - Update many docstrings due to these changes
Some more progress, major remaining thing is the documentation. The number of added and deleted lines looks daunting, but most of those are due to files having been deleted with the code being moved to a different module. For example the
I'll make a proper list of the all the changes when they're all implemented. |
Two points which would be nice to discuss: In this pull request, the def plot(self):
self.T.plot() I'm not sure if this is the best ways of doing this? I'm thinking at least the args and kwargs should be passed. But I'm also wondering if this sub-optimal since the In |
I think we want to do a couple of things:
There is also the The mask implementation should be better as well... But I'm not sure what the best way to handle that is.... |
I switched |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@magnunor This is starting to look quite good. Just some small changes that I might make if you are okay with that?
@pc494 What are your feelings on breaking the API here? There are quite a few changes to the API here. I know we have been trying to avoid that but we might be reaching the end game where we need to start :).
pyxem/signals/beam_shift.py
Outdated
s_bs = self._deepcopy_with_new_data(plane_image) | ||
return s_bs | ||
|
||
def plot(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add **kwargs here for passing to plot. Also add documentation saying this is equivalent to .T.plot
|
||
|
||
class BeamShift(Signal1D): | ||
"""Signal class for working with shift of the direct beam.""" | ||
|
||
_signal_type = "beam_shift" | ||
|
||
def make_linear_plane(self, mask=None): | ||
def get_linear_plane(self, mask=None, fit_corners=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth testing this with a 5D dataset to make sure that it works with N-Dimensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently this doesn't work on 5 dimensions but we can wait on that for a later PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can assume that the probe positions are always the two first navigation dimensions, we could easily iterate over the remaining navigation dimensions.
We also need to handle BeamShift
signals with 1 navigation dimension.
pyxem/signals/beam_shift.py
Outdated
from hyperspy._signals.lazy import LazySignal | ||
from hyperspy._signals.signal1d import Signal1D | ||
from hyperspy.signals import Signal1D | ||
from hyperspy.utils.plot import plot_images | ||
|
||
|
||
class BeamShift(Signal1D): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@magnunor is it okay if I make a couple of adjustments to this? I think we should make BeamShift a subclass of Vector1D. I'm planning on moving some of the plotting capablilites to that class and then that can be a more general feature. I think the other place where that might be useful is with the StrainMap
class which is essentially plotting 4 Vector quantities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go for it!
@magnunor Do you know why those tests are failing? This seems like a regression but maybe it wasn't tested before. |
Once #1080 is merged do you want to rebase? If we figure out the testing I can take another pass through and then we can think about what it would take to merge? |
Sounds good! I'll do that either late tomorrow, or (most likely) Friday. |
Perfect! |
I merged the current Running WARNING | Hyperspy | Axes labels were requested, but one or both of the axes units and/or name are undefined. Axes decorations have been set to 'ticks' instead. (hyperspy.drawing.utils:1167) This will be a very annoying warning, so we should do something to avoid that.
With regards to the failing tests: this is related to interaction between |
Yay
In this case we know the units are pixels, right? We can just set that? I think we should pass the axes_manager of the original signal as well to the beam shift and maybe allow pixel --> real units?
Hmmm I don't love merging non-passing code into main, but it might be nice to seperate that into a smaller PR. |
@magnunor do you have time to work on this or do you want me to give it a shot. On second thought I think the warnining is totally reasonable... People should have axes labels on their data including units. The more we can pester people into doing that (I think) the better, if it's really that annoying it's only a warning, you can silence it. I can look into fixing that failing test/adjusting it and then we can think about what merging might look like. It might also be nice to make a small Example using a dummy test dataset to show how to do some of the more simple operations. |
Go for it! My schedule got a bit too full the next days.
I think these warnings just get very annoying. I think it by default should set it to pixels or arbitrary units. To avoid the warning.
Agreed! We should be able to make nice dataset to show the DPC features. |
…it can go through an appropriate deprecation cycle.
@magnunor I fixed the bug causing the tests to fail and adjusted some of the code. I think this is starting to look pretty good, the only thing I would like to look into is what other visualizations might be of interest. We could think about things like:
|
Very nice!
I agree that these would be very good. However, since these are additions, rather than API-breaking, we should wait with these for the next release. |
@magnunor sounds good. I'm going to review the changes again. If you have time can you go over my additions? Then we can merge. |
I'll try to get this done today, or most likely tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some small comments of things we could do eventually.
|
||
|
||
class BeamShift(Signal1D): | ||
"""Signal class for working with shift of the direct beam.""" | ||
|
||
_signal_type = "beam_shift" | ||
|
||
def make_linear_plane(self, mask=None): | ||
def get_linear_plane(self, mask=None, fit_corners=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently this doesn't work on 5 dimensions but we can wait on that for a later PR.
if fit_corners is not None: | ||
mask = bst._get_corner_mask(self.isig[0], corner_size=fit_corners) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be more efficient. Right now this requires that you calculate the entire shifts when really we only need to calculate the corners.
""" | ||
# Rotate the phase by -30 degrees in the color "wheel", to get better | ||
# visualization in the vertical and horizontal direction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I adjusted this but before the rotation was always rotation=30
Hello, I work quite a bit with this functionality, so I can take a gander at some parts tomorrow and the day after, at least! |
@@ -23,7 +23,7 @@ | |||
# In many instances the zero beam position will vary systematically with the scan position. | |||
# This can be corrected by fitting a linear plane to the zero beam position using the | |||
# :meth:`make_linear_plane` method. | |||
shifts.make_linear_plane() # Making a linear plane to remove the systematic shift | |||
shifts.get_linear_plane() # Making a linear plane to remove the systematic shift |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The functionality is changed here so that the plane is returned. So should AFAIK be shifts = shifts.get_linear_plane()
I looked into using old DPC signals with the new
which has the output:
In the past you would use the |
s_rgb.change_dtype("rgb16") | ||
return s_rgb | ||
|
||
def get_color_signal( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be a good idea to rename this function? As it can easily be confused with get_phase_signal
since it's also very colourful. Maybe something like get_magnitude_phase_signal
. Easier to search for too.
This is a good point: how to best handle the old files. I'm not sure how to best do this, as we would like to drop the
This is a very good point! This should also be useful if different masks are used, essentially that we only calculate this for the chunks which we really need.
Agreed, we should add a |
I think this is totally reasonable. We should keep the DPC class and signal type but just transpose the data and set the signal type to |
@magnunor If you don't have time to get to this today I might try to make things a bit more backwards compatible and then merge. |
Go for it! I can review it. |
To read files containing |
That sounds tempting. How would this work? Looking for the |
There should be enough metadata (see for example https://github.com/hyperspy/rosettasciio/blob/31bd677cc4c02c5787ae9b61250bc1431f352cba/rsciio/_hierarchical.py#L309 and https://github.com/hyperspy/rosettasciio/blob/31bd677cc4c02c5787ae9b61250bc1431f352cba/rsciio/utils/tools.py#L466) that is saved in the file to figure out when it needs to be converted and not interfere with other Note that keeping an empty class in pyxem will prevent other use of this signal type. |
This pull request implements the changes discussed in #1039
This to make the pyXem class structure a bit clearer, by changing the default plotting behavior in the
BeamShift
class:s.map
in one or two lines of code has been removedThis pull request drastically break the API, so this should be implemented in an "API-breaking" release. Also, due to changes in other pull requests, there will probably be some merge conflicts.
Checklist
diffraction2d.center_of_mass
dummy_data
Some points for discussion:
BeamShift.plot()
: currently, the plot function simply doesself.T.plot()
. Is this a good way of doing this?BeamShift
functions will only work with signals with 2 navigation dimensions. How to best deal with this?get_phase_signal
andphase_retrivial
, which returns very different phases:get_phase_signal
is the "direction" of the beam shift "vector", whilephase_retrival
retrives the phase.make_bivariate_histogram
(which is not a class method) should be moved to someutils
package?pixelated_stem_tools
should be cleaned up, with some of the DPC specific functionality being moved to a (new?) utils focusing on beam-shift and DPC.gaussian_blur
, as (in my experience) it is not used very often, and can easily be replaced by two lines of code.