Detector and detector modules - xcist/documentation GitHub Wiki

The detector is defined by a callback function. In principle, there can be multiple callback functions available, each with its own features and configuration variables. In practice, there is currently only one released callback function, which is specified by the following line in CatSim’s configuration file.

cfg.callback_detector = 'Detector_ThirdgenCurved';

This computes the entire detector structure, including the module definitions, module coordinates, cell coordinates, sample coordinates and weights. This routine uses the parameters discussed below.

Third generation/Curved CT detector

The detector is built as a set of planar detector modules, which can but do not have to represent actual (manufactured) detector modules. These modules are arranged side by side in an arc such that columns in the detector modules are parallel, and rows in the detector modules form a piecewise linear arc. The radius of the arc (in mm), from the nominal center of the source to the center of each detector module, is given by

cfg.sdd = Source-to-Detector Distance;

Only one row of modules is permitted (i.e. modules can be replicated laterally – in the row direction – but not longitudinally). The number of modules in the detector, i.e. replicates in the row direction, is specified by

cfg.n_modules = number of detector modules;

There will be typically only one module type, but many modules. However, it is possible to model a planar detector by specifying a single module. One disadvantage to this is that some of the projectors are multi-threaded. This is accomplished by distributing the projection task on a per-module basis. Therefore, the performance improvement of multi-threading would not be realized if a single detector module were specified.

The numbers of columns and rows per module are specified by

cfg.cols_per_mod = number of columns per module;
cfg.rows_per_mod = number of rows per module;

The total number of rows in the detector is given by
cfg.row_count = cfg.rows_per_mod;

The total number of columns in the detector (sum for all modules) is given by
cfg.col_count = number of detector columns;

If this is specified as a constant that is less than cfg.cols_per_mod*cfg.n_modules, then the size of the “edge” modules is reduced accordingly.

The total number of cells in the detector (sum for all modules) is given by
cfg.total_n_cells = cfg.col_count*cfg.row_count;

The detector column size and row size, or the u and v dimensions of a single detector cell (in mm) are specified by
cfg.col_size = detector pixel u dimension (mm);
cfg.row_size = detector pixel v dimension (mm);

The detector fill fraction is specified by
cfg.col_fillfraction = detector pixel fill fraction in u direction;
cfg.row_fillfraction = detector pixel fill fraction in v direction;

This models the fact that there is a small dead zone between detector columns and rows respectively. A fill fraction of 1.0 means that the detector has no dead space. A fill fraction of 0.0 means that the detector is completely inactive.

Note: In order to take full advantage of the focal spot and detector models, and correctly model spatial resolution, appropriate oversampling must be utilized. See section 23: Sampling.

The number of samples to use per detector cell in the column and row direction is specified by
cfg.col_oversample = detector pixel oversampling in u direction;
cfg.row_oversample = detector pixel oversampling in v direction;

The sample locations are distributed uniformly inside the active area of the detector. Some additional samples are placed at the edge of the neighboring detector cells to model x-ray crosstalk. X-ray crosstalk (not including optical crosstalk) is specified by
cfg.col_crosstalk = detector pixel crosstalk fraction in u direction;
cfg.row_crosstalk = detector pixel crosstalk fraction in v direction;

which is the fraction of the signal that is detected as cross-talk in neighboring detector columns/rows. For example 0.05 means that each column/row receives 5% of the x-rays from both neighboring columns/rows.

If a CatSim user defines his own detector_callback routine, some additional parameters may be required.

In the detector callback function, the detector is defined as a structure det containing the following fields: (see Detector definition figure below)


det.n_modules number of detector modules
det.modtypes vector of size [det.n_modules] specifying the module types; this is one-based in Matlab and will automatically be converted to zero-based when passing to C. So if all modules are of the same type, this should be an [det.n_modules] array of all ones.
det.modcoords [3 * det.n_modules] array of module centers (x,y,z) in mm.
det.uvecs [3 * det.n_modules] array of unit vectors defining a u-direction (x,y,z) for each module. The u-vector is typically perpendicular to the rotation axis.
det.vvecs [3 * det.n_modules] array of unit vectors defining a v-direction (x,y,z) for each module. The v-vector is typically parallel to the rotation axis.
det.total_n_cells total number of detector cells, i.e., the sum of the number of cells in all modules.
det.n_moddefs number of different module definitions; often this will be one, assuming all modules are of the same type.
det.n_cells [det.n_moddefs] array with the number of cells in each module type
det.cellcoords [2 * max(n_cells) * det.n_moddefs] array with the cell (u,v) coordinates for each module type. The cell coordinates are defined relative to the module center, along the u and v coordinates, in mm.
det.n_samples [det.n_moddefs] vector with the number of samples per cell.
det.samplecoords [2 x max(det.n_samples) * det.n_moddefs] array of sample centers for each module type. All cells in a module type have the same sampling pattern. The sample coordinates are defined relative to the cell centers, along the u and v coordinates, and in mm. The samples may include x-ray crosstalk samples in neighboring cells.
det.weights [max(det.n_samples) * det.n_moddefs] array of relative sample weights for each module type. The weights have to sum up to one!
det.activearea [det.n_moddefs] array of the cell active area for a given module type.
det.width [det.n_moddefs] array of module widths. This serves as bounding box for all cell samples.
det.height [det.n_moddefs] array of module heights. This serves as bounding box for all cell samples.


Detector definition

Pack-Module structure and Multi-Z-Module

Pack-Module structure and Multi-Z-Module are the new design of detector in Release 6.0. The detector is built as 2D arrays of modules, and a module is a 2D array of packs, a pack is a 2D array of cells, as shown in Figure 16, the detector is defined with 4 by 3 modules, the module is defined with 2 by 2 packs and the pack is defined with 3 by 3 cells.

  • Kerf size
    For each cell, the pitch size and kerf size are defined along both column and row direction. The kerf size is the width of the kerf between two cells, which is filled with reflector material, so that the active area (fill fraction) is defined.

  • Pack gap and module gap
    Pack gap/module gap are the gaps between two packs or two modules along u/v vector. This module allows defining different pack/module gap values for all the gaps.

  • Module rotation around u vector and position offset along w vector

All the modules can have a rotation around u vector, and a position offset along w vector (w vector is the orthogonal vector of u and v vector). With that we can define the “chiclet” detector.


Figure 16: Detector defined with Pack-Module structure


The cfg variables are:

% DEFINE PACK
cfg.col_size = 1.0;		                    % Detector column size or x-pitch (mm)
cfg.row_size = 1.0;			            % Detector row size or z-pitch (mm)
cfg.col_cast = 0.1;			            % Reflector thickness at column direction (mm)
cfg.row_cast = 0.1;			            % Reflector thickness at raw direction (mm)
cfg.cols_per_pack = 8;			            % Number of detector columns per pack
cfg.rows_per_pack = 16;			            % Number of detector rows per pack

% DEFINE MODULE
cfg.col_packs_per_mod = 2;		            % Number of column packs per module
cfg.row_packs_per_mod = 2;		            % Number of row packs per module
cfg.col_pack_gap = 0;			            % Inter-pack gap at column direction (mm)
cfg.row_pack_gap = 0.12;		            % Inter-pack gap at row direction (mm) 

% DEFINE DETECTOR
cfg.mods_per_det_x = 52;                            % Number of modules per detector along X axis
cfg.mods_per_det_z = 8;			            % Number of modules per detector along Z axis
cfg.mod_gap_u = 0.;			            % Inter-module gap at column direction (mm)
cfg.mod_gap_v = 0.1;			            % Inter-module gap at column direction (mm)
cfg.col_offset = -4.25;			            % In-plane detector offset (in mm)
cfg.mod_offset_w = zeros(1,cfg.mods_per_det_z);	    % module position offset along w vector
cfg.mod_rotation_u = ones(1,cfg.mods_per_det_z)*0;  % module rotation around u vector
cfg.mod_row_offset = zeros(1,cfg.mods_per_det_x);   % module position offset along row direction


Back to Main menu

⚠️ **GitHub.com Fallback** ⚠️