CbmRoot
Loading...
Searching...
No Matches
DigiEventSelector.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Shreya Roy [committer], Pierre-Alain Loizeau, Norbert Herrmann, Volker Friese, Dominik Smith */
4
5#include "DigiEventSelector.h"
6
8#include "CbmStsDigi.h"
9
10#include <gsl/span>
11#include <iterator>
12#include <unordered_map>
13#include <unordered_set>
14
15
16namespace cbm::algo::evbuild
17{
18
19 // ----- Test one digi event --------------------------------------------
21 {
22
23 // --- Test number of digis per detector system
24 for (auto& entry : fConfig.fMinNumDigis) {
25 if (!(event.Size(entry.first) >= entry.second)) {
26 return false;
27 break;
28 }
29 }
30
31 // --- Test number of layers with digis per detector system
32 for (auto& entry : fConfig.fMinNumLayers) {
33 if (entry.second == 0) continue;
34 switch (entry.first) {
36 if (!CheckStsStations(event.fSts, entry.second)) return false;
37 break;
39 if (!CheckTofLayers(event.fTof, entry.second)) return false;
40 break;
41 default:
42 throw std::runtime_error("Number of layers for " + ::ToString(entry.first) + " is not implemented");
43 break;
44 }
45 }
46
47 return true;
48 }
49 // --------------------------------------------------------------------------
50
51
52 // ----- Check number of STS stations -----------------------------------
53 bool DigiEventSelector::CheckStsStations(gsl::span<const CbmStsDigi> digis, size_t minNum) const
54 {
55
56 // A station is considered activated if it has at least one activated module. A module is considered
57 // activated if it has at least one digi on each of the sensor sides.
58 const uint16_t chanPerSide = 1024;
59 std::unordered_set<uint32_t> stations; // active stations
60 std::unordered_map<int32_t, bool> modules; // active modules, value false means front side hit, true is back side
61
62 for (auto& digi : digis) {
63 const int32_t addr = digi.GetAddress();
64 auto module = modules.find(addr);
65 if (module == modules.end())
66 modules[addr] = digi.GetChannel() / chanPerSide; // = 0,1 for sides
67 else {
68 if (digi.GetChannel() / chanPerSide != module->second) { // other sensor side found, chance for cluster
69 const uint32_t stationAddr = CbmStsAddress::GetElementId(addr, EStsElementLevel::kStsUnit);
70 if (stations.count(stationAddr) == 0) {
71 stations.insert(stationAddr);
72 if (stations.size() == minNum) break;
73 }
74 }
75 }
76 }
77
78 if (stations.size() < minNum)
79 return false;
80 else
81 return true;
82 }
83 // TODO: (VF 14/07/23) I do not like this implementation very much. It is mCBM-specific in the sense
84 // that what actually is checked are the units, not the stations. Only for mCBM geometries, stations
85 // and units are identical. Moreover, I feel that the association of digis (addresses) to stations
86 // should be implemented in the STS geometry handler, like for TOF in the method below.
87 // And the number of channels per sensor side is hard-coded here. Not nice.
88 // --------------------------------------------------------------------------
89
90
91 // ----- Check number of TOF layers -------------------------------------
92 bool DigiEventSelector::CheckTofLayers(gsl::span<const CbmTofDigi> digis, size_t minNum) const
93 {
94 // A station is considered activated if it has at least one activated RPC. An RPC is considered
95 // activated if it has at least one activated strip. A strip is considered activated
96 // if it has digis on each side.
97 std::unordered_set<int32_t> rpcs; // active RPCs (address)
98 std::unordered_set<int32_t> stations; // active TOF stations
99 std::unordered_map<int32_t, bool> strips; // active strips
100 for (auto& digi : digis) {
101 const int32_t digiAddr = digi.GetAddress();
102 const int32_t stripAddr = CbmTofAddress::GetStripFullId(digiAddr);
103
104 auto strip = strips.find(stripAddr);
105 if (strip == strips.end())
106 strips[stripAddr] = digi.GetSide();
107 else {
108 if (digi.GetSide() != strip->second) { // Found other end => full strip, insert into counter set
109 const int32_t rpcAddr = CbmTofAddress::GetRpcFullId(digiAddr);
110 if (rpcs.count(rpcAddr) == 0) { // new RPC activated
111 const int32_t TofStationId = fpTrackingSetup->GetTrackingStation<fles::Subsystem::TOF>(digiAddr);
112 if (TofStationId < 0) {
113 continue;
114 } // unused tracking station (BMON)
115 stations.insert(TofStationId);
116 if (stations.size() == minNum) break;
117 }
118 }
119 }
120 }
121
122 if (stations.size() < minNum)
123 return false;
124 else
125 return true;
126 }
127 // --------------------------------------------------------------------------
128
129
130 // ----- Info to string -------------------------------------------------
131 std::string DigiEventSelector::ToString() const
132 {
133 std::stringstream out;
134 out << "--- Using DigiEventSelector with";
135 out << (fConfig.IsEmpty() ? " no selection criteria" : " selection criteria: ");
136 if (!fConfig.fMinNumDigis.empty()) {
137 out << "\n min. digis : ";
138 for (const auto& entry : fConfig.fMinNumDigis)
139 out << ::ToString(entry.first) << " " << entry.second << " ";
140 }
141 if (!fConfig.fMinNumLayers.empty()) {
142 out << "\n min. layers: ";
143 for (const auto& entry : fConfig.fMinNumLayers)
144 out << ::ToString(entry.first) << " " << entry.second << " ";
145 }
146 return out.str();
147 }
148 // --------------------------------------------------------------------------
149
150} // namespace cbm::algo::evbuild
@ kTof
Time-of-flight Detector.
@ kSts
Silicon Tracking System.
@ kStsUnit
static int32_t GetStripFullId(uint32_t address)
static int32_t GetRpcFullId(uint32_t address)
bool IsEmpty() const
Presence of selection criteria.
std::map< ECbmModuleId, size_t > fMinNumLayers
Key: detector, value: Minimal number of layers.
std::map< ECbmModuleId, size_t > fMinNumDigis
Key: detector, value: minimal number of digis.
DigiEventSelectorConfig fConfig
Configuration / parameters.
bool operator()(const DigiEvent &event) const
Test one event for the selection criteria.
std::shared_ptr< TrackingSetup > fpTrackingSetup
Tracking setup (access to stations info)
bool CheckStsStations(gsl::span< const CbmStsDigi > digis, size_t minNum) const
Test for the number of STS stations.
bool CheckTofLayers(gsl::span< const CbmTofDigi > digis, size_t minNum) const
Test for the number of TOF layers.
std::string ToString() const
Info to string.
uint32_t GetElementId(int32_t address, int32_t level)
Get the index of an element.
PODVector< CbmStsDigi > fSts
Unpacked STS digis.
Definition DigiData.h:32
PODVector< CbmTofDigi > fTof
Unpacked TOF digis.
Definition DigiData.h:34
size_t Size(ECbmModuleId system) const
Get the number of digis for a given subsystem.
Definition DigiData.cxx:27
Event data with event number and trigger time.
Definition DigiData.h:79