Proposal for precise geometry parametrization of planar imaging detectors.
Cartesian coordinate system of setup is defined by three mutually orthogonal right-hand-indexed axes with origin in the interaction point (IP) of the photon beam with target:
as shown in the plot:
Each photon with sample collision happens in different place... IP is an abstract position of the crossing point of the "beam line" and "target", which both are not well defined... Is it really good definition? |
Detector coordinate system may have a translation and rotation with respect to the setup, which can be defined by the 3 vectors in the setup frame:
ey – unit vector along the detector frame y axis,
as shown in the plot:
Third unit vector ez – is assumed to be right-hand triplet component,
ez=[ex × ey]
.
Components of these three unit vectors form the rotation matrix
/ ex1 ey1
ez1
\
R
= | ij
ex2 ey2
ez2
|
\ ex3 ey3
ez3
/
where indexes "i" and "j" corresponds to the vector components in the setup and detector local coordinate frames, respectively. Within this definition 3-d pixel coordinate "c" in the detector frame can be transformed to the setup coordinate "C" using equation
Ci=Rij·cj + Pi
.
The list of parameters, which defines detector position and orientation in the setup (lab) frame consists of vector components:
P1 | P2 | P3 | ex1 | ex2 | ex3 | ey1 | ey2 | ey3 |
---|
assuming ez=[ex × ey]
, and |ex|=|ey
| =|ez|=
1.
Alternatively, directions of the three unit vectors ex, ey
,
and ez
of the detector frame can be defined in terms of three Euler angle rotations with respect to the setup (lab) frame:
P1 | P2 | P3 | alpha | beta | gamma |
---|
with classic relations between (ex,ey
,
ez
) and (alpha, beta, gamma) presentations.
Access to these parameters should should be provided at least two methods of the calibration store object:
(P1, P2, P3, ex1, ex2, ex3, ey1, ey2, ey3) = calib.get( type, detector_name )
calib.put(type, detector_name, (P1, P2, P3, ex1, ex2, ex3, ey1, ey2, ey3))
or similar methods for Euler angles.
In this note we assume that:
These assumptions are not necessary for most of algorithms. But, in many cases it may be convenient to use small angle approximation or ignore angular misalignment for image mapping between tiles and 2-d image array.
For any type of tile there should be a method returning pixel coordinates in this ideal geometry,
xarr, yarr, zarr = get_xyz_maps_um()
For example, Python interface for CSPAD2x1
from PyCSPadImage.PixCoords2x1 import cspad2x1_one ... xarr, yarr, zarr = cspad2x1_one.get_xyz_maps_um() |
returns x-, y-, and z-coordinate arrays of shape [185,388].
It is assumed that each tile is presented in DAQ or offline data by a consecutive block of memory. Uniform matrix-type geometry of pixel array is preferable, but other geometry can be handled. For example, for CSPAD 2x1 sensor pixel index in the tile memory block of size (185,388) can be evaluated as
i = column + row*388.
Detector data record consists of consecutive tile-blocks, in accordance with numeration adopted in DAQ. For effective memory management, some of the tile-blocks may be missing due to current detector configuration. Available configuration of the detector tile-blocks should be marked in a bit-mask word in position order (bit position from lower to higher is associated with the tile number in DAQ).
Optical measurements provide a list of coordinates for all sensor points:
Tile # |
---|
Point # | X[µm] | Y[µm] | Y[µm] |
---|
Quality check of optical measurement may include for each tile:
Detector pixels' geometry in 3-d can be unambiguously derived from
The tile location and orientation can be defined by the table of records (see example of file: geometry)
Parent name | Parent index | Object name | Object index | X0[µm] | Y0[µm] | Y0[µm] | Rotation Z [°] | Rotation Y [°] | Rotation X[°] | Tilt Z[°] | Tilt Y[°] | Tilt X[°] |
---|
where
Tile center coordinates are defined as an average over 4 corners.
Tilt angles are projected angles of the tile sides on relevant planes. Each angle is evaluated as an averaged angle for 2 sides.
Origin of the detector local frame is arbitrary. There are few preferable options for choosing coordinate frame origin:
Pixel coordinate reconstruction in the detector frame uses
Then all rotations and translations are defined as:
#file: pyimgalgos/src/GeometryObject.py def rotation(X, Y, C, S) : Xrot = X*C - Y*S Yrot = Y*C + X*S return Xrot, Yrot class GeometryObject : ... def transform_geo_coord_arrays(self, X, Y, Z) : ... # define Cx, Cy, Cz, Sx, Sy, Sz - cosines and sines of rotation + tilt angles ... X1, Y1 = rotation(X, Y, Cz, Sz) Z2, X2 = rotation(Z, X1, Cy, Sy) Y3, Z3 = rotation(Y1, Z2, Cx, Sx) Zt = Z3 + self.z0 Yt = Y3 + self.y0 Xt = X2 + self.x0 return Xt, Yt, Zt |
where the 3-d rotation matrix R is a product of three 2-d rotations around appropriate axes,
Pixel coordinates in the detector should be accessed by a method like
xarr, yarr, zarr = get_pixel_coords().
For example, Python interface for CSPAD
from pyimgalgos.GeometryAccess import GeometryAccess ... fname_geometry='<path>/geometry/0-end.data' geometry = GeometryAccess(fname_geometry) X,Y,Z = geometry.get_pixel_coords() |
Suggested method for imaging detector geometry description provides simple and unambiguous way of pixel coordinate parametrization. This method utilizes all available information from optical measurement and design of the detector and tiles. All geometry parameters are extracted without fitting technique and presented by natural intuitive way.