Tutorial 2: Manipulating grids
Now that you are already familiar with the basic functionality of SpmGrids, let's dive deeper. Here we want to learn how to manipulate data.
Adding channels
Let's manualla add a channel "Z rel" that is the relative Z position in the grid, i.e, the Z position with respect to the parameter "Scan Start". The new channel should have the unit of "m".
julia> using SpmGrids
julia> grid = load_grid("Z_spectroscopy.3ds")
SpmGrid("Z_spectroscopy.3ds", sweep: "Z", 16 channels, 256 points, 32x32 pixels)
julia> z = get_channel(grid, "Z");
julia> sweep_start = get_parameter(grid, "Sweep Start");
julia> z_rel = z .- sweep_start;
julia> add_channel!(grid, "Z rel", "m", z_rel)
Quite easy, isn't it?
However, notice that we didn't add the backward channel "Z rel [bwd]".
julia> has_channel(grid, "Z")
true
julia> has_channel(grid, bwd"Z")
true
julia> has_channel(grid, "Z rel")
true
julia> has_channel(grid, bwd"Z rel")
false
And we can do it manually, just as before. But a better way is the following. Again, we add a "Z rel" channel (in fact it will be overwritten). But this time we use the a function as the first argument in add_channel!
. It takes two input parameters x
and y
and computes x .- y
(i.e. the broadcasted subtraction).
The new channel name will be "Z rel"
, it's unit "m"
, and the input parameters for the function are "Z"
and "Sweep Start"
.
julia> add_channel!( (x,y) -> x .- y, grid, "Z rel", "m", "Z", "Sweep Start" )
We could also explicitely specify that "Z"
is a channel and "Sweep Start"
is a parameter by using ch"Z"
and par"Sweep Start"
.
But the more important thing is that the function automatically handled the backward channels:
julia> has_channel(grid, "Z rel")
true
julia> has_channel(grid, bwd"Z rel")
true
One thing to keep in mind is that the channels can contain NaN
values. This can happen when the grid was stopped prematurely or a sweep within a grid is stopped.
Thus to calculate a "Z rel" channel relative to the minimum value of all "Z" values, you need to do the following:
julia> zmin = minimum( SpmGrids.skipnan(get_channel(grid, "Z")) )
-5.1229296360588705e-9
julia> add_channel!(x -> x .- zmin, grid, "Z rel", "m", "Z")
julia> z_rel = get_channel(grid, "Z rel");
julia> z_rel[1,1,20]
5.960782978320367e-10
The SpmGrids.skipnan
function is a convenience function that skips all NaN
values, it is just a shorthand for : filter(!isnan, x)
.
We could now even set the sweep_signal
of the grid to the new "Z rel"
channel:
julia> grid.sweep_signal = "Z rel"
"Z rel"
But be careful to know what you are doing when changing these values. The sweep signal has special requirements, for instance, its values should be unique.
Adding parameters
Similarly as adding channels, we can add parameters to our grid. For instance a parameter "Sweep Span":
julia> add_parameter!( (x,y) -> abs.(y .- x), grid, "Sweep Span", "m", "Sweep Start", "Sweep End" )
julia> p = get_parameter(grid, "Sweep Span");
julia> has_parameter(grid, "Sweep Span")
true
julia> size(p)
(32, 32)
julia> # now all "Z rel" values are ≥ 0 all(SpmGrids.skipnan(p) .≥ 0)
true
Also, all these new channels and parameters are available in the interactive widget. You can load it with:
interactive_display(grid, colormap=:bluegreenyellow)
More information
A more detailed description can be found in the Reference.