hyperspy / hyperspy

Multidimensional data analysis
https://hyperspy.org
GNU General Public License v3.0
518 stars 210 forks source link

Map function Add in ability to copy/modify axes #2909

Open CSSFrancis opened 2 years ago

CSSFrancis commented 2 years ago

The discussion from #2830 reminded me of something that I have been meaning to fix.

In many cases after using the map function the axes are changed/ adjusted and should have different scales, axes etc.

For example in pyxem when we take the azimuthal_integral2d the signal changes from a diffraction pattern to a polar signal this chunk of code is used to change the axes to the proper format.

# Dealing with axis changes
        if inplace:
            t_axis = self.axes_manager.signal_axes[0]
            k_axis = self.axes_manager.signal_axes[1]
            self.set_signal_type("polar_diffraction")
        else:
            transfer_navigation_axes(integration, self)
            integration.set_signal_type("polar_diffraction")
            t_axis = integration.axes_manager.signal_axes[0]
            k_axis = integration.axes_manager.signal_axes[1]
        t_axis.name = "Radians"
        if azimuth_range is None:
            t_axis.scale = np.pi * 2 / npt_azim
        else:
            t_axis.scale = (azimuth_range[1] - azimuth_range[0]) / npt
            t_axis.offset = azimuth_range[0]
        k_axis.name = "Radius"
        k_axis.scale = (radial_range[1] - radial_range[0]) / npt
        k_axis.units = unit
        k_axis.offset = radial_range[0]

I think that there are a couple of better ways to do this but the easiest would be to add a signal_axes parameter to the map function which automatically sets the units, offset, and name for some axes after mapping the signal.

ericpre commented 2 years ago

Indeed, that would be good to improve the situation but I suspect that adding signal_axes is not the right approach because it may the end up being quite complicated to be generic enough. I find that updating the axes separately after running map has the advantage of being explicit and easy to read. Maybe improving the syntax and the documentation may be good enough?

I didn't look at the full code of the example above, but I suspect that it should be possible to avoid the first if/else block. For the rest, I don't think that you can get away without it! Maybe something along the line of https://github.com/hyperspy/hyperspy/pull/2756 would help in general - even if in this specific example, it will not! ;)