CbmRoot
Loading...
Searching...
No Matches
tof/Calibrate.cxx
Go to the documentation of this file.
1/* Copyright (C) 2023 Facility for Antiproton and Ion Research in Europe, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Dominik Smith [committer] */
4
5#include "Calibrate.h"
6
9
10#include <chrono>
11
12using namespace std;
13using fles::Subsystem;
14
15namespace cbm::algo::tof
16{
17 // ----- Constructor ------------------------------------------------------
18 Calibrate::Calibrate(tof::CalibrateSetup setup) : fSetup(setup), smTypeOffset(1, 0), smOffset(1, 0), rpcOffset(1, 0)
19 {
20 // Initialize offset arrays for channel deadtime check
21 for (uint32_t SmType = 0; SmType < fSetup.NbSm.size(); SmType++) {
22 int32_t NbSm = fSetup.NbSm[SmType];
23 int32_t NbRpc = fSetup.NbRpc[SmType];
24 smTypeOffset.push_back(smTypeOffset.back() + NbSm);
25 for (int32_t Sm = 0; Sm < NbSm; Sm++) {
26 smOffset.push_back(smOffset.back() + NbRpc);
27 for (int32_t Rpc = 0; Rpc < NbRpc; Rpc++) {
28 int32_t NbChan = fSetup.rpcs[SmType][Sm * NbRpc + Rpc].chanPar.size();
29 rpcOffset.push_back(rpcOffset.back() + 2 * NbChan); //Factor 2 for channel sides
30 }
31 }
32 }
33 mChannelDeadTime = std::vector<double>(rpcOffset.back(), std::numeric_limits<double>::quiet_NaN());
34 }
35
36
37 // ----- Execution -------------------------------------------------------
38 Calibrate::resultType Calibrate::operator()(gsl::span<const CbmTofDigi> digiIn)
39 {
40 xpu::push_timer("TofCalibrate");
41 xpu::t_add_bytes(digiIn.size_bytes());
42
43 // --- Output data
44 resultType result = {};
45
46 auto& calDigiOut = result.first;
47 auto& monitor = result.second;
48 calDigiOut.reserve(digiIn.size());
49
50 std::fill(mChannelDeadTime.begin(), mChannelDeadTime.end(), std::numeric_limits<double>::quiet_NaN());
51
52 for (const auto& digi : digiIn) {
53 const double SmType = digi.GetType();
54 const double Sm = digi.GetSm();
55 const double Rpc = digi.GetRpc();
56 const double Chan = digi.GetChannel();
57 const double Side = digi.GetSide();
58 const int NbRpc = fSetup.NbRpc[SmType];
59
60 auto& rpcs = fSetup.rpcs;
61 if (SmType >= rpcs.size() || Sm * NbRpc + Rpc >= rpcs.at(SmType).size()) {
62 monitor.fDigiCalibUnknownRPC++;
63 continue;
64 }
65
66 CalibrateSetup::Rpc& rpcPar = fSetup.rpcs.at(SmType).at(Sm * NbRpc + Rpc);
67 CalibrateSetup::Channel& chanPar = rpcPar.chanPar[Chan];
68
69 // Check dead time
70 const size_t chanIdx = rpcOffset[smOffset[smTypeOffset[SmType] + Sm] + Rpc] + Chan + Side * rpcPar.chanPar.size();
71 const double deadTime = mChannelDeadTime[chanIdx];
72
73 if (!std::isnan(deadTime) && digi.GetTime() <= deadTime) {
74 mChannelDeadTime[chanIdx] = digi.GetTime() + rpcPar.channelDeadtime;
75 monitor.fDigiDeadTimeCount++;
76 continue;
77 }
78 mChannelDeadTime[chanIdx] = digi.GetTime() + rpcPar.channelDeadtime;
79
80 // Create calibrated digi
81 CbmTofDigi& pCalDigi = calDigiOut.emplace_back(digi);
82
83 // Check if channel sides need to be swapped
84 if (rpcPar.swapChannelSides && 5 != SmType && 8 != SmType) {
85 pCalDigi.SetAddress(Sm, Rpc, Chan, (0 == Side) ? 1 : 0, SmType);
86 }
87
88 // calibrate Digi Time
89 pCalDigi.SetTime(pCalDigi.GetTime() - chanPar.vCPTOff[Side]);
90
91 // subtract Offset
92 const double dTot = std::max(pCalDigi.GetTot() - chanPar.vCPTotOff[Side], 0.001);
93
94 // calibrate Digi ToT
95 pCalDigi.SetTot(dTot * chanPar.vCPTotGain[Side]);
96
97 // walk correction
98 std::vector<double>& walk = chanPar.vCPWalk[Side];
99 const double dTotBinSize = (rpcPar.TOTMax - rpcPar.TOTMin) / rpcPar.numClWalkBinX;
100 int32_t iWx = std::max((int32_t)((pCalDigi.GetTot() - rpcPar.TOTMin) / dTotBinSize), 0);
101 iWx = std::min(iWx, rpcPar.numClWalkBinX - 1);
102
103 const double dDTot = (pCalDigi.GetTot() - rpcPar.TOTMin) / dTotBinSize - (double) iWx - 0.5;
104 double dWT = walk[iWx];
105
106 // linear interpolation to next bin
107 if (dDTot > 0) {
108 if (iWx < rpcPar.numClWalkBinX - 1) {
109 dWT += dDTot * (walk[iWx + 1] - walk[iWx]);
110 }
111 }
112 else {
113 if (0 < iWx) {
114 dWT -= dDTot * (walk[iWx - 1] - walk[iWx]);
115 }
116 }
117 pCalDigi.SetTime(pCalDigi.GetTime() - dWT); // calibrate Digi Time
118 }
119
121 // (insert-sort faster than std::sort due to pre-sorting)
122 for (std::size_t i = 1; i < calDigiOut.size(); ++i) {
123 CbmTofDigi digi = calDigiOut[i];
124 std::size_t j = i;
125 while (j > 0 && calDigiOut[j - 1].GetTime() > digi.GetTime()) {
126 calDigiOut[j] = calDigiOut[j - 1];
127 --j;
128 }
129 calDigiOut[j] = digi;
130 }
131
132 // Kept for possible unsorted input
133 // std::sort(calDigiOut.begin(), calDigiOut.end(),
134 // [](const CbmTofDigi& a, const CbmTofDigi& b) -> bool { return a.GetTime() < b.GetTime(); });
135
136 monitor.fTime = xpu::pop_timer();
137 monitor.fNumDigis = digiIn.size();
138 return result;
139 }
140
141} // namespace cbm::algo::tof
Data class for expanded digital TOF information.
Definition CbmTofDigi.h:47
void SetTot(double tot)
Definition CbmTofDigi.h:169
double GetTime() const
Inherited from CbmDigi.
Definition CbmTofDigi.h:132
double GetTot() const
Alias for GetCharge.
Definition CbmTofDigi.h:141
void SetAddress(int32_t address)
Definition CbmTofDigi.h:166
void SetTime(double time)
Definition CbmTofDigi.h:168
resultType operator()(gsl::span< const CbmTofDigi > digiIn)
Algorithm execution.
std::vector< double > mChannelDeadTime
Storage for deadtime check.
Calibrate(tof::CalibrateSetup params)
Constructor.
std::vector< size_t > smTypeOffset
Offset of super module type.
std::vector< size_t > smOffset
Offset of super module.
std::vector< size_t > rpcOffset
Offset of RPC.
tof::CalibrateSetup fSetup
Parameters for TOF calibrator.
std::pair< std::vector< CbmTofDigi >, CalibrateMonitorData > resultType
Hash for CbmL1LinkKey.
std::vector< std::vector< double > > vCPWalk
std::vector< std::vector< Rpc > > rpcs