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 Micro-Channel Plate simulation involves many features. For the moment, just its non-linear 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 S_p^\text{proj} that is a fraction of the maximum transfer momentum projected on the xy plane, i.e.:

S_p^\text{proj} = \frac{|k_\text{in}| \sin(\theta_\text{max})}{\frac{N_p}{2}}

where |k_\text{in}| is the radiation wavenumber, \theta_\text{max} is the maximum scattering angle and N_p 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 S_p^\text{mom} that corresponds to a constant unit of the transfer momentum, that is:

S_p^\text{mom} = \frac{2 |k_\text{in}| \sin \left( \frac{\theta_\text{max}}{2} \right)}{\frac{N_p}{2}}

Another one is, instead, the case in which the pixel size S_p^\text{ang} has a constant unit of scattering angle, which means:

S_p^\text{ang} = \frac{\theta_\text{max}}{\frac{N_p}{2}}

The last case is when the pixel size S_p^\text{det} of the pattern directly corresponds to a pixel of the real detector, that is:

S_p^\text{ang} = \frac{\tan(\theta_\text{max})}{\frac{N_p}{2}}

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:

_images/coordinates.png

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 H_a(x,y) at coordinates x,y is computed through the Lamber-Beer law (with the radiation propagating along the z direction):

H_a(x,y) = H_i \left [ 1 - e^{2 k_0 \int dz \beta(x,y,z)} \right ]

where H_i is the incident power density, assumed to be uniform on the x,y plane, and \beta(x,y,z) is the absorption coefficient of the sample material. Then, the total absorbed power W_a is:

W_a = \iint dx dy H_a(x,y) = H_i  \iint dx dy \left [ 1 - e^{2 k_0 \int dz \beta(x,y,z)} \right ]

As stated before, the Scatman assumes a completely elasitc scattering, which implies that the total scattered power W_s is equal to the total absorbed one W_a. Moreover, being the power directly proportional to the amount of photons, the equation can be rewritten as:

N_s = N_a = \rho_i  \iint dx dy \left [ 1 - e^{2 k_0 \int dz \beta(x,y,z)} \right ]

where N_s and N_a is the amount of scattered and absorbed photons, respectively, and \rho_i is the incoming photon density (i.e. photons per area unit).

The final assumption made by the current implementation is that the N_s 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 \rho has to be computed, and depends on the experimental parameters. Here, we simulate an experiment with radiation wavelength \lambda=40\text{nm}=31\text{eV} and incoming power density H = 3 \cdot 10^{14} \frac{\text{W}}{\text{cm}^2} =  3 \cdot 10^{18} \frac{\text{W}}{\text{m}^2}. The duration of the laser shot is t = 80\text{fs} = 8\cdot 10^{-14}\text{s}. The photon density can be calculated with the following formula:

\rho = \frac{H \cdot t}{q \cdot E} = 4.84\cdot 10^{22} \frac{\text{photons}}{\text{m}^2} = 4.84\cdot 10^{4} \frac{\text{photons}}{\text{nm}^2}

where q=1.6\cdot 10^{-19} \text{C} 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)
_images/example_ideal.png

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 I_\text{ideal} the input intensity value of the scattered field, the MCP output response I_\text{MCP} can be modeled with a function R such that I_\text{MCP}=R(I_\text{ideal}).

In the current implementation, the response function is defined as it follows:

R(x)=
\begin{cases}
  G \cdot x^E, & \text{if}\ G \cdot x^E < L \cdot S \\
  S \cdot \left [ (1-L) \cdot (1 - e^{\frac{1}{L-1} \cdot (\frac{G \cdot x^E}{S} - L)}) + L \right ] , & \text{otherwise}
\end{cases}

where:

  • G refers to what I called gain
  • E refers to what I called exponent, usually < 1 (the MCP response is usually sub-linear)
  • S is the saturation value of the MCP output
  • L is the (sub) linearity level, i.e. the fraction of the saturation value up to which the response follows the power-law 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 sub-linear 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:

_images/MCP_response.png

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 wide-angle 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 wide-angle 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, non-linear 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 R to the ideal pattern I_\text{ideal}, that is I_\text{MCP}= R(I_\text{ideal}).

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 sub-linear.
  • exponent – exponent to simulate the non-linear 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 wide-angle scattering image for each shape provided as input.