BmnRoot 26.10.0-210-gc52d34b0
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnRun9DM.h
Go to the documentation of this file.
1/*
2 BM@N alignment routine
3 BM@N experiment at NICA complex, JINR, 2025
4
5 Department: Math & Soft Group of HEP lab
6 Author: Igor Polev, polev@jinr.int
7
8 BmnRun9DM class declaration
9 Run9 representation of detector elements via encoding
10*/
11
12#ifndef BMNRUN9DM_H
13#define BMNRUN9DM_H
14
15#include "BmnDetectorList.h"
16#include "BmnDetectorModel.h"
17
18#include <TString.h>
19#include <numeric>
20
21/*
22 * Detector elements enumeration scheme
23 *
24 * SystemID - fixed constatns defined in BmnDetectorList.h
25 * StationID - sequence across all systems starting from 0 or 1 (currently 1)
26 * ModuleID - separate sequence for each station starting from 0 or 1 (currently 1)
27 *
28 * CbmStsHit DetectorID layout:
29 *
30 * 27:24 ( 4 bit) System ID
31 * 23:16 ( 8 bit) Station number
32 * 15:4 (12 bit) Sector (module) number
33 * 3:1 ( 3 bit) Sensor number (not used, allways 0b001)
34 * 0:0 ( 1 bit) Unknown (not used, allways 0b0)
35 * --------------
36 * 28 bit in total
37 *
38 * See CbmStsHit.h and BmnToCbmHitConverter::Exec()
39 *
40 * A zero module count in VSP_MODULES / SIL_MODULES / GEM_MODULES marks a
41 * station left out of the model: it gets no elements, and its hits are
42 * ignored, see IgnoreHit(). Its station number stays unused, so the element
43 * IDs are still the CbmStsHit DetectorIDs. The marker works on whole stations
44 * only: the elements of a station must have contiguous module numbers.
45 *
46 * The target (TRG) closes the sequence as one more element, see TargetID(),
47 * unless the model is built without it. It is last so that the element
48 * indices of the stations, which config files address, are the same with and
49 * without it.
50 */
51
53{
54 protected:
56 const Bool_t fWithTarget{kTRUE}; // the target element closes the sequence
57
58 enum
59 {
62 };
63 // Run9 configuration definition
66 TRG_SYSTEM_ID{DetectorId::kREF}, // no STS hit carries it, and it fits the 4-bit field
69 STA_NUM_START{1}, // first station number (0 or 1)
70 MOD_NUM_START{1}, // first module number for each station (0 or 1)
71 // stations have one common index range, VSP first, then silicons, then GEMs
76 GEM_MODULES[GEM_STATION_CNT]{8, 8, 8, 8, 8, 8, 8, 0};
77 // A GEM "module" here is one zone (sector) of a configuration module,
78 // cold and hot zones alternate, see LoadGeometry(). The last station
79 // has a single zone, but registers no hits in Run9 data: left out.
80
81 // module count of the station at the given 0-based station index, zero for a station left out.
82 // CAUTION: the index is not checked.
83 inline Int_t StationModules(Int_t station) const noexcept
84 {
85 if (station < VSP_STATION_CNT)
86 return VSP_MODULES[station];
87 if (station < VSP_STATION_CNT + SIL_STATION_CNT)
88 return SIL_MODULES[station - VSP_STATION_CNT];
90 }
91 // of those, the ones aligned independently. This is the single per-station
92 // primitive Alignables() and MaxModulesInStation() are built from, so a
93 // model keeping fewer elements per station restates it here alone.
94 virtual Int_t StationAlignables(Int_t station) const noexcept { return StationModules(station); }
95 // module number the station's alignable sequence starts at
96 virtual Int_t FirstModule(Int_t /*station*/) const noexcept { return MOD_NUM_START; }
97 // 0-based, inclusive index range of stations this model enumerates. A
98 // subsystem-restricted model narrows it (e.g. GEM-only starts past silicon),
99 // and Reset()/NextID()/Alignables()/Composites() all honour it.
100 virtual Int_t FirstStation() const noexcept { return 0; }
101 virtual Int_t LastStation() const noexcept { return ALL_STATION_CNT - 1; }
102
103 // sensitive rectangles read from the Run9 XML configurations and the target
104 // read from its ASCII geometry file, see the .cxx
105 virtual Bool_t LoadGeometry(const char* targetGeoFile) override;
106
107 // detector modules enumeration: see base class
108 virtual void Reset() noexcept override
109 {
110 // must set iterator BEFORE the first module according to base class definition
111 const Int_t station{FirstStation()};
115 fStation = station + STA_NUM_START;
116 fModule = FirstModule(station) - 1;
117 }
118
119 virtual Int_t NextID() noexcept override
120 {
121 // out of range check
122 if (-1 == fSystem)
123 return -1; // EOF marker must be negative
124 // the target element was the last one
125 if (TRG_SYSTEM_ID == fSystem)
126 return fSystem = -1;
127
128 fModule++;
129
130 // Next station check. It is counted off the first module of the
131 // station's own sequence, so the test holds for a model keeping only a
132 // part of the station just as well as for the full one. A station with
133 // no elements meets the condition at once, so the loop passes it.
134 Int_t stationIdx{fStation - STA_NUM_START};
135 while (fModule - FirstModule(stationIdx) >= StationAlignables(stationIdx)) {
136 fStation++, stationIdx++;
137 // remember: stations has common enumeration across all systems
138
139 // past the last station the target, if any, closes the sequence
140 if (stationIdx > LastStation()) {
141 if (!fWithTarget)
142 return fSystem = -1;
144 return TargetID();
145 }
146
147 // next system check
150 else if (fStation > VSP_STATION_IDX[kLast])
152
153 fModule = FirstModule(stationIdx);
154 }
155
156 return (fSystem << 24) | (fStation << 16) | (fModule << 4) | 0b0010;
157 // constant term 0b0010 is used to match CbmStsHit DetectorID encoding
158 }
159
160 public:
161 virtual Int_t MaxModulesInStation() const noexcept override
162 {
163 Int_t cnt{0};
164 for (Int_t i = FirstStation(); i <= LastStation(); i++)
165 if (StationAlignables(i) > cnt)
166 cnt = StationAlignables(i);
167 return cnt;
168 }
169
170 virtual Int_t Alignables() const noexcept override
171 {
172 Int_t al{fWithTarget ? 1 : 0};
173 for (Int_t i = FirstStation(); i <= LastStation(); i++)
174 al += StationAlignables(i);
175 return al;
176 }
177
178 virtual Int_t TargetID() const noexcept override
179 {
180 return fWithTarget ? (TRG_SYSTEM_ID << 24) | (STA_NUM_START << 16) | (MOD_NUM_START << 4) | 0b0010 : -1;
181 }
182
183 // the element IDs are the CbmStsHit DetectorIDs themselves, see the layout above
184 virtual Int_t IDfromHit(Int_t CbmDetectorID) const noexcept override { return CbmDetectorID; }
185
186 // ATTENTION: A station number out of range is not checked.
187 // The hit is unknown to the model, but not ignored.
188 virtual Bool_t IgnoreHit(Int_t CbmDetectorID) const noexcept override
189 {
190 const Int_t station{((CbmDetectorID >> 16) & 0xFF) - STA_NUM_START};
191 return TRG_SYSTEM_ID != (CbmDetectorID >> 24) && station >= 0 && station < ALL_STATION_CNT
192 && StationModules(station) == 0;
193 }
194 virtual Bool_t IgnoresSome() const noexcept override
195 {
196 for (Int_t station = 0; station < ALL_STATION_CNT; station++)
197 if (0 == StationModules(station))
198 return kTRUE;
199 return kFALSE;
200 }
201
202 // the target is shown with its system name, REF
203 virtual std::string DecodeID(Int_t id) const override
204 {
205 TString system;
206 BmnDetectorList::GetSystemNameCaps(id >> 24, system);
207 return Form("%-7s st %2d mod %2d", system.Data(), (id >> 16) & 0xFF, (id >> 4) & 0xFFF);
208 }
209
210 virtual std::vector<Composite> Composites() const override
211 {
212 std::vector<Composite> nodes;
213 nodes.reserve(2 * (LastStation() - FirstStation() + 1));
214 for (Int_t station = FirstStation(), leaf = 0; station <= LastStation(); station++) {
215 const Int_t nodeSize{StationAlignables(station) / 2};
216 if (0 == nodeSize) { // left out, or a single module: no halves
217 leaf += StationAlignables(station);
218 continue;
219 }
220 Composite node;
221 node.leaves.resize(nodeSize);
222
223 // upper half of the station
224 node.name = Form("STA%02dU", station + STA_NUM_START);
225 std::iota(node.leaves.begin(), node.leaves.end(), leaf);
226 leaf += nodeSize;
227 nodes.push_back(node);
228
229 // lower half of the station
230 node.name = Form("STA%02dL", station + STA_NUM_START);
231 std::iota(node.leaves.begin(), node.leaves.end(), leaf);
232 leaf += nodeSize;
233 nodes.push_back(std::move(node));
234 }
235 return nodes;
236 }
237
238 // Without the target the data needs no SiBT beam branch, and a target
239 // geometry file given to Init() is read but describes no element.
240 explicit BmnRun9DM(Bool_t withTarget = kTRUE)
241 : fWithTarget{withTarget}
242 {
243 fDescription = withTarget ? "Run9 VSP, FSD, GEM zones all independent plus the target: 111 elements"
244 : "Run9 VSP, FSD, GEM zones all independent, no target: 110 elements";
245 }
246 virtual ~BmnRun9DM() override = default;
247};
248
249#endif // BMNRUN9DM_H
Defines unique identifiers (enum) for all BM@N detector systems.
@ kSILICON
@ kGEM
@ kVSP
@ kREF
int i
Definition P4_F32vec4.h:22
bool Bool_t
int Int_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
char * Form(const char *fmt,...)
static void GetSystemNameCaps(DetectorId det, TString &name)
Get system name in capitals.
BmnDetectorModel()=default
std::string fDescription
virtual Int_t TargetID() const noexcept override
Definition BmnRun9DM.h:178
BmnRun9DM(Bool_t withTarget=kTRUE)
Definition BmnRun9DM.h:240
virtual Int_t IDfromHit(Int_t CbmDetectorID) const noexcept override
Definition BmnRun9DM.h:184
virtual Int_t NextID() noexcept override
Definition BmnRun9DM.h:119
static constexpr const Int_t VSP_SYSTEM_ID
Definition BmnRun9DM.h:64
virtual Bool_t LoadGeometry(const char *targetGeoFile) override
Definition BmnRun9DM.cxx:42
static constexpr const Int_t MOD_NUM_START
Definition BmnRun9DM.h:70
static constexpr const Int_t STA_NUM_START
Definition BmnRun9DM.h:69
virtual std::vector< Composite > Composites() const override
Definition BmnRun9DM.h:210
Int_t fStation
Definition BmnRun9DM.h:55
static constexpr const Int_t GEM_STATION_CNT
Definition BmnRun9DM.h:67
virtual Int_t FirstModule(Int_t) const noexcept
Definition BmnRun9DM.h:96
virtual Int_t FirstStation() const noexcept
Definition BmnRun9DM.h:100
static constexpr const Int_t GEM_SYSTEM_ID
Definition BmnRun9DM.h:65
virtual Bool_t IgnoresSome() const noexcept override
Definition BmnRun9DM.h:194
static constexpr const Int_t SIL_SYSTEM_ID
Definition BmnRun9DM.h:64
static constexpr const Int_t GEM_MODULES[GEM_STATION_CNT]
Definition BmnRun9DM.h:76
virtual Bool_t IgnoreHit(Int_t CbmDetectorID) const noexcept override
Definition BmnRun9DM.h:188
static constexpr const Int_t TRG_SYSTEM_ID
Definition BmnRun9DM.h:66
static constexpr const Int_t ALL_STATION_CNT
Definition BmnRun9DM.h:68
Int_t StationModules(Int_t station) const noexcept
Definition BmnRun9DM.h:83
static constexpr const Int_t VSP_STATION_IDX[2]
Definition BmnRun9DM.h:72
virtual Int_t MaxModulesInStation() const noexcept override
Definition BmnRun9DM.h:161
virtual ~BmnRun9DM() override=default
Int_t fSystem
Definition BmnRun9DM.h:55
static constexpr const Int_t SIL_MODULES[SIL_STATION_CNT]
Definition BmnRun9DM.h:75
static constexpr const Int_t SIL_STATION_IDX[2]
Definition BmnRun9DM.h:73
static constexpr const Int_t GEM_STATION_IDX[2]
Definition BmnRun9DM.h:74
static constexpr const Int_t SIL_STATION_CNT
Definition BmnRun9DM.h:67
virtual Int_t LastStation() const noexcept
Definition BmnRun9DM.h:101
virtual std::string DecodeID(Int_t id) const override
Definition BmnRun9DM.h:203
virtual Int_t Alignables() const noexcept override
Definition BmnRun9DM.h:170
static constexpr const Int_t VSP_MODULES[VSP_STATION_CNT]
Definition BmnRun9DM.h:75
static constexpr const Int_t VSP_STATION_CNT
Definition BmnRun9DM.h:67
const Bool_t fWithTarget
Definition BmnRun9DM.h:56
virtual Int_t StationAlignables(Int_t station) const noexcept
Definition BmnRun9DM.h:94
virtual void Reset() noexcept override
Definition BmnRun9DM.h:108
Int_t fModule
Definition BmnRun9DM.h:55
const char * Data() const