R3BROOT
R3B analysis software
|
Digitizing is the process of converting the "raw" Monte Carlo energy depositions to experimental look-alike hits.
The Digitizing task R3BNeulandDigitizer
handles the Input and Output of data. The task takes the R3BNeulandPoints
from the Simulation, runs them through a DigitizingEngine
and fills R3BNeulandHits
. It also requires the configuration storage NeulandGeoPar
to convert position coordinates.
It's encouraged to create an executable file to use this digitization task. However, users are still able to use the task in ROOT Macro file, with much less configurability though.
For the ROOT Macro file, the input parameter of the digitization task can only be one of the two options: neulandTamex
and neulandTacquila
.
Example:
Much more options are available when the task is used in a C++ executable. Such an example can be found in the source file neulandAna.cxx implemented with some program options. To see what kind of options can be used with this executable, go to the folder build/bin
and run the executable with:
Before running any executable, please make sure the configuration file build/config.sh
has been sourced.
The digitization task must be set with a digitization engine, which specifies the type of the scintillator and the digitization channel.
An engine can be created with
which chooses the Neuland scintillator and the Tamex channel for the digitization engine. Then, the task can be setup with this engine by
The Tamex channel has an option to setup its parameters through an object in the type R3B::Digitizing::Neuland::Tamex::Params
:
Following table shows all the parameters that can be modified for the Tamex channel:
Name | Type | Default value | Meaning |
---|---|---|---|
fPMTThresh | double | 1. [MeV] | Value of the PMT threshold |
fSaturationCoefficient | double | 0.012 | Saturation coefficient of PMTs |
fExperimentalDataIsCorrectedForSaturation | bool | true | If true, the PMT saturation effect is enabled |
fTimeRes | double | 0.15 [ns] | Time resolution of channel outputs |
fEResRel | double | 0.05 [MeV] | Energy resolution of channel outputs |
fEnergyGain | double | 15.0 | Value of the PMT gain (used for the width calculation) |
fPedestal | double | 14.0 | Pedestal value (used for the width calculation) |
fTimeMax | double | 1000. [ns] | Maximum time cutoff |
fTimeMin | double | 1. [ns] | Minimum time cutoff |
fPileUpTimeWindow | double | 1000. [ns] | FQT Peaks pileup time window |
fPileUpDistance | double | 200. [ns] | FQT Peaks pileup time distance |
fQdcMin | double | 0.67 [MeV] | Minimum energy cutoff |
On the other hand, users are also allowed to set the parameters of each channel according to a parameter container from the calibration process:
In the example above, the object with the name "NeulandHitPar" should have the type R3BNeulandHitPar
in the root file "params_sync.root". Be aware that the runID in the parameter root file must be the same runID in the simulation input file.
A DigitizingEngine
object handles the actual data processing, which requires another two objects as the input parameters for its instantiation: UseChannel
and UsePaddle
. As suggested by their names, these two objects behave like factories, which are used by DigitizingEngine
to generate Channel
and Paddle
objects.
To minimize the coupling between different algorithm components, users should use the base class of DigitizingEngine
(DigitizingEngineInterface
) containing all necessary essential interfaces. The following diagram depicts the correct usage of this class:
An example of the digitizer class:
Here instead of letting the class member engine_
directly have the type MyDigitizingEngine
, let its type be the base class DigitizingEngineInterface
. Such a design pattern has two major advantages:
Dependency injection
The class MyDigitizer
is no longer bundled together with MyDigitizingEngine
. The dynamic type of its member variable Engine_
can be any type with various implementations.
Compilation wall
Implementation details are hidden from MyDigitizer
. Therefore, any changes made in MyDigitizingEngine
will not cause the recompilation of the class MyDigitizer
.
As a class template, DigitizingEngine
has the following structure:
Therefore, an instantiation directly with this constructor is a little bit complicated:
However there is a helper function template called CreateEngine
that can be used to instantiate this class more easily:
There is a third optional parameter of the constructor of the class template DigitizingEngine
called InitFunc
. It takes a std::function
or a lambda function as an input, which will be invoked inside the member function DigitizingEngine::Init()
. The existence of such a parameter introduces another dependency injection of any kind of initialization function needed for the paddle or channel classes, such as the parameter initialization before the event loop. One example could be:
The UsePaddle
and UseChannel
class template are two input parameter types of the class template DigitizingEngine
. They specify the paddle and channel class (containing all implementations of the real physical paddle and channel) and the input parameters of the corresponding class constructors.
For example, if the paddle and channel class are defined in the following way:
then UsePaddle
and UseChannel
should be defined as:
Remember that only additional input parameters should be given in the curly brackets. The parameters, such as channelSide
or paddleId
, already required in the base class Digitizing::Channel
and Digitizing::Paddle
should not be given as input parameters to UsePaddle
and UseChannel
.
The input and the output of the paddle and channel class are represented by four different I/O structures (in the namespace of Digitizing
).
Struct name | Meaning | Member variables |
---|---|---|
PaddleSignal | Output of paddle class passed to the output of digitizingEngine (reconstructed hit level data) | double energy (in MeV ) double time (in ns ) double position (in cm ) const Channel::Signal& leftChannel const Channel::Signal& rightChannel |
ChannelSignal | Output of channel class passed to the paddle class as an input | double qdc (in MeV ) double tdc (in ns )double qdcUnSat (unsaturated QDC value) ChannelSide side (left or right) |
PaddleHit | Input of the paddle class from the input of digitizingEngine | double time (in ns ) double LightDep (in MeV ) double DistToPaddleCenter (in cm ) |
ChannelHit | Input of the channel from the input of the paddle class | double time (in ns ) double light (in MeV ) |
The paddle class should include all algorithms needed to simulate the real process in the paddle shaped scintillators, such as the light attenuation and reconstruction of the energy deposition from the signals of two channels on either end. All paddle classes, used by UsePaddle
, have to be child classes of the Digitizing::Paddle
base class. A simple example of such a paddle class can be found in the class DigitizingPaddleMock.
There are two components that must be defined in the derived paddle classes:
For these two requirements, there are several pure virtual functions from the class Digitizing::Paddle
that must be overridden in the child classes:
This function is used to calculate the hits of both channels from a paddle hit. The signature is defined as follows:
Any real physical processes related to the scintillators, such as light attenuation, could be introduced in this function.
This function is used to calculate the time of the reconstructed paddle signal from the two channel signals. Its signature is defined as follows:
Here the sides of the first and second channel signals don't matter as long as two channel signals come from different sides. The output of this function is the double
type.
This function is used to calculate the energy of the paddle signal from two channel signals. Its signature is defined as:
with the input parameter as channel signals coming from different sides.
This is used to compute the position of the paddle signal with the following signature:
Since there is a positive direction the position, the first input parameter must be the channel signal coming from the right (top) side and the second parameter must be the one coming from the left (bottom) side.
The constructor of the derived paddle class must have the paddle ID as the first parameter.
Channel class is responsible for the simulation of physical processes in the digitization channels, such as the pileup effect, PMT saturation or low energy filtering. The input and output of the channel classes are directly connected to the corresponding paddle class. Just as for the paddle class, every channel class used by UseChannel
must be derived from the base class of Digitizing::Channel
, which has three pure virtual functions that must be overridden (see DigitizingChannelMock for a simple example.):
This is the input function of the channel class with the parameter to be of the type Channel::Hit
and the signature as follows:
It's called every time an input hit is fed into the digitizingEngine, without any threshold. The input parameter is the return value of the paddle member function ComputeTime
. In almost all cases, the derived channel class should have a private member variable to store useful input hits for later data processing (such as applying a threshold or pileup effects).
This function calculates the output from the channel class (Channel::Signals
) to the paddle class. Its function signature is defined as follows:
The return value should be calculated from the hit collections obtained by the input member function AddHit
. It will then be fed into the paddle object as an input parameter of multiple paddle member functions.
The constructor of the derived channel class must have the channel side as the first input parameter.