36 for (
size_t mod = 0; mod < setup.
modules.size(); mod++) {
42 const double* tra_ptr =
module.translation.data();
43 const double* rot_ptr =
module.rotation.data();
44 params.
translation = ROOT::Math::XYZVector(tra_ptr[0], tra_ptr[1], tra_ptr[2]);
45 params.
rotation = ROOT::Math::Rotation3D(&rot_ptr[0], &rot_ptr[9]);
46 params.
address =
module.address;
53 for (
size_t row = 0; row < module.
rowPar.size(); row++) {
57 for (
size_t col = 0; col < rowPar.
padPar.size(); col++) {
61 const double* pos_ptr = pad.
position.data();
63 padPar.
pos = ROOT::Math::XYZVector(pos_ptr[0], pos_ptr[1], pos_ptr[2]);
64 padPar.
posErr = ROOT::Math::XYZVector(posErr_ptr[0], posErr_ptr[1], posErr_ptr[2]);
68 fHitFind[module.
address] = std::make_unique<cbm::algo::trd::HitFinder>(params);
69 fHitMerge[module.
address] = std::make_unique<cbm::algo::trd::HitMerger>(params);
76 for (
size_t mod = 0; mod < setup2D.
modules.size(); mod++) {
82 const double* tra_ptr =
module.translation.data();
83 const double* rot_ptr =
module.rotation.data();
84 params.
translation = ROOT::Math::XYZVector(tra_ptr[0], tra_ptr[1], tra_ptr[2]);
85 params.
rotation = ROOT::Math::Rotation3D(&rot_ptr[0], &rot_ptr[9]);
86 params.
address =
module.address;
90 for (
size_t row = 0; row < module.
rowPar.size(); row++) {
94 for (
size_t col = 0; col < rowPar.
padPar.size(); col++) {
98 const double* pos_ptr = pad.
position.data();
100 padPar.
pos = ROOT::Math::XYZVector(pos_ptr[0], pos_ptr[1], pos_ptr[2]);
101 padPar.
posErr = ROOT::Math::XYZVector(posErr_ptr[0], posErr_ptr[1], posErr_ptr[2]);
107 fHitFind2d[module.
address] = std::make_unique<cbm::algo::trd::HitFinder2D>(params);
114 L_(info) <<
"--- Configured hitfinder algorithms for TRD.";
132 constexpr bool DebugCheckInput =
true;
136 auto& hitsOut = std::get<0>(result);
137 auto& monitor = std::get<1>(result);
140 std::vector<std::vector<std::vector<std::pair<CbmTrdDigi, int32_t>>>> digiBuffer;
144 std::vector<std::vector<hitDataType>> hitBuffer;
148 for (
size_t mod = 0; mod <
fModList.size(); mod++) {
149 const size_t numRows = std::get<2>(
fModList[mod]);
150 digiBuffer[mod].resize(numRows);
155 xpu::push_timer(
"DigiModuleSort");
156 for (
size_t idigi = 0; idigi < digiIn.size(); idigi++) {
159 if constexpr (DebugCheckInput) {
161 std::find_if(
fModList.begin(),
fModList.end(), [&](
auto m) { return std::get<0>(m) == address; });
163 L_(error) <<
"TRD: Unknown module ID";
166 bool digiIs2D = digi->
IsFASP();
167 if (std::get<1>(*modInfo) != digiIs2D) {
168 L_(error) <<
"TRD: Module + Digi type mismatch: " << std::get<0>(*modInfo) <<
": " << std::get<1>(*modInfo)
173 const size_t modId =
fModId[address];
174 const size_t numCols = std::get<3>(
fModList[modId]);
176 digiBuffer[modId][row].emplace_back(*digi, idigi);
178 monitor.sortTime = xpu::pop_timer();
186 std::vector<size_t> hitsPrefix;
187 std::vector<size_t> sizePrefix;
188 std::vector<size_t> addrPrefix;
190 xpu::push_timer(
"BuildHits");
191 xpu::t_add_bytes(digiIn.size_bytes());
200 hitsPrefix.resize(nthreads + 1);
201 sizePrefix.resize(nthreads + 1);
202 addrPrefix.resize(nthreads + 1);
207 for (
size_t row = 0; row <
fRowList.size(); row++) {
208 const int address = std::get<0>(
fRowList[row]);
209 const bool is2D = std::get<1>(
fRowList[row]);
210 const size_t rowInMod = std::get<2>(
fRowList[row]);
211 const size_t modId =
fModId[address];
212 const auto& digiInput = digiBuffer[modId][rowInMod];
215 hitBuffer[row] = (*
fHitFind2d[address])(&clusters);
219 hitBuffer[row] = (*
fHitFind[address])(&clusters);
225 for (
size_t row = 0; row <
fRowList.size() / 2; row++) {
226 const size_t row1 = 2 * row;
227 const size_t row2 = 2 * row + 1;
228 const int address = std::get<0>(
fRowList[row1]);
229 const bool is2D = std::get<1>(
fRowList[row1]);
234 std::tie(hitBuffer[row1], hitBuffer[row2]) = (*
fHitMerge2d[address])(hitBuffer[row1], hitBuffer[row2]);
237 std::tie(hitBuffer[row1], hitBuffer[row2]) = (*
fHitMerge[address])(hitBuffer[row1], hitBuffer[row2]);
243 for (
size_t row = 0; row <
fRowList.size() / 2; row++) {
244 const size_t row1 = 2 * row + 1;
245 const size_t row2 = 2 * row + 2;
249 const int address = std::get<0>(
fRowList[row1]);
250 const bool is2D = std::get<1>(
fRowList[row1]);
251 if (std::get<0>(
fRowList[row2]) != address) {
255 std::tie(hitBuffer[row1], hitBuffer[row2]) = (*
fHitMerge2d[address])(hitBuffer[row1], hitBuffer[row2]);
258 std::tie(hitBuffer[row1], hitBuffer[row2]) = (*
fHitMerge[address])(hitBuffer[row1], hitBuffer[row2]);
262 std::vector<Hit> local_hits;
263 std::vector<size_t> local_sizes;
264 std::vector<uint> local_addresses;
267 CBM_OMP(
for schedule(dynamic) nowait)
268 for (
size_t row = 0; row <
fRowList.size(); row++) {
269 const int address = std::get<0>(
fRowList[row]);
270 auto&
hits = hitBuffer[row];
271 std::vector<Hit> row_hits;
272 std::transform(
hits.begin(),
hits.end(), std::back_inserter(row_hits), [](
const auto& p) { return p.first; });
275 local_sizes.push_back(row_hits.size());
278 local_addresses.push_back(address);
281 local_hits.insert(local_hits.end(), std::make_move_iterator(row_hits.begin()),
282 std::make_move_iterator(row_hits.end()));
285 hitsPrefix[ithread + 1] = local_hits.size();
286 sizePrefix[ithread + 1] = local_sizes.size();
287 addrPrefix[ithread + 1] = local_addresses.size();
291 for (
int i = 1; i < (nthreads + 1); i++) {
292 hitsPrefix[i] += hitsPrefix[i - 1];
293 sizePrefix[i] += sizePrefix[i - 1];
294 addrPrefix[i] += addrPrefix[i - 1];
296 hitsFlat.resize(hitsPrefix[nthreads]);
297 rowSizes.resize(sizePrefix[nthreads]);
298 rowAddresses.resize(addrPrefix[nthreads]);
300 std::move(local_hits.begin(), local_hits.end(), hitsFlat.begin() + hitsPrefix[ithread]);
301 std::move(local_sizes.begin(), local_sizes.end(), rowSizes.begin() + sizePrefix[ithread]);
302 std::move(local_addresses.begin(), local_addresses.end(), rowAddresses.begin() + addrPrefix[ithread]);
306 monitor.timeHitfind = xpu::pop_timer();
307 monitor.numDigis = digiIn.size();
308 monitor.numHits = hitsFlat.size();
315 for (
size_t i = 0; i < hitsOut.NPartitions(); i++) {
316 auto part = hitsOut[i];
317 std::sort(part.begin(), part.end(), [](
const auto& h0,
const auto& h1) { return h0.Time() < h1.Time(); });
328 constexpr bool DebugCheckInput =
true;
332 auto& hitsOut = std::get<0>(result);
333 auto& monitor = std::get<1>(result);
336 std::unordered_map<int, std::vector<std::vector<std::pair<CbmTrdDigi, int32_t>>>> digiBuffer;
339 std::unordered_map<int, std::vector<std::vector<hitDataType>>> hitBuffer;
342 for (
size_t mod = 0; mod <
fModList.size(); mod++) {
343 const int address = std::get<0>(
fModList[mod]);
344 const size_t numRows = std::get<2>(
fModList[mod]);
345 digiBuffer[address].resize(numRows);
346 hitBuffer[address].resize(numRows);
351 xpu::push_timer(
"DigiModuleSort");
352 for (
size_t idigi = 0; idigi < digiIn.size(); idigi++) {
355 if constexpr (DebugCheckInput) {
357 std::find_if(
fModList.begin(),
fModList.end(), [&](
auto m) { return std::get<0>(m) == address; });
359 L_(error) <<
"TRD: Unknown module ID";
362 bool digiIs2D = digi->
IsFASP();
363 if (std::get<1>(*modInfo) != digiIs2D) {
364 L_(error) <<
"TRD: Module + Digi type mismatch: " << std::get<0>(*modInfo) <<
": " << std::get<1>(*modInfo)
369 const size_t modId =
fModId[address];
370 const size_t numCols = std::get<3>(
fModList[modId]);
372 digiBuffer[address][row].emplace_back(*digi, idigi);
374 monitor.sortTime = xpu::pop_timer();
376 xpu::push_timer(
"BuildClusters");
377 xpu::t_add_bytes(digiIn.size_bytes());
381 for (
size_t row = 0; row <
fRowList.size(); row++) {
382 const int address = std::get<0>(
fRowList[row]);
383 const bool is2D = std::get<1>(
fRowList[row]);
384 const size_t rowInMod = std::get<2>(
fRowList[row]);
385 const auto& digiInput = digiBuffer[address][rowInMod];
388 hitBuffer[address][rowInMod] = (*
fHitFind2d[address])(&clusters);
392 hitBuffer[address][rowInMod] = (*
fHitFind[address])(&clusters);
396#ifdef PREPROCESS_BY_ROW
399 for (
size_t row = 0; row <
fRowList.size() / 2; row++) {
400 const size_t row1 = 2 * row;
401 const size_t row2 = 2 * row + 1;
402 const int address = std::get<0>(
fRowList[row1]);
403 const bool is2D = std::get<1>(
fRowList[row1]);
404 const size_t rowInMod1 = std::get<2>(
fRowList[row1]);
405 const size_t rowInMod2 = std::get<2>(
fRowList[row2]);
406 auto&
buffer = hitBuffer[address];
421 for (
size_t row = 0; row <
fRowList.size() / 2; row++) {
422 const size_t row1 = 2 * row + 1;
423 const size_t row2 = 2 * row + 2;
427 const int address = std::get<0>(
fRowList[row1]);
428 const bool is2D = std::get<1>(
fRowList[row1]);
429 if (std::get<0>(
fRowList[row2]) != address) {
432 const size_t rowInMod1 = std::get<2>(
fRowList[row1]);
433 const size_t rowInMod2 = std::get<2>(
fRowList[row2]);
434 auto&
buffer = hitBuffer[address];
444 monitor.timeClusterize = xpu::pop_timer();
452 std::vector<size_t> hitsPrefix;
453 std::vector<size_t> sizePrefix;
454 std::vector<size_t> addrPrefix;
456 xpu::push_timer(
"FindHits");
467 hitsPrefix.resize(nthreads + 1);
468 sizePrefix.resize(nthreads + 1);
469 addrPrefix.resize(nthreads + 1);
472 std::vector<Hit> local_hits;
473 std::vector<size_t> local_sizes;
474 std::vector<uint> local_addresses;
476 CBM_OMP(
for schedule(dynamic) nowait)
477 for (
size_t mod = 0; mod <
fModList.size(); mod++) {
478 const int address = std::get<0>(
fModList[mod]);
479 const bool is2D = std::get<1>(
fModList[mod]);
482 auto concatVec = [](
auto& acc,
const auto& innerVec) {
483 acc.insert(acc.end(), innerVec.begin(), innerVec.end());
484 return std::move(acc);
489 auto& hitbuffer = hitBuffer[address];
490 auto hitData = std::accumulate(hitbuffer.begin(), hitbuffer.end(), std::vector<hitDataType>(), concatVec);
492 std::vector<hitDataType> mod_hitdata;
493 std::vector<hitDataType> dummy;
495 mod_hitdata = (*
fHitMerge2d[address])(hitData, dummy).first;
498 mod_hitdata = (*
fHitMerge[address])(hitData, dummy).first;
502 std::vector<Hit> mod_hits;
503 std::transform(mod_hitdata.begin(), mod_hitdata.end(), std::back_inserter(mod_hits),
504 [](
const auto& p) { return p.first; });
507 local_sizes.push_back(mod_hits.size());
510 local_addresses.push_back(address);
513 local_hits.insert(local_hits.end(), std::make_move_iterator(mod_hits.begin()),
514 std::make_move_iterator(mod_hits.end()));
517 hitsPrefix[ithread + 1] = local_hits.size();
518 sizePrefix[ithread + 1] = local_sizes.size();
519 addrPrefix[ithread + 1] = local_addresses.size();
523 for (
int i = 1; i < (nthreads + 1); i++) {
524 hitsPrefix[i] += hitsPrefix[i - 1];
525 sizePrefix[i] += sizePrefix[i - 1];
526 addrPrefix[i] += addrPrefix[i - 1];
528 hitsFlat.resize(hitsPrefix[nthreads]);
529 modSizes.resize(sizePrefix[nthreads]);
530 modAddresses.resize(addrPrefix[nthreads]);
532 std::move(local_hits.begin(), local_hits.end(), hitsFlat.begin() + hitsPrefix[ithread]);
533 std::move(local_sizes.begin(), local_sizes.end(), modSizes.begin() + sizePrefix[ithread]);
534 std::move(local_addresses.begin(), local_addresses.end(), modAddresses.begin() + addrPrefix[ithread]);
537 monitor.timeHitfind = xpu::pop_timer();
538 monitor.numDigis = digiIn.size();
539 monitor.numHits = hitsFlat.size();
546 for (
size_t i = 0; i < hitsOut.NPartitions(); i++) {
547 auto part = hitsOut[i];
548 std::sort(part.begin(), part.end(), [](
const auto& h0,
const auto& h1) { return h0.Time() < h1.Time(); });