What are Dimensions?¶
If a Spec tells you the parameters of a scan, Dimensions gives you the positions that will let you actually exectute the scan. A list of Dimensions is interpreted as nested from slowest moving to fastest moving, so each faster Dimension will iterate once per position of the slower Dimension. When fly-scanning they key will traverse lower-position-upper on the fastest Dimension for each point in the scan.
An Example¶
>>> from scanspec.specs import Line
>>> spec = Line("y", 4, 5, 6) * Line("x", 1, 2, 3)
>>> dims = spec.create_dimensions()
>>> len(dims)
2
>>> len(dims[0])
6
>>> len(dims[1])
3
>>> dims[0].positions
{'y': array([4. , 4.2, 4.4, 4.6, 4.8, 5. ])}
>>> dims[1].positions
{'x': array([1. , 1.5, 2. ])}
So the Product
of two Lines
creates a list of 2 Dimensions, the first
having the same size as the outer line, and the second having the same size as
the inner. Executing the scan will iterate the inner dimension 6 times, once for
each point in the outer dimension, 18 positions in all.
Why a list of Dimensions?¶
A list of Dimensions are created to give the most compact representation of the scan. Imagine a 100x2000x2000 point scan, which creates a list of 3 Dimensions. Considering just the position arrays, they would take 100 + 2000 + 2000 float64 = 32.8kB RAM in our list form. If we squashed the list into a single Dimension 100 * 2000 * 2000 float64 = 3.2GB of RAM. The scan itself is likely to be executed over a long period of time, so it makes sense to save on the memory and calculate the squashed positions as they are needed.
What about Regions?¶
Regions will stop the regularity of the nested Dimensions, so will cause them to
be squashed into a single Dimension. Taking our example above, if we Mask
the
grid with a Circle
, then the Line
in x
won’t have 3 positions in each
iteration, the number of positions is dependent on y
. This means that a
Mask
will squash any Specs together referred to by its Regions.
How do ScanSpec Dimensions relate to HDF5 Dimensions?¶
A Spec by itself does not specify how the scan points should be written to disk.
The simplest strategy is to simply write a stack of images, along with the
setpoint positions specified in the Dimensions, and let the reader of the data
pick out the required frames from the positions. However, the list of Dimensions
contain all the information required to reshape a stack of HDF5 frames into the
dimensionality of the scan using a VDS. This holds until we turn snake on, at
which point it destroys the performance of the VDS. For this reason, it is
advisable to Squash
any snaking Specs with the first non-snaking axis above it
so that the Dimension will not be snaking. See Why Squash (and Mask) can change the Path for
some details on this.