The Detectors¶
The scatman.Detectors
submodule contains a set of objects (at the moment 3) that aim to simulate the behavior of different kinds of CDI detectors.
All detectors derive from an abstract base class scatman.Detectors.Detector
. Being an abstract class, it cannot be used directly, i.e. it is not possible to instantiate an object of that type:
>>> import scatman
>>> MyDetector = scatman.Detectors.Detector()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: scatman.Detectors.Detector: No constructor defined!
For the moment, the following detectors are implemented:
MSFT:  It is actually not a real detector. It just provides the diffraction pattern as it is computed via the MSFT. 

Ideal:  The Ideal detector is the one that perfectly detects each photon arriving on it. It basically adds just the photon statistics (Poisson) to the MSFT result. 
MCP:  The MicroChannel Plate simulation involves many features. For the moment, just its nonlinear response function is included in the simulation. Things like the 8 degrees hole will be added in future. 
Detector Coordinates¶
The output of the MSFT gives the result for an ideal curved detector, i.e. a detector where each idealized pixel has the same cross section and the same distance from the interaction zone between the sample and the beam.
It is often necessary to translate the pixel position in the diffraction pattern, basically its x and y coordinates, into a physical quantity of interest. Usually, common physical quantities are the transfer momentum and the scattering angle. So, it is often desiderable that the single pixel size is a constant amount of transfer momentum or scattering angle.
However, the raw MSFT result provides a scattering image whose pixels are equally spaced on the plane orthogonal to the beam propagation direction. In practice, this means that each pixel has a constant size that is a fraction of the maximum transfer momentum projected on the xy plane, i.e.:
where is the radiation wavenumber, is the maximum scattering angle and is the linear amount of pixels of the detector.
It is however possible to perform a change of coordinates and obtain different representations. It’s worth noting that this operation is done by interpolating the raw MSFT data, and the result must be thus considered just an approximation of the correct result.
An useful coordinates system is the one where each pixel has a size that corresponds to a constant unit of the transfer momentum, that is:
Another one is, instead, the case in which the pixel size has a constant unit of scattering angle, which means:
The last case is when the pixel size of the pattern directly corresponds to a pixel of the real detector, that is:
The Scatman is capable of providing these different representations of the diffraction pattern, by setting a proper value for the parameter coordinates
when a detector is defined. Its value can be:
'projection'
: keep the natural MSFT coordinates system. No interpolation is performed'momentum'
: Interpolate the MSFT result, such that the pixel size is a constant fraction of the transfer momentum.'angle'
: Interpolate the MSFT result, such that the pixel size is a constant fraction of the scattering angle.'detector'
: Interpolate the MSFT result, such that the pixel size of the output corresponds to the pixel size of a real detector. In this case, the intensity of the scattering is scaled too, to match what is acquired by a real detector, where the cross section of the pixels varies as function of the distance from the detector center.
The following scheme summarizes the three options for the choice of the coordinates:
Modelling the photons statistics¶
The amount of scattered photons depends on the radiation absorbed by the sample. In particular, here we assume that the amount of absorbed radiation is equal to the scattered one. The distribution if the power density absorbed by the sample at coordinates is computed through the LamberBeer law (with the radiation propagating along the direction):
where is the incident power density, assumed to be uniform on the plane, and is the absorption coefficient of the sample material. Then, the total absorbed power is:
As stated before, the Scatman assumes a completely elasitc scattering, which implies that the total scattered power is equal to the total absorbed one . Moreover, being the power directly proportional to the amount of photons, the equation can be rewritten as:
where and is the amount of scattered and absorbed photons, respectively, and is the incoming photon density (i.e. photons per area unit).
The final assumption made by the current implementation is that the photons are all scattered towards the detector.
The following example deals with the simulation of a realistic diffraction pattern, i.e. including photons statistics, through the use of the scatman.Detectors.Ideal
detector.
To simulate photons statistics, the photon density has to be computed, and depends on the experimental parameters. Here, we simulate an experiment with radiation wavelength and incoming power density . The duration of the laser shot is .
The photon density can be calculated with the following formula:
where is the elementary charge.
The following code is a simulation of a spherical sample at these experimental conditions, with a detector covering up to 30 degrees scattering angle.
import scatman
scatman.set_experiment(wavelength=40., angle=30, resolution=512, photon_density=4.84e4);
mydetector = scatman.Detectors.Ideal()
myshape = scatman.Shapes.SphericalHarmonics(a=400, coefficients=[[0,0,1]], delta = 0.01, beta=0.02)
mypattern = mydetector.acquire(myshape)
Simulation of the MCP response¶
Modelling the MCP response function (i.e. finding out which is the MCP output at a given input) is all but trivial. given the input intensity value of the scattered field, the MCP output response can be modeled with a function such that .
In the current implementation, the response function is defined as it follows:
where:
 refers to what I called
gain
 refers to what I called
exponent
, usually (the MCP response is usually sublinear) is the
saturation
value of the MCP output is the (sub)
linearity
level, i.e. the fraction of the saturation value up to which the response follows the powerlaw model
All these parameters can be set when defining the scatman.Detectors.MCP()
.
Despite this function looks quite messy, it is just a power law that at some point becomes an exponential that goes to the saturation level. The complicated expression is due to the fact that, at the point where there is the transition between the sublinear behavior and the exponential one, the continuity of both the function and its first derivative are imposed.
To get a better idea, the following plot depicts the meaning of the parameters in a graphical way:
List of Detectors¶

class
scatman.Detectors.
MSFT
(self: scatman.Detectors.MSFT, coordinates: str = 'projection') → None¶ Bases:
scatman.Detectors.Detector
The MSFT detector is a sort of “virtual” detector, in the sense that it directly provides the MSFT numerical result, without adding any kind of additional feature, poisson noise included.
Parameters: coordinates – ( ‘projection’, ‘momentum’, ‘angle’ or ‘detector’) set the coordinates of the pattern. 
acquire
(self: scatman.Detectors.Detector, shape: Union[scatman.Shapes.Shape, List[scatman.Shapes.Shape]], field: bool = False) → Union[scatman.Pattern, List[scatman.Pattern]]¶ Simulate the experiment on a given shape or list of shapes.
The function performs the MSFT on the shapes, applying the properties of the detector.
Parameters:  shape – the input sample on which the MSFT is performed. Can be a single shape, or a list of shapes.
 field – If true, the complex scattered wavefield is also saved, and can be accessed by calling the
get_field()
method of the returned Pattern objects.
Returns: The diffraction pattern, or a list of diffraction patterns, corresponding to the simulated wideangle scattering image for each shape provided as input.


class
scatman.Detectors.
Ideal
(self: scatman.Detectors.Ideal, mask_radius: int = 0, coordinates: str = 'projection') → None¶ Bases:
scatman.Detectors.Detector
The Ideal detector is a model for a perfect detector. It is a detector with no artifacts, a perfect linear response and a pixel color depth equivalent to the precision of the
float
type (32 or 64 bits).Parameters:  mask_radius – radius (in pixels) of the beam stopper/hole at the center of the detector
 coordinates – ( ‘projection’, ‘momentum’, ‘angle’ or ‘detector’) set the coordinates of the pattern.

acquire
(self: scatman.Detectors.Detector, shape: Union[scatman.Shapes.Shape, List[scatman.Shapes.Shape]], field: bool = False) → Union[scatman.Pattern, List[scatman.Pattern]]¶ Simulate the experiment on a given shape or list of shapes.
The function performs the MSFT on the shapes, applying the properties of the detector.
Parameters:  shape – the input sample on which the MSFT is performed. Can be a single shape, or a list of shapes.
 field – If true, the complex scattered wavefield is also saved, and can be accessed by calling the
get_field()
method of the returned Pattern objects.
Returns: The diffraction pattern, or a list of diffraction patterns, corresponding to the simulated wideangle scattering image for each shape provided as input.

class
scatman.Detectors.
MCP
(self: scatman.Detectors.MCP, mask_radius: int = 0, gain: float = 1.0, saturation: float = 30000, linearity: float = 0.7, exponent: float = 0.4, offset: float = 0, coordinates: str = 'projection') → None¶ Bases:
scatman.Detectors.Detector
Model for a Micro Channel Plate detector. This detector provides as output a diffraction pattern affected by the MCP artifacts, like background noise, signal offset, nonlinear response and saturation. The relevant parameters for the features simulation are provided as arguments for its construction. The MCP features are applied to the diffraction pattern after having performed the MSFT, by applying function to the ideal pattern , that is .
For more info see here.
Warning
This class is still experimental. The following description of the arguments was done months after its implementation, and it is very likely that there are some mistakes. Please, use it carefully and don’t pretend meaningful results from it. Work on this class is still ongoing.
Parameters:  mask_radius – radius (in pixels) of the beam stopper/hole at the center of the detector
 gain – gain of the MCP.
 saturation – saturation value of the MCP.
 linearity – fraction of the saturation value up to which the MCP response is sublinear.
 exponent – exponent to simulate the nonlinear behavior.
 offset – offset value of the MCP output.
 coordinates – ( ‘projection’, ‘momentum’, ‘angle’ or ‘detector’) set the coordinates of the pattern.

acquire
(self: scatman.Detectors.Detector, shape: Union[scatman.Shapes.Shape, List[scatman.Shapes.Shape]], field: bool = False) → Union[scatman.Pattern, List[scatman.Pattern]]¶ Simulate the experiment on a given shape or list of shapes.
The function performs the MSFT on the shapes, applying the properties of the detector.
Parameters:  shape – the input sample on which the MSFT is performed. Can be a single shape, or a list of shapes.
 field – If true, the complex scattered wavefield is also saved, and can be accessed by calling the
get_field()
method of the returned Pattern objects.
Returns: The diffraction pattern, or a list of diffraction patterns, corresponding to the simulated wideangle scattering image for each shape provided as input.