# Reference frames¶

## Sample-detector geometry¶

Fig. 1 and Fig. 2 show EBSD reference frames used in kikuchipy, all of which are right handed. They are based on definitions presented in [Britton2016] and the accompanying supplementary material.

## The EBSD detector¶

All relevant parameters for the sample-detector geometry are stored in an
`EBSDDetector`

object:

```
>>> from kikuchipy.detectors import EBSDDetector
>>> det = EBSDDetector(
... shape=(60, 60),
... pc=[0.421, 0.779, 0.505],
... convention="tsl",
... pixel_size=70, # microns
... binning=8,
... tilt=0,
... sample_tilt=70,
... )
>>> det
EBSDDetector (60, 60), px_size 70 um, binning 8, tilt 0, pc
(0.421, 0.221, 0.505)
>>> det.pc_tsl()
array([[0.421, 0.779, 0.505]])
```

The projection/pattern center (PC) is stored internally in the Bruker convention:

PCx is measured from the left border of the detector in fractions of detector width.

PCy is measured from the top border of the detector in fractions of detector height.

PCz is the distance from the detector scintillator to the sample divided by pattern height.

Above, the PC was passed in the EDAX TSL convention. Passing the PC in the
Bruker, Oxford, or EMsoft v4 or v5 convention is also supported. Likewise, the
PC can be returned in all conventions via
`pc_emsoft()`

and similar.
Conversions between conventions are implemented as described in
[JPDeGraef19]. The unbinned pixel size \(\delta\), binning
factor \(b\) and number of pixel rows \(s_y\) and columns \(s_x\)
are needed to convert a PC between the EMsoft and Bruker conventions:

EDAX TSL or Oxford to Bruker

EMsoft to Bruker, with \(v = -1\) for EMsoft v5 and \(+1\) for v4

The detector can be plotted to show whether the average PC is placed as
expected using `plot()`

(see
its docstring for a complete explanation of its parameters):

```
>>> det.plot()
```

This will produce a figure similar to the left panel in
Fig. 2, without the pattern, arrows and colored
labels. Passing a numpy array in the `pattern`

parameter places a pattern on
the detector.

Multiple PCs with a 1D or 2D navigation shape can be passed to the `pc`

parameter upon initialization, or can be set directly. This gives the detector
a navigation shape (not to be confused with the detector shape) and a navigation
dimension (maximum of two):

```
>>> det.pc = np.ones((3, 4, 3)) * [0.421, 0.779, 0.505]
>>> det.navigation_shape
(3, 4)
>>> det.navigation_dimension
2
>>> det.pc = det.pc[0, 0]
>>> det.navigation_shape
(1,)
```

Note

The offset and scale of HyperSpy’s `axes_manager`

is fixed for a signal,
meaning that we cannot let the PC vary with scan position if we want to
calibrate the EBSD detector via the `axes_manager`

. The need for a varying
PC was the main motivation behind the `EBSDDetector`

class.

The right panel in Fig. 2 shows the detector plotted
in the gnomonic projection using
`plot()`

. We assign 2D
gnomonic coordinates (\(x_g\), \(y_g\)) in a gnomonic projection plane
parallel to the detector screen to a 3D point (\(x_d\), \(y_d\),
\(z_d\)) in the detector frame as

The detector bounds and pixel scale in this projection, per navigation point, are stored with the detector:

```
>>> det.bounds # In pixels
array([ 0, 59, 0, 59])
>>> det.gnomonic_bounds
array([[-0.83366337, 1.14653465, -1.54257426, 0.43762376]])
>>> det.x_range
array([[-0.83366337, 1.14653465]])
>>> det.r_max # Largest radial distance to PC
array([[1.92199819]])
```