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