CbmRoot
Loading...
Searching...
No Matches
tof/HitFinder.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022 Facility for Antiproton and Ion Research in Europe, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Dominik Smith [committer], Pierre-Alain Loizeau */
4
5#include "HitFinder.h"
6
7// TOF Classes and includes
8#include "CbmTofDigi.h"
9
10// C++ Classes and includes
11#include <iomanip>
12#include <iostream>
13
14namespace cbm::algo::tof
15{
16 HitFinder::resultType HitFinder::operator()(std::vector<CbmTofDigi> digisIn, const std::vector<int32_t>& digiIndexIn)
17 {
18 inputType input = calibrateDigis(digisIn, digiIndexIn);
19 return buildClusters(input);
20 }
21
23 {
24 // Intermediate storage variables
25 std::vector<std::vector<CbmTofDigi*>>& digisExp = input.first; //[nbCh][nDigis]
26 std::vector<std::vector<int32_t>>& digisInd = input.second; //[nbCh][nDigis]
27
28 // Hit variables
29 Cluster cluster;
30 std::vector<Cluster> clustersOut;
31
32 // Reference cell of a cluster
33 Cell* trafoCell = nullptr;
34 int32_t iTrafoCell = -1;
35
36 // Last Channel Temp variables
37 int32_t lastChan = -1;
38 double lastPosY = 0.0;
39 double lastTime = 0.0;
40
41 //reset counter
42 numSameSide = 0;
43
44 for (int32_t chan = 0; chan < (int32_t) fParams.fChanPar.size(); chan++) {
45
46 std::vector<CbmTofDigi*>& storDigiExp = digisExp[chan];
47 std::vector<int32_t>& storDigiInd = digisInd[chan];
48 HitFinderChanPar& chanPar = fParams.fChanPar[chan];
49
50 auto digiExpIt = storDigiExp.begin();
51 auto digiIndIt = storDigiInd.begin();
52
53 while (1 < std::distance(digiExpIt, storDigiExp.end())) {
54 while ((*digiExpIt)->GetSide() == (*std::next(digiExpIt, 1))->GetSide()) {
55 // Not one Digi of each end!
57 digiExpIt++;
58 digiIndIt++;
59 if (2 > std::distance(digiExpIt, storDigiExp.end())) break;
60 }
61 if (2 > std::distance(digiExpIt, storDigiExp.end())) break; // 2 Digis = both sides present
62
63 Cell* channelInfo = &chanPar.cell;
64 CbmTofDigi* xDigiA = *digiExpIt;
65 CbmTofDigi* xDigiB = *std::next(digiExpIt, 1);
66
67 // The "Strip" time is the mean time between each end
68 const double time = 0.5 * (xDigiA->GetTime() + xDigiB->GetTime());
69
70 // Weight is the total charge => sum of both ends ToT
71 const double totSum = xDigiA->GetTot() + xDigiB->GetTot();
72
73 if (nullptr == trafoCell) {
74 trafoCell = channelInfo;
75 iTrafoCell = chan;
76 }
77
78 // switch to local coordinates, (0,0,0) is in the center of counter ?
79 // It is assumed that the cell size is the same for all channels within one rpc!
80 ROOT::Math::XYZVector pos(((double) (-iTrafoCell + chan)) * trafoCell->sizeX, 0., 0.);
81
82 if (1 == xDigiA->GetSide()) {
83 // 0 is the top side, 1 is the bottom side
84 pos.SetY(fParams.CPSigPropSpeed * (xDigiA->GetTime() - xDigiB->GetTime()) / 2.0);
85 }
86 else {
87 // 0 is the bottom side, 1 is the top side
88 pos.SetY(fParams.CPSigPropSpeed * (xDigiB->GetTime() - xDigiA->GetTime()) / 2.0);
89 }
90
91 if (channelInfo->sizeY / 2.0 < pos.Y() || -1 * channelInfo->sizeY / 2.0 > pos.Y()) {
92 // if outside of strip limits, the pair is bad => try to remove one end and check the next pair
93 // (if another possibility exist)
94 digiExpIt++;
95 digiIndIt++;
96 continue;
97 } // Pair leads to hit oustide of strip limits
98
99 // Now check if a hit/cluster is already started
100 if (0 < cluster.numChan()) {
101 // a cluster is already started => check distance in space/time
102 // For simplicity, just check along strip direction for now
103 // and break cluster when a not fired strip is found
104 if (!(std::abs(time - lastTime) < fParams.maxTimeDist && lastChan == chan - 1
105 && std::abs(pos.Y() - lastPosY) < fParams.maxSpaceDist)) {
106 // simple error scaling with TOT
107 // weightedTimeErr = TMath::Sqrt( weightedTimeErr ) * SysTimeRes / weightsSum;
108 // OR harcoded value: weightedTimeErr = SysTimeRes;
110
111 // Save Hit and start a new one
112 cluster.finalize(*trafoCell, iTrafoCell, fParams);
113 clustersOut.push_back(cluster);
114 cluster.reset();
115 }
116 }
117 cluster.add(pos, time, totSum, totSum, *digiIndIt, *std::next(digiIndIt, 1));
118 digiExpIt += 2;
119 digiIndIt += 2;
120
121 lastChan = chan;
122 lastPosY = pos.Y();
123 lastTime = time;
124 } // while (1 < storDigiExp.size())
125 } // for( int32_t chan = 0; chan < iNbCh; chan++ )
126
127 // Save last cluster if it exists
128 if (0 < cluster.numChan()) {
130 cluster.finalize(*trafoCell, iTrafoCell, fParams);
131 clustersOut.push_back(cluster);
132 }
133 return clustersOut;
134 }
135
136 HitFinder::inputType HitFinder::calibrateDigis(std::vector<CbmTofDigi>& digisIn,
137 const std::vector<int32_t>& digiIndexIn)
138 {
139 inputType result;
140 std::vector<std::vector<CbmTofDigi*>>& digisExp = result.first; //[nbCh][nDigis]
141 std::vector<std::vector<int32_t>>& digisInd = result.second; //[nbCh][nDigis]
142
143 digisExp.resize(fParams.fChanPar.size());
144 digisInd.resize(fParams.fChanPar.size());
145
146 const int32_t numClWalkBinX = fParams.numClWalkBinX;
147 const double TOTMax = fParams.TOTMax;
148 const double TOTMin = fParams.TOTMin;
149
150 for (size_t iDigi = 0; iDigi < digisIn.size(); iDigi++) {
151 CbmTofDigi* pDigi = &digisIn[iDigi];
152 assert(pDigi);
153
154 // These are doubles in the digi class
155 const double chan = pDigi->GetChannel();
156 const double side = pDigi->GetSide();
157 const double charge = pDigi->GetTot() * fParams.fChanPar[chan].fvCPTotGain[side]; // calibrate Digi ToT
158 const double time = pDigi->GetTime() - fParams.fChanPar[chan].fvCPTOff[side]; // calibrate Digi Time
159
160 digisExp[chan].push_back(pDigi);
161 digisInd[chan].push_back(digiIndexIn[iDigi]);
162
163 pDigi->SetTot(charge);
164
165 { // walk correction
166 const double totBinSize = (TOTMax - TOTMin) / 2. / numClWalkBinX;
167 int32_t iWx = (int32_t)((charge - TOTMin / 2.) / totBinSize);
168 if (0 > iWx) iWx = 0;
169 if (iWx > (numClWalkBinX - 1)) iWx = numClWalkBinX - 1;
170
171 std::vector<double>& cpWalk = fParams.fChanPar[chan].fvCPWalk[side];
172 double dWT = cpWalk[iWx];
173 const double dDTot = (charge - TOTMin / 2.) / totBinSize - (double) iWx - 0.5;
174
175 if (dDTot > 0) {
176 if (iWx < numClWalkBinX - 1) { // linear interpolation to next bin
177 dWT += dDTot * (cpWalk[iWx + 1] - cpWalk[iWx]);
178 }
179 }
180 else {
181 if (0 < iWx) { // linear interpolation to next bin
182 dWT -= dDTot * (cpWalk[iWx - 1] - cpWalk[iWx]);
183 }
184 }
185 pDigi->SetTime(time - dWT);
186 }
187 }
188 return result;
189 }
190} // namespace cbm::algo::tof
const int32_t numClWalkBinX
Double_t TOTMax
Double_t TOTMin
Data class for expanded digital TOF information.
Definition CbmTofDigi.h:47
double GetSide() const
Channel Side.
Definition CbmTofDigi.h:160
void SetTot(double tot)
Definition CbmTofDigi.h:166
double GetChannel() const
Channel .
Definition CbmTofDigi.h:156
double GetTime() const
Inherited from CbmDigi.
Definition CbmTofDigi.h:131
double GetTot() const
Alias for GetCharge.
Definition CbmTofDigi.h:140
void SetTime(double time)
Definition CbmTofDigi.h:165
resultType buildClusters(inputType &input)
inputType calibrateDigis(std::vector< CbmTofDigi > &digisIn, const std::vector< int32_t > &digiIndexIn)
HitFinderRpcPar fParams
Parameter container.
resultType operator()(std::vector< CbmTofDigi > digisIn, const std::vector< int32_t > &digiIndexIn)
Build clusters out of ToF Digis and store the resulting info in a TofHit.
std::pair< std::vector< std::vector< CbmTofDigi * > >, std::vector< std::vector< int32_t > > > inputType
std::vector< Cluster > resultType
void add(ROOT::Math::XYZVector pos, double time, double timeErr, double weight, int32_t digiIndA, int32_t digiIndB)
void finalize(const Cell &trafoCell, const int32_t iTrafoCell, const HitFinderRpcPar &par)
void normalize(double timeErr)
std::vector< HitFinderChanPar > fChanPar