CbmRoot
Loading...
Searching...
No Matches
CbmRichDigiMapManager.cxx
Go to the documentation of this file.
1/* Copyright (C) 2015-2024 GSI/JINR-LIT, Darmstadt/Dubna
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Semen Lebedev, Martin Beyer, Adrian Amatus Weber, Andrey Lebedev [committer], Florian Uhlig */
4
5/*
6 * CbmRichDigiMapManager.cxx
7 *
8 * Created on: Dec 17, 2015
9 * Author: slebedev
10 */
12
13#include "CbmRichDetectorData.h" // for CbmRichPmtData, CbmRichPixelData
14
15#include <Logger.h> // for LOG, Logger
16
17#include <TGeoBBox.h> // for TGeoBBox
18#include <TGeoManager.h> // for TGeoManager, gGeoManager
19#include <TGeoMatrix.h> // for TGeoMatrix
20#include <TGeoNode.h> // for TGeoIterator, TGeoNode
21#include <TGeoVolume.h> // for TGeoVolume
22#include <TRandom.h> // for TRandom, gRandom
23
24#include <string> // for operator<, stoul
25#include <tuple> // for tuple, make_tuple, get
26#include <utility> // for pair
27
28#include <stddef.h> // for size_t
29
30using namespace std;
31
33 : fPixelPathToAddressMap()
34 , fPixelAddressToDataMap()
35 , fPixelAddresses()
36 , fPmtPathToIdMap()
37 , fPmtIdToDataMap()
38 , fPmtIds()
39{
40 Init();
41}
42
44
46{
47 // temporary map storing local x and y coordinates of pixels in its PMT volume
48 std::map<Int_t, tuple<Double_t, Double_t>> localPixelCoord;
49
52 fPixelAddresses.clear();
53
54 fPmtPathToIdMap.clear();
55 fPmtIdToDataMap.clear();
56 fPmtIds.clear();
57
58 Int_t currentPixelAddress = 1;
59 Int_t currentPmtId = 1;
60
61 // Get MAPMT dimensions
62 Double_t pmtHeight = 5.2;
63 Double_t pmtWidth = 5.2;
64 TGeoVolume* pmtVolume = gGeoManager->FindVolumeFast("pmt");
65 if (pmtVolume == nullptr) pmtVolume = gGeoManager->FindVolumeFast("pmt_vol_0");
66 if (pmtVolume != nullptr) {
67 const TGeoBBox* shape = (const TGeoBBox*) (pmtVolume->GetShape());
68 if (shape != nullptr) {
69 pmtHeight = 2. * shape->GetDY();
70 pmtWidth = 2. * shape->GetDX();
71 }
72 }
73
74 TGeoIterator geoIterator(gGeoManager->GetTopNode()->GetVolume());
75 geoIterator.SetTopName("/cave_1");
76 TGeoNode* curNode;
77 // PMT plane position\rotation
78 TString pixelNameStr("pmt_pixel");
79 geoIterator.Reset();
80 while ((curNode = geoIterator())) {
81 TString nodeName(curNode->GetName());
82 TString nodePath;
83 if (TString(curNode->GetVolume()->GetName()).Contains(pixelNameStr)) {
84 geoIterator.GetPath(nodePath);
85
86 int detSetup = getDetectorSetup(nodePath);
87 switch (detSetup) {
88 case 0: {
89 // RICH detector
90 //std::cout<<"RICH"<<std::endl;
91 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
92 const Double_t* curNodeTr = curMatrix->GetTranslation();
93 const TGeoMatrix* localMatrix = curNode->GetMatrix(); // local transformation of pixel in MAPMT volume
94 string path = string(nodePath.Data());
95
96 size_t pmtInd = path.find_last_of("/");
97 if (string::npos == pmtInd) continue;
98 string pmtPath = path.substr(0, pmtInd + 1);
99
100 fPixelPathToAddressMap.insert(pair<string, Int_t>(path, currentPixelAddress));
101 CbmRichPixelData* pixelData = new CbmRichPixelData();
102 pixelData->fX = curNodeTr[0];
103 pixelData->fY = curNodeTr[1];
104 pixelData->fZ = curNodeTr[2];
105 pixelData->fAddress = currentPixelAddress;
106 localPixelCoord[currentPixelAddress] =
107 make_tuple(localMatrix->GetTranslation()[0], localMatrix->GetTranslation()[1]);
108 fPixelAddressToDataMap.insert(pair<Int_t, CbmRichPixelData*>(pixelData->fAddress, pixelData));
109 fPixelAddresses.push_back(currentPixelAddress);
110 currentPixelAddress++;
111
112 if (fPmtPathToIdMap.count(pmtPath) == 0) {
113 fPmtPathToIdMap.insert(pair<string, Int_t>(pmtPath, currentPmtId));
114
115 CbmRichPmtData* pmtData = new CbmRichPmtData();
116 pmtData->fId = currentPmtId;
117 pmtData->fPixelAddresses.push_back(pixelData->fAddress);
118 pmtData->fHeight = pmtHeight;
119 pmtData->fWidth = pmtWidth;
120 fPmtIdToDataMap.insert(pair<Int_t, CbmRichPmtData*>(pmtData->fId, pmtData));
121 pixelData->fPmtId = pmtData->fId;
122
123 fPmtIds.push_back(pmtData->fId);
124
125 currentPmtId++;
126 }
127 else {
128 //cout << "pmtPath old:" << pmtPath << endl;
129 Int_t pmtId = fPmtPathToIdMap[pmtPath];
130 CbmRichPmtData* pmtData = fPmtIdToDataMap[pmtId];
131 if (pmtData == nullptr || pmtId != pmtData->fId) {
132 LOG(error) << "(pmtData == nullptr || pmtId != pmtData->fId) ";
133 }
134 pmtData->fPixelAddresses.push_back(pixelData->fAddress);
135 pixelData->fPmtId = pmtData->fId;
136 if (pmtData->fPixelAddresses.size() > 64) {
137 LOG(info) << "size:" << pmtData->fPixelAddresses.size() << " pmtData->fId:" << pmtData->fId
138 << " pmtPath:" << pmtPath << endl
139 << " path:" << path;
140 }
141 }
142 } break;
143
144 case 1: {
145 //std::cout<<"mRICH"<<std::endl;
146 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
147 const Double_t* curNodeTr = curMatrix->GetTranslation();
148 const TGeoMatrix* localMatrix = curNode->GetMatrix(); // local transformation of pixel in MAPMT volume
149 string path = string(nodePath.Data());
150
151 size_t pmtInd = path.find_last_of("/");
152 if (string::npos == pmtInd) continue;
153 string pmtPath = path.substr(0, pmtInd + 1);
154
155 Int_t channel = std::stoul(path.substr(pmtInd + 11)); // cut away "pmt_pixel_"
156 Int_t posAtPmt = channel / 100;
157 channel = channel % 100;
158
159 size_t pmtVolInd = path.rfind("/", pmtInd - 1);
160 if (string::npos == pmtVolInd) continue;
161 Int_t pmtPosBP = std::stoul(path.substr(pmtVolInd + 11,
162 pmtInd - pmtVolInd - 11)); // cut away "/pmt_vol_*_" ; position on BP
163
164 size_t bpInd = path.rfind("/", pmtVolInd - 1);
165 if (string::npos == bpInd) continue;
166 Int_t posBP = std::stoul(path.substr(bpInd + 14,
167 pmtVolInd - bpInd - 14)); // cut away "/pmt_cont_vol_" ; position on BP
168
169 Int_t x = (posBP / 10) + ((((pmtPosBP - 1) / 3) + 1) % 2);
170 Int_t y = (posBP % 10) + (2 - ((pmtPosBP - 1) % 3));
171
172 Int_t DiRICH_Add = ((7 & 0xF) << 12) + ((x & 0xF) << 8) + ((y & 0xF) << 4) + (posAtPmt & 0xF);
173 Int_t pixelUID = ((DiRICH_Add << 16) | (channel & 0x00FF));
174 Int_t pmtUID = ((x & 0xF) << 4) + (y & 0xF);
175 //std::cout<<"Addr: 0x"<< std::hex << DiRICH_Add << std::dec << "\t" << channel <<"\t"<< std::hex << pixelUID << std::dec << std::endl;
176
177 fPixelPathToAddressMap.insert(pair<string, Int_t>(path, pixelUID));
178 CbmRichPixelData* pixelData = new CbmRichPixelData();
179 pixelData->fX = curNodeTr[0];
180 pixelData->fY = curNodeTr[1];
181 pixelData->fZ = curNodeTr[2];
182 pixelData->fAddress = pixelUID;
183 localPixelCoord[pixelUID] = make_tuple(localMatrix->GetTranslation()[0], localMatrix->GetTranslation()[1]);
184 fPixelAddressToDataMap.insert(pair<Int_t, CbmRichPixelData*>(pixelData->fAddress, pixelData));
185 fPixelAddresses.push_back(pixelUID);
186 //currentPixelAddress++;
187
188 if (fPmtPathToIdMap.count(pmtPath) == 0) {
189 fPmtPathToIdMap.insert(pair<string, Int_t>(pmtPath, pmtUID));
190
191 CbmRichPmtData* pmtData = new CbmRichPmtData();
192 pmtData->fId = pmtUID;
193 pmtData->fPixelAddresses.push_back(pixelData->fAddress);
194 pmtData->fHeight = pmtHeight;
195 pmtData->fWidth = pmtWidth;
196 fPmtIdToDataMap.insert(pair<Int_t, CbmRichPmtData*>(pmtData->fId, pmtData));
197 pixelData->fPmtId = pmtData->fId;
198
199 fPmtIds.push_back(pmtData->fId);
200 }
201 else {
202 //cout << "pmtPath old:" << pmtPath << endl;
203 Int_t pmtId = fPmtPathToIdMap[pmtPath];
204 CbmRichPmtData* pmtData = fPmtIdToDataMap[pmtId];
205 if (pmtData == nullptr || pmtId != pmtData->fId) {
206 LOG(error) << "(pmtData == nullptr || pmtId != pmtData->fId) ";
207 }
208 pmtData->fPixelAddresses.push_back(pixelData->fAddress);
209 pixelData->fPmtId = pmtData->fId;
210 if (pmtData->fPixelAddresses.size() > 64) {
211 LOG(info) << "size:" << pmtData->fPixelAddresses.size() << " pmtData->fId:" << pmtData->fId
212 << " pmtPath:" << pmtPath << endl
213 << " path:" << path;
214 }
215 }
216
217 } break;
218
219 default: LOG(error) << "ERROR: Could not identify Detector setup!"; break;
220 }
221 }
222 }
223
224 // calculate Pmt center as center of gravity of 64 pixels
225 for (auto const& pmt : fPmtIdToDataMap) {
226 // Int_t pmtId = pmt.first;
227 CbmRichPmtData* pmtData = pmt.second;
228 pmtData->fX = 0.;
229 pmtData->fY = 0.;
230 pmtData->fZ = 0.;
231 for (int pixelId : pmtData->fPixelAddresses) {
232 CbmRichPixelData* pixelData = fPixelAddressToDataMap[pixelId];
233 if (pixelData == nullptr) continue;
234 pmtData->fX += pixelData->fX;
235 pmtData->fY += pixelData->fY;
236 pmtData->fZ += pixelData->fZ;
237 }
238 pmtData->fX /= pmtData->fPixelAddresses.size();
239 pmtData->fY /= pmtData->fPixelAddresses.size();
240 pmtData->fZ /= pmtData->fPixelAddresses.size();
241 }
242
243 // calculate fPixelId for each pixel by sorting x and y translation inside PMT volume
244 for (auto const& pmt : fPmtIdToDataMap) {
245 CbmRichPmtData* pmtData = pmt.second;
246 std::vector<tuple<CbmRichPixelData*, Double_t, Double_t>> pixelsInPmt;
247 for (int pixelAddress : pmtData->fPixelAddresses) {
248 CbmRichPixelData* pixelData = fPixelAddressToDataMap[pixelAddress];
249 if (pixelData == nullptr) continue;
250 pixelsInPmt.push_back(
251 make_tuple(pixelData, get<0>(localPixelCoord[pixelAddress]), get<1>(localPixelCoord[pixelAddress])));
252 }
253
254 std::sort(
255 pixelsInPmt.begin(), pixelsInPmt.end(),
256 [](tuple<CbmRichPixelData*, Double_t, Double_t> a, tuple<CbmRichPixelData*, Double_t, Double_t> b) {
257 return (get<2>(a) > get<2>(b)) || ((abs(get<2>(a) - get<2>(b)) <= 0.3) && (get<1>(a) < get<1>(b)));
258 // first sort by y (up to down) coordinate, then by x (left to right) coordinate
259 // stop sorting by y when y coordinate difference is less than 0.3 (to start sorting by x when y is the "same")
260 // needed because edge/corner pixels are slightly larger
261 });
262
263 if (pixelsInPmt.size() != 64) {
264 LOG(error) << "ERROR: Calculating local pixel indices failed, number of pixels in PMT is not 64. "
265 << pmtData->ToString();
266 }
267 for (unsigned int i = 0; i < pixelsInPmt.size(); i++) {
268 get<0>(pixelsInPmt[i])->fPixelId = i;
269 }
270 }
271
272 localPixelCoord.clear();
273
274 LOG(info) << "CbmRichDigiMapManager is initialized";
275 LOG(info) << "fPixelPathToAddressMap.size() = " << fPixelPathToAddressMap.size();
276 LOG(info) << "fPixelAddressToDataMap.size() = " << fPixelAddressToDataMap.size();
277
278 LOG(info) << "fPmtPathToIdMap.size() = " << fPmtPathToIdMap.size();
279 LOG(info) << "fPmtIdToDataMap.size() = " << fPmtIdToDataMap.size();
280
281 // for (auto const& pmt : fPmtIdToDataMap) {
282 // // cout << pmt.first << endl;
283 // cout << pmt.second->ToString() << endl;
284 // }
285}
286
288{
289 std::map<string, Int_t>::iterator it;
290 it = fPixelPathToAddressMap.find(path);
291 if (it == fPixelPathToAddressMap.end()) return -1;
292 return it->second;
293}
294
295
297{
298 std::map<Int_t, CbmRichPixelData*>::iterator it;
299 it = fPixelAddressToDataMap.find(address);
300 if (it == fPixelAddressToDataMap.end()) return nullptr;
301 return it->second;
302}
303
305{
306 Int_t nofPixels = fPixelAddresses.size();
307 Int_t index = gRandom->Integer(nofPixels);
308 return fPixelAddresses[index];
309}
310
312
313
314vector<Int_t> CbmRichDigiMapManager::GetPmtIds() { return fPmtIds; }
315
316
318{
319 std::map<Int_t, CbmRichPmtData*>::iterator it;
320 it = fPmtIdToDataMap.find(id);
321 if (it == fPmtIdToDataMap.end()) return nullptr;
322 return it->second;
323}
324
325vector<Int_t> CbmRichDigiMapManager::GetNeighbourPixels(Int_t address, Int_t n, Bool_t horizontal, Bool_t vertical,
326 Bool_t diagonal)
327{
328 vector<Int_t> neighbourPixels;
329 if (n == 0) return neighbourPixels;
330 CbmRichPixelData* addressPixelData = GetPixelDataByAddress(address);
331 Int_t indX = addressPixelData->fPixelId % 8;
332 Int_t indY = addressPixelData->fPixelId / 8;
333 vector<Int_t> pmtPixelAddresses = GetPmtDataById(addressPixelData->fPmtId)->fPixelAddresses;
334 for (auto const& iAddr : pmtPixelAddresses) {
335 if (iAddr == address) continue;
336 CbmRichPixelData* iPixelData = GetPixelDataByAddress(iAddr);
337 Int_t iIndX = iPixelData->fPixelId % 8;
338 Int_t iIndY = iPixelData->fPixelId / 8;
339 if (horizontal && !vertical && !diagonal && n == 1) { // direct horizontal neighbours
340 if (abs(iIndX - indX) == 1 && abs(iIndY - indY) == 0) neighbourPixels.push_back(iAddr);
341 }
342 else if (vertical && !horizontal && !diagonal && n == 1) { // direct vertical neighbours
343 if (abs(iIndX - indX) == 0 && abs(iIndY - indY) == 1) neighbourPixels.push_back(iAddr);
344 }
345 else if (!horizontal && !vertical && diagonal && n == 1) { // diagonal neighbours
346 if ((abs(iIndX - indX) == 1) && (abs(iIndY - indY) == 1)) neighbourPixels.push_back(iAddr);
347 }
348 else if (horizontal && vertical && !diagonal && n == 1) { // direct horizontal and vertical neighbours
349 if ((abs(iIndX - indX) + abs(iIndY - indY)) == 1) neighbourPixels.push_back(iAddr);
350 }
351 else if (horizontal && vertical && diagonal) { // all neighbours in (2N+1)*(2N+1) grid
352 if ((abs(iIndX - indX) <= n) && (abs(iIndY - indY) <= n)) neighbourPixels.push_back(iAddr);
353 }
354 else {
355 LOG(error) << "ERROR: Unrecogniced option in CbmRichDigiMapManager::GetNeighbourPixels " << endl
356 << " n = " << n << " horizontal = " << horizontal << " vertical = " << vertical
357 << " diagonal = " << diagonal;
358 }
359 }
360 return neighbourPixels;
361}
362
364{
365 //identify Detector by nodePath:
366 // 0: RICH
367 // 1: mRICH
368 bool check = nodePath.Contains("mcbm");
369 if (check) {
370 //mRICH
371 return 1;
372 }
373 else {
374 //RICH
375 return 0;
376 }
377
378 return 0;
379}
std::map< std::string, Int_t > fPmtPathToIdMap
std::vector< Int_t > fPmtIds
std::vector< Int_t > GetNeighbourPixels(Int_t address, Int_t N, Bool_t horizontal=true, Bool_t vertical=true, Bool_t diagonal=true)
Return the addresses of the neighbour pixels.
void Init()
Initialize maps.
int getDetectorSetup(TString const nodePath)
std::vector< Int_t > GetPmtIds()
Return ids for all pmts.
std::vector< Int_t > fPixelAddresses
std::map< Int_t, CbmRichPixelData * > fPixelAddressToDataMap
Int_t GetRandomPixelAddress()
Return random address. Needed for noise digi.
std::map< std::string, Int_t > fPixelPathToAddressMap
std::vector< Int_t > GetPixelAddresses()
Return addresses of all pixels.
CbmRichPixelData * GetPixelDataByAddress(Int_t address)
Return CbmRichDataPixel by digi address.
CbmRichPmtData * GetPmtDataById(Int_t id)
Return CbmRichDataPmt by id.
std::map< Int_t, CbmRichPmtData * > fPmtIdToDataMap
Int_t GetPixelAddressByPath(const std::string &path)
Return digi address by path to node.
std::string ToString()
std::vector< Int_t > fPixelAddresses
Hash for CbmL1LinkKey.