Skip to content

Commit 96c2635

Browse files
committed
FV0-like digitizer added
1 parent 0ee92aa commit 96c2635

5 files changed

Lines changed: 693 additions & 1 deletion

File tree

Detectors/Upgrades/ALICE3/FD3/simulation/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111

1212
o2_add_library(FD3Simulation
1313
SOURCES src/Detector.cxx
14+
src/Digitizer.cxx
1415
PUBLIC_LINK_LIBRARIES O2::FD3Base
1516
O2::DataFormatsFD3
1617
ROOT::Physics)
1718

1819
o2_target_root_dictionary(FD3Simulation
19-
HEADERS include/FD3Simulation/Detector.h)
20+
HEADERS include/FD3Simulation/Detector.h
21+
include/FD3Simulation/DigitizationConstants.h
22+
include/FD3Simulation/Digitizer.h)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2019-2025 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef ALICEO2_FD3_DIGITIZATION_CONSTANTS
13+
#define ALICEO2_FD3_DIGITIZATION_CONSTANTS
14+
15+
#include "FD3Base/FD3BaseParam.h"
16+
#include "FD3Base/Constants.h"
17+
18+
namespace o2
19+
{
20+
namespace fd3
21+
{
22+
struct DigitizationConstants {
23+
static constexpr int NCELLSA = Constants::nringsA * Constants::nsect; // number of scintillator cells side A
24+
static constexpr int NCELLSC = Constants::nringsC * Constants::nsect; // number of scintillator cells side C
25+
static constexpr int NCELLSTOT = NCELLSA + NCELLSC; // total number of scintillator cells
26+
static constexpr float INV_CHARGE_PER_ADC = 1. / 0.6e-12; // charge conversion
27+
static constexpr float TIME_PER_TDCCHANNEL = 0.01302; // time conversion from TDC channels to ns
28+
static constexpr float INV_TIME_PER_TDCCHANNEL = 1. / TIME_PER_TDCCHANNEL; // time conversion from ns to TDC channels
29+
static constexpr float N_PHOTONS_PER_MEV = 10400; // average #photons generated per 1 MeV of deposited energy
30+
};
31+
} // namespace o2
32+
} // namespace fd3
33+
#endif
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Copyright 2019-2025 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef ALICEO2_FD3_DIGITIZER_H
13+
#define ALICEO2_FD3_DIGITIZER_H
14+
15+
#include "CommonDataFormat/InteractionRecord.h"
16+
#include "DataFormatsFD3/Digit.h"
17+
#include "DataFormatsFD3/ChannelData.h"
18+
#include "DataFormatsFD3/MCLabel.h"
19+
#include "FD3Simulation/Detector.h"
20+
#include "FD3Base/Constants.h"
21+
#include "SimulationDataFormat/MCTruthContainer.h"
22+
#include "FD3Simulation/DigitizationConstants.h"
23+
#include <array>
24+
#include <vector>
25+
26+
namespace o2
27+
{
28+
namespace fd3
29+
{
30+
class Digitizer
31+
{
32+
private:
33+
using DP = DigitizationConstants;
34+
35+
public:
36+
Digitizer()
37+
: mTimeStamp(0), mIntRecord(), mEventId(-1), mSrcId(-1), mMCLabels(), mCache(), mPmtChargeVsTime(), mNBins(), mNTimeBinsPerBC(), mPmtResponseGlobalRings(), mPmtResponseTemp(), mLastBCCache(), mCfdStartIndex()
38+
{
39+
}
40+
41+
/// Destructor
42+
~Digitizer() = default;
43+
44+
Digitizer(const Digitizer&) = delete;
45+
Digitizer& operator=(const Digitizer&) = delete;
46+
47+
void clear();
48+
void init();
49+
50+
void setTimeStamp(long t) { mTimeStamp = t; }
51+
void setEventId(Int_t id) { mEventId = id; }
52+
void setSrcId(Int_t id) { mSrcId = id; }
53+
void setInteractionRecord(const InteractionTimeRecord& ir) { mIntRecord = ir; }
54+
55+
void process(const std::vector<o2::fd3::Hit>& hits, std::vector<o2::fd3::Digit>& digitsBC,
56+
std::vector<o2::fd3::ChannelData>& digitsCh, std::vector<o2::fd3::DetTrigInput>& digitsTrig,
57+
o2::dataformats::MCTruthContainer<o2::fd3::MCLabel>& labels);
58+
59+
void flush(std::vector<o2::fd3::Digit>& digitsBC,
60+
std::vector<o2::fd3::ChannelData>& digitsCh,
61+
std::vector<o2::fd3::DetTrigInput>& digitsTrig,
62+
o2::dataformats::MCTruthContainer<o2::fd3::MCLabel>& labels);
63+
64+
const InteractionRecord& getInteractionRecord() const { return mIntRecord; }
65+
InteractionRecord& getInteractionRecord(InteractionRecord& src) { return mIntRecord; }
66+
uint32_t getOrbit() const { return mIntRecord.orbit; }
67+
uint16_t getBC() const { return mIntRecord.bc; }
68+
69+
using ChannelDigitF = std::vector<float>;
70+
71+
struct BCCache : public o2::InteractionRecord {
72+
std::vector<o2::fd3::MCLabel> labels;
73+
std::array<ChannelDigitF, DP::NCELLSTOT> mPmtChargeVsTime = {};
74+
75+
void clear()
76+
{
77+
for (auto& channel : mPmtChargeVsTime) {
78+
std::fill(std::begin(channel), std::end(channel), 0.);
79+
}
80+
labels.clear();
81+
}
82+
83+
BCCache& operator=(const o2::InteractionRecord& ir)
84+
{
85+
o2::InteractionRecord::operator=(ir);
86+
return *this;
87+
}
88+
void print() const;
89+
};
90+
91+
private:
92+
static constexpr int BCCacheMin = 0, BCCacheMax = 7, NBC2Cache = 1 + BCCacheMax - BCCacheMin;
93+
/// Create signal pulse based on MC hit
94+
/// \param mipFraction Fraction of the MIP energy deposited in the cell
95+
/// \param parID Particle ID
96+
/// \param hitTime Time of the hit
97+
/// \param hitR Length to IP from the position of the hit
98+
/// \param cachedIR Cached interaction records
99+
/// \param nCachedIR Number of cached interaction records
100+
/// \param detID Detector cell ID
101+
void createPulse(float mipFraction, int parID, const double hitTime, const float hitR,
102+
std::array<o2::InteractionRecord, NBC2Cache> const& cachedIR, int nCachedIR, const int detID);
103+
104+
long mTimeStamp; // TF (run) timestamp
105+
InteractionTimeRecord mIntRecord; // Interaction record (orbit, bc) -> InteractionTimeRecord
106+
Int_t mEventId; // ID of the current event
107+
Int_t mSrcId; // signal, background or QED
108+
std::deque<fd3::MCLabel> mMCLabels;
109+
std::deque<BCCache> mCache;
110+
111+
BCCache& setBCCache(const o2::InteractionRecord& ir);
112+
BCCache* getBCCache(const o2::InteractionRecord& ir);
113+
114+
void storeBC(const BCCache& bc,
115+
std::vector<o2::fd3::Digit>& digitsBC,
116+
std::vector<o2::fd3::ChannelData>& digitsCh,
117+
std::vector<o2::fd3::DetTrigInput>& digitsTrig,
118+
o2::dataformats::MCTruthContainer<o2::fd3::MCLabel>& labels);
119+
120+
std::array<std::vector<float>, DigitizationConstants::NCELLSTOT> mPmtChargeVsTime; // Charge time series aka analogue signal pulse from PM
121+
unsigned int mNBins; //
122+
unsigned int mNTimeBinsPerBC;
123+
float mBinSize; // Time width of the pulse bin - HPTDC resolution
124+
125+
/// vectors to store the PMT signal from cosmic muons
126+
std::vector<double> mPmtResponseGlobalRings;
127+
std::vector<double> mPmtResponseTemp;
128+
129+
/// for CFD
130+
BCCache mLastBCCache; // buffer for the last BC
131+
std::array<int, DigitizationConstants::NCELLSTOT> mCfdStartIndex; // start indices for the CFD detector
132+
133+
/// Internal helper methods related to conversion of energy-deposition into el. signal
134+
Int_t SimulateLightYield(Int_t pmt, Int_t nPhot) const;
135+
float SimulateTimeCfd(int& startIndex, const ChannelDigitF& pulseLast, const ChannelDigitF& pulse) const;
136+
float IntegrateCharge(const ChannelDigitF& pulse) const;
137+
138+
ClassDefNV(Digitizer, 1);
139+
};
140+
} // namespace fd3
141+
} // namespace o2
142+
143+
#endif
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright 2019-2025 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file FD3DigParam.h
13+
/// \brief Configurable digitization parameters
14+
15+
#ifndef ALICEO2_FD3_DIG_PARAM
16+
#define ALICEO2_FD3_DIG_PARAM
17+
18+
#include "CommonConstants/PhysicsConstants.h"
19+
#include "CommonUtils/ConfigurableParamHelper.h"
20+
21+
namespace o2
22+
{
23+
namespace fd3
24+
{
25+
// parameters of FD3 digitization / transport simulation
26+
struct FD3DigParam : o2::conf::ConfigurableParamHelper<FD3DigParam> {
27+
float hitTimeOffset = 0.0; ///< Hit time offset [ns]
28+
29+
float photoCathodeEfficiency = 0.23; // quantum efficiency = nOfPhotoE_emitted_by_photocathode / nIncidentPhotons
30+
float lightYield = 0.01; // light collection efficiency to be tuned using collision data [1%]
31+
float adcChannelsPerMip = 16; // Default: 16 for pp and 8 for PbPb
32+
float getChannelsPerMilivolt() const { return adcChannelsPerMip / 7.5; } // Non-trivial conversion depending on the pulseshape: amplitude to charge
33+
float chargeThrForMeanTime = 5; // Charge threshold, only above which the time is taken into account in calculating the mean time of all qualifying channels
34+
35+
/// Parameters for the FD3 waveform [Conv. of expo. with Landau]
36+
// For ring 1-4
37+
float offsetRings = 15.87e-09;
38+
float normRingsbase = 9.1042481e-13;
39+
float getNormRings() const { return normRingsbase * adcChannelsPerMip / 16; }
40+
float constRings = -25.6165;
41+
float slopeRings = 4.7942e+08;
42+
float mpvRings = -6.38203e-08;
43+
float sigmaRings = 2.12167e-09;
44+
// For ring 5
45+
// float offsetRing5 = 16.38e-09;
46+
// float normRing5base = 1.1680805e-12;
47+
// float getNormRing5() const { return normRing5base * adcChannelsPerMip / 16; }
48+
// float constRing5 = -66.76;
49+
// float slopeRing5 = 9.43117e+08;
50+
// float mpvRing5 = -6.44167e-08;
51+
// float sigmaRing5 = 2.3621e-09;
52+
53+
float timeShiftCfd = 5.3; // TODO: adjust after FD3 with FEE measurements are done
54+
float singleMipThreshold = 3.0; // in [MeV] of deposited energy
55+
float singleHitTimeThreshold = 120.0; // in [ns] to skip very slow particles
56+
UInt_t waveformNbins = 10000; // number of bins for the analog pulse waveform
57+
float waveformBinWidth = 0.01302; // bin width [ns] for analog pulse waveform
58+
float avgCfdTimeForMip = 8.63; // in ns to shift the CFD time to zero TODO [do ring wise]
59+
bool isIntegrateFull = false; // Full charge integration widow in 25 ns
60+
float cfdCheckWindow = 2.5; // time window for the cfd in ns to trigger the charge integration
61+
int avgNumberPhElectronPerMip = 201; // avg number of photo-electrons per MIP
62+
float mCfdDeadTime = 15.6; // [ns]
63+
float mCFD_trsh = 3.; // [mV]
64+
float getCFDTrshInAdc() const { return mCFD_trsh * getChannelsPerMilivolt(); } // [ADC channels]
65+
/// Parameters for trigger simulation
66+
bool useMaxChInAdc = true; // default = true
67+
int adcChargeCenThr = 3 * 498; // threshold value of ADC charge for Central trigger
68+
int adcChargeSCenThr = 1 * 498; // threshold value of ADC charge for Semi-central trigger
69+
int maxCountInAdc = 4095; // to take care adc ADC overflow
70+
short mTime_trg_gate = 153; // #channels as in TCM as in Pilot beams ('OR gate' setting in TCM tab in ControlServer)
71+
uint8_t defaultChainQtc = 0x48; // only 2 flags are set by default in simulation: kIsCFDinADCgate and kIsEventInTVDC
72+
float mAmpThresholdForReco = 24; // only channels with amplitude higher will participate in calibration and collision time
73+
short mTimeThresholdForReco = 1000; // only channels with time below will participate in calibration and collision time
74+
75+
O2ParamDef(FD3DigParam, "FD3DigParam");
76+
};
77+
} // namespace o2
78+
} // namespace fd3
79+
80+
#endif

0 commit comments

Comments
 (0)