SimSiPM
Library for SiPM simulation
Install / Use
/learn @EdoPro98/SimSiPMREADME
SimSiPM
Authors
SimSiPM has been developed by Edoardo Proserpio under the supervision of professor Romualdo Santoro at University of Insubria Como - Italy.
SimSiPM is distrubuted as an Open Source project and if you plan to use it please acknowledge us as authors or cite us in your paper.
Table of contents
<a name="introduction"></a>Introduction
SimSiPM is a simple and easy to use C++ library providing a set of object-oriented tools with all the functionality needed to describe and simulate Silicon PhotonMultipliers (SiPM) sensors. The main goal of SimSiPM is to include the response of SiPM sensors, along with noise and saturation effects, in the description of a generic detector in order to have a more detailed simulation. It can also be used to perform optimization studies considering different SiPMs models allowing to choose the most suitable product available on the market.
SimSiPM code mostly follows FCCSW rules and guidelines concerning C++. SimSiPM has been developed especially for high-energy physics applications and particle physics experiments, however its flexibility allows to simulate any kind of experiments involving SiPM devices.
SimSiPM does not have any major external dependency making it the perfect candidate to be used in an already existing environment (Geant4 or DD4HEP) or as "stand-alone".
<p align="center"><img src="images/signals.svg" width=500></p><a name="features"></a>Features
- Easy to use:
- Straight forward installation without external dependencies
- Easy to use Object Oriented paradigm
- Python implementation via Pybind11
- Description of SiPM sensors:
- Driven by parameters that can be obtained from the datasheet or laboratory measurements
- High level of customization allowing to describe a wide range of use cases
- Does not include tedious electronic circuit simulations
- High performance:
- Very fast signal generation
- Reliable description of SiPM signals and related quantities over all the dynamic range
- Low memory footprint (if you do not intend to save all waveforms!)
<a name="installation"></a>Installation
SimSiPM is fully functional without any external dependencies other than CMake.
Optional dependencies:
- Pybind11: to generate python bindings
- Doxygen: to generate documentation
- GTest/Pytest: for advanced testing
<a name="c++install"></a>C++
SimSiPM can be installed using the standard CMake workflow:
# In SimSiPM directory
cmake -B build -S .
make -C build
make -C build install
It is advisable to enable compiler optimizations like -O3 and -mfma -mavx2 since some parts of code are specifically written to exploit vectorization capabilities of the compilers.
Installation directory can be specified with -DCMAKE_INSTALL_PREFIX variable.
Python bindings can be compiled and installed by adding the variable -DCOMPILE_PYTHON_BINDINGS=ON but this requires Pybind11.
The corresponding python module is called SiPM and each class can be accessed as a sub-module.
import SiPM
from SiPM import SiPMSensor
print(SiPM.__version__)
<a name="pyinstall"></a>Python
It is also possible to use pip to install only the Python version using a precompiled binary wheel. This installation method is easyer but performance may be impaired with respect to the C++/Pybind11 installation.
pip install SiPM
<a name="C++_basic_usage"></a>C++ basic use
SimSiPM focuses on simplicity! It does not make use of pointers, or custom classes as parameters of the simulation or input. In most cases a std::vector is all that you need in order to get started.
SiPMProperties
SiPMProperties class stores all SiPM and simulation parameters. It can be used to define the SiPM detector model in use and it can be shared among different SiPMs in case many identical sensors are needed.
#include "SiPMProperties.h"
using namespace sipm;
// Create a SiPMProperties object
SiPMProperties myProperties;
// Edit some parameters
myProperties.setDcr(250e3); // Using proper setter
myProperties.setProperty("Xt",0.03); // Using parameter name
std::cout<<myProperties<<"\n"; // All classes can be printed using std::cout
// ===> SiPM Properties <===
// Address: 0x7f2cf11ea018
// Size: 1.00 mm
// Pitch: 25.00 um
// Number of cells: 1600
// Hit distribution: Uniform
// Cell recovery time: 50.00 ns
// Dark count rate: 250.00 kHz
// Optical crosstalk probability: 3.00 %
// Delayed optical crosstalk is OFF
// Afterpulse probability: 3.00 %
// Tau afterpulses (fast): 10.00 ns
// Tau afterpulses (slow): 80.00 ns
// Cell-to-cell gain variation: 5.00 %
// SNR: 30.00 dB
// Photon detection efficiency is OFF (100 %)
// Rising time of signal: 1.00 ns
// Falling time of signal (fast): 50.00 ns
// Signal length: 500.00 ns
// Sampling time: 1.00 ns
SiPMSensor
SiPMSensor class is the core of the simulation and is created from a SiPMProperties class. It stores input photoelectrons, it runs the event simulation and gives a signal as output.
#include "SiPMProperties.h"
using namespace sipm;
// Create a SiPMSensor object
SiPMSensor mySensor(myProperties);
// Change parameters
mySensor.properties().setAp(0.01); // Using proper getter/setter
mySensor.setProperty("Pitch", 25); // Using parameter name
std::cout<<mySensor<<"\n";
// ===> SiPM Sensor <===
// Address: 0x7f48ef5d62f0
// ===> SiPM Properties <===
// Address: 0x7f48ef5d62f0
// Size: 1.00 mm
// Pitch: 25.00 um
// Number of cells: 1600
// Hit distribution: Uniform
// Cell recovery time: 50.00 ns
// Dark count rate: 200.00 kHz
// Optical crosstalk probability: 5.00 %
// Delayed optical crosstalk is OFF
// Afterpulse probability: 1.00 %
// Tau afterpulses (fast): 10.00 ns
// Tau afterpulses (slow): 80.00 ns
// Cell-to-cell gain variation: 5.00 %
// SNR: 30.00 dB
// Photon detection efficiency is OFF (100 %)
// Rising time of signal: 1.00 ns
// Falling time of signal (fast): 50.00 ns
// Signal length: 500.00 ns
// Sampling time: 1.00 ns
// Address :0x7ffcded8a300
// ===> SiPM Debug Info <===
// Number of photons impinging to the sensor: 0
// Number of photoelectrons detected: 0
// Number of dark count events (DCR): 0
// Number of optical crosstalk events (XT + DTX): 0
// Number of delayed optical crosstalk events (DXT): 0
// Number of afterpulsing events (AP): 10.00
SiPMAnalogSignal
SiPMAnalogSignal class is a wrapper around std::vector that expands its features. It contains the samples of the SiPM waveform along with some properties and methods used to extract features from the signal.
SiPMAnalogSignal signal = mySensor.signal();
double sampling = signal.sampling();
double sample = signal[10];
std::cout<<signal<<"\n";
// ===> SiPM Analog Signal <===
// Address: 0x7f48ef5d64e8
// Signal length is: 0.00 ns
// Signal is sampled every: 1.00 ns
// Signal contains: 0 points
Input and simulation
The only input needed for the simulation of a SiPM event is the arriving time of each photon to the sensitive surface of the SiPM detector. In order to have a detailed description of the dependency of the PDE with respect to the photon wavelength it is possible to add the wavelength information togheter with the time information.
It is possible to add individual photons in a loop
mySensor.resetState();
for(...){
// Generate times for photons
mySensor.addPhoton(time); // Appends a single photon (time is in ns)
}
mySensor.runEvent(); // Runs the simulation
It is also possible to add all photons at once
std::vector<double> times = {13.12, 25.45, 33.68};
mySensor.resetState();
mySensor.addPhotons(times); // Sets photon times (times are in ns) (not appending)
mySensor.runEvent(); // Runs the simulation
Signal output and signal features
The simulation can output the signal waveform and can also perform some simple features extraction.
SiPMAnalogSignal mySignal = mySensor.signal();
double integral = signal.integral(5,250,0.5); // (intStart, intGate, threshold)
double peak = signal.peak(5,250,0.5); // (intStart, intGate, threshold)
double toa = signal.toa(5,250,0.5); // (intStart, intGate, threshold)
double tot = signal.tot(5,250,0.5); // (intStart, intGate, threshold)
// It is possible to iterate throw an analog signal
for(int i=0;i<mySignal.size();++i){
double sam
