CbmRoot
Loading...
Searching...
No Matches
tof/Hitfind.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 "Hitfind.h"
6
8#include "compat/OpenMP.h"
10
11#include <chrono>
12
13using namespace std;
14using fles::Subsystem;
15
16namespace cbm::algo::tof
17{
18 // ----- Constructor ------------------------------------------------------
19 Hitfind::Hitfind(tof::HitfindSetup setup) : fNbSm(setup.NbSm), fNbRpc(setup.NbRpc), fStorDigi(fNbSm.size())
20 {
21
22 // Create one algorithm per RPC for TOF and configure it with parametersa
23 for (uint32_t SmType = 0; SmType < fNbSm.size(); SmType++) {
24
25 int32_t NbSm = fNbSm[SmType];
26 int32_t NbRpc = fNbRpc[SmType];
27 fStorDigi[SmType].resize(NbSm * NbRpc);
28
29 for (int32_t Sm = 0; Sm < NbSm; Sm++) {
30 for (int32_t Rpc = 0; Rpc < NbRpc; Rpc++) {
31
32 auto par = std::make_unique<cbm::algo::tof::ClusterizerRpcPar>();
33
34 HitfindSetup::Rpc rpcPar = setup.rpcs[SmType][Sm * NbRpc + Rpc];
35 par->fDeadStrips = rpcPar.deadStrips;
36 par->fPosYMaxScal = rpcPar.posYMaxScal;
37 par->fdMaxTimeDist = rpcPar.maxTimeDist;
38 par->fdMaxSpaceDist = rpcPar.maxSpaceDist;
39 par->fSigVel = rpcPar.sigVel;
40 par->fCPTOffYBinWidth = rpcPar.CPTOffYBinWidth;
41 par->fCPTOffY = rpcPar.CPTOffY;
42 par->fCPTOffYRange = rpcPar.CPTOffYRange;
43 par->fTimeRes = rpcPar.timeRes;
44
45 //geometry information, can in principle be done channel-wise but not needed for now
46 const double* tra_ptr = rpcPar.cell.translation.data();
47 const double* rot_ptr = rpcPar.cell.rotation.data();
48
49 //channel parameters
50 int32_t NbChan = rpcPar.chanPar.size();
51 par->fChanPar.resize(NbChan);
52
53 for (int32_t Ch = 0; Ch < NbChan; Ch++) {
54 HitfindSetup::Channel chanPar = rpcPar.chanPar[Ch];
55 par->fChanPar[Ch].address = chanPar.address;
56 par->fChanPar[Ch].cell.pos = ROOT::Math::XYZVector(tra_ptr[0], tra_ptr[1], tra_ptr[2]);
57 par->fChanPar[Ch].cell.rotation = ROOT::Math::Rotation3D(&rot_ptr[0], &rot_ptr[9]);
58 par->fChanPar[Ch].cell.sizeX = rpcPar.cell.sizeX;
59 par->fChanPar[Ch].cell.sizeY = rpcPar.cell.sizeY;
60 }
61 fAlgo.emplace_back(std::move(*par));
62
63 // fill unique rpc pointer vectors for parallelization
64 fStorDigiPtr.push_back(&fStorDigi[SmType][Sm * NbRpc + Rpc]);
65 }
66 }
67 }
68 L_(info) << "--- Configured hitfinder algorithms for TOF.";
69 }
70 // ----------------------------------------------------------------------------
71
72
73 // ----- Execution -------------------------------------------------------
74 Hitfind::resultType Hitfind::operator()(gsl::span<CbmTofDigi> digiIn)
75 {
76 // --- Output data
77 resultType result = {};
78 //auto& [clusterTs, monitor, digiInd] = result; // TO DO: Re-activte this when compiler bug is fixed
79 auto& clusterTs = std::get<0>(result);
80 auto& monitor = std::get<1>(result);
81 auto& digiInd = std::get<2>(result);
82
83 // Loop over the digis array and store the Digis in separate vectors for
84 // each RPC modules
85 xpu::push_timer("TofHitfindChanSort");
86 for (size_t idigi = 0; idigi < digiIn.size(); idigi++) {
87 CbmTofDigi* pDigi = &(digiIn[idigi]);
88
89 // These are doubles in the digi class
90 const double SmType = pDigi->GetType();
91 const double Sm = pDigi->GetSm();
92 const double Rpc = pDigi->GetRpc();
93 const int NbRpc = fNbRpc[SmType];
94 if (SmType >= fNbSm.size() || Sm * NbRpc + Rpc >= fNbSm[SmType] * NbRpc) {
95 // Error already counted for monitoring during Digis calibration, so just discard here
96 continue;
97 }
98 fStorDigi[SmType][Sm * NbRpc + Rpc].emplace_back(*pDigi, idigi);
99 }
100 monitor.fSortTime = xpu::pop_timer();
101
102 PODVector<Hit> clustersFlat; // cluster storage
103 PODVector<size_t> chanSizes; // nClusters per channel
104 PODVector<u32> chanAddresses; // channel addresses
105
106 // Prefix arrays for parallelization
107 std::vector<size_t> cluPrefix;
108 std::vector<size_t> sizePrefix;
109 std::vector<size_t> addrPrefix;
110 std::vector<size_t> indPrefix;
111
112 xpu::push_timer("TofHitfind");
113 xpu::t_add_bytes(digiIn.size_bytes());
114
116 {
117 const int ithread = openmp::GetThreadNum();
118 const int nthreads = openmp::GetNumThreads();
119
120 CBM_OMP(single)
121 {
122 cluPrefix.resize(nthreads + 1);
123 sizePrefix.resize(nthreads + 1);
124 addrPrefix.resize(nthreads + 1);
125 indPrefix.resize(nthreads + 1);
126 }
127
128 //auto [clusters, sizes, addresses, indices] = Clusterizer::resultType(); // TO DO: Re-activte this when compiler bug is fixed
129 auto localresult = Clusterizer::resultType();
130 auto& clusters = std::get<0>(localresult);
131 auto& sizes = std::get<1>(localresult);
132 auto& addresses = std::get<2>(localresult);
133 auto& indices = std::get<3>(localresult);
134
135 CBM_OMP(for schedule(dynamic) nowait)
136 for (uint32_t iRpc = 0; iRpc < fAlgo.size(); iRpc++) {
137
138 // Get digis
139 std::vector<std::pair<CbmTofDigi, int32_t>>& digiExp = *fStorDigiPtr[iRpc];
140
141 // Build clusters
142 //auto [rpc_clu, rpc_size, rpc_addr, rpc_ind] = fAlgo[iRpc](digiExp); // TO DO: Re-activte this when compiler bug is fixed
143 auto rpc_result = fAlgo[iRpc](digiExp);
144 auto& rpc_clu = std::get<0>(rpc_result);
145 auto& rpc_size = std::get<1>(rpc_result);
146 auto& rpc_addr = std::get<2>(rpc_result);
147 auto& rpc_ind = std::get<3>(rpc_result);
148
149 // Append clusters to output
150 clusters.insert(clusters.end(), std::make_move_iterator(rpc_clu.begin()),
151 std::make_move_iterator(rpc_clu.end()));
152
153 // store partition size
154 sizes.insert(sizes.end(), std::make_move_iterator(rpc_size.begin()), std::make_move_iterator(rpc_size.end()));
155
156 // Store hw address of partition
157 addresses.insert(addresses.end(), std::make_move_iterator(rpc_addr.begin()),
158 std::make_move_iterator(rpc_addr.end()));
159
160 // store digi indices
161 indices.insert(indices.end(), std::make_move_iterator(rpc_ind.begin()), std::make_move_iterator(rpc_ind.end()));
162
163 // Clear digi storage
164 digiExp.clear();
165 }
166 cluPrefix[ithread + 1] = clusters.size();
167 sizePrefix[ithread + 1] = sizes.size();
168 addrPrefix[ithread + 1] = addresses.size();
169 indPrefix[ithread + 1] = indices.size();
170 CBM_OMP(barrier)
171
172 CBM_OMP(single)
173 {
174 for (int i = 1; i < (nthreads + 1); i++) {
175 cluPrefix[i] += cluPrefix[i - 1];
176 sizePrefix[i] += sizePrefix[i - 1];
177 addrPrefix[i] += addrPrefix[i - 1];
178 indPrefix[i] += indPrefix[i - 1];
179 }
180
181 clustersFlat.resize(cluPrefix[nthreads]);
182 chanSizes.resize(sizePrefix[nthreads]);
183 chanAddresses.resize(addrPrefix[nthreads]);
184 digiInd.resize(indPrefix[nthreads]);
185 }
186 std::move(clusters.begin(), clusters.end(), clustersFlat.begin() + cluPrefix[ithread]);
187 std::move(sizes.begin(), sizes.end(), chanSizes.begin() + sizePrefix[ithread]);
188 std::move(addresses.begin(), addresses.end(), chanAddresses.begin() + addrPrefix[ithread]);
189 std::move(indices.begin(), indices.end(), digiInd.begin() + indPrefix[ithread]);
190 }
191
192 // Monitoring
193 monitor.fTime = xpu::pop_timer();
194 monitor.fNumDigis = digiIn.size();
195 monitor.fNumHits = clustersFlat.size();
196
197 // Create ouput vector
198 clusterTs = PartitionedVector(std::move(clustersFlat), chanSizes, chanAddresses);
199
200 return result;
201 }
202 // ----------------------------------------------------------------------------
203
204} // namespace cbm::algo::tof
#define L_(level)
static constexpr size_t size()
Definition KfSimdPseudo.h:2
#define CBM_OMP(...)
Definition OpenMP.h:39
#define CBM_PARALLEL(...)
Definition OpenMP.h:32
Data class for expanded digital TOF information.
Definition CbmTofDigi.h:47
double GetSm() const
Sm.
Definition CbmTofDigi.h:144
double GetType() const
Sm Type .
Definition CbmTofDigi.h:148
double GetRpc() const
Detector aka Module aka RPC .
Definition CbmTofDigi.h:152
A vector that is partitioned into multiple subvectors.
std::tuple< std::vector< Hit >, std::vector< size_t >, std::vector< u32 >, std::vector< int32_t > > resultType
std::vector< std::vector< std::pair< CbmTofDigi, int32_t > > * > fStorDigiPtr
Pointer to storage variables with unique RPC index (for OpenMP)
Definition tof/Hitfind.h:82
std::vector< std::vector< std::vector< std::pair< CbmTofDigi, int32_t > > > > fStorDigi
Intermediate storage variables (digi, index)
Definition tof/Hitfind.h:79
resultType operator()(gsl::span< CbmTofDigi > digiIn)
Algorithm execution.
std::tuple< PartitionedVector< Hit >, HitfindMonitorData, PODVector< i32 > > resultType
Definition tof/Hitfind.h:55
std::vector< int32_t > fNbSm
Number of SMs per super module type.
Definition tof/Hitfind.h:73
std::vector< tof::Clusterizer > fAlgo
TOF hitfinders (with unique RPC index for OpenMP)
Definition tof/Hitfind.h:70
std::vector< int32_t > fNbRpc
Number of RPCs per super module type.
Definition tof/Hitfind.h:76
Hitfind(tof::HitfindSetup)
Constructor.
int GetNumThreads()
Definition OpenMP.h:48
int GetThreadNum()
Definition OpenMP.h:47
std::vector< T, PODAllocator< T > > PODVector
PODVector is a std::vector that doesn't initialize its elements.
Definition PODVector.h:17
Hash for CbmL1LinkKey.
std::array< double, 3 > translation
Hitfind setup / Hardware cabling for TOF Used to create the hardware mapping for the TOF hitfinder.
std::vector< std::vector< Rpc > > rpcs