34 std::map<Int_t, std::tuple<Double_t, Double_t>> localPixelCoord{};
44 Int_t currentPixelAddress{0};
45 Int_t currentPmtId{0};
48 Double_t pmtHeight{5.2};
49 Double_t pmtWidth{5.2};
50 TGeoVolume* pmtVolume = gGeoManager->FindVolumeFast(
"pmt");
51 if (!pmtVolume) pmtVolume = gGeoManager->FindVolumeFast(
"pmt_vol_0");
53 auto shape =
static_cast<const TGeoBBox*
>(pmtVolume->GetShape());
55 pmtHeight = 2. *
shape->GetDY();
56 pmtWidth = 2. *
shape->GetDX();
60 const TString pixelNameStr{
"pmt_pixel"};
62 TGeoIterator geoIterator{gGeoManager->GetTopNode()->GetVolume()};
63 geoIterator.SetTopName(
"/cave_1");
65 TGeoNode* curNode{
nullptr};
66 while ((curNode = geoIterator())) {
67 if (!TString(curNode->GetVolume()->GetName()).Contains(pixelNameStr))
continue;
69 const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix();
70 const Double_t* curNodeTr = curMatrix->GetTranslation();
71 const TGeoMatrix* localMatrix = curNode->GetMatrix();
74 geoIterator.GetPath(nodePath);
78 auto vPos = nodePath.Index(
"rich_v");
79 if (vPos != TString::kNPOS) {
80 auto versionStr = std::string(nodePath.Data() + vPos + 6, 2);
81 int version = std::stoi(versionStr);
85 const std::string path = std::string(nodePath.Data());
86 auto pmtInd = path.find_last_of(
'/');
87 if (std::string::npos == pmtInd)
continue;
88 std::string pmtPath = path.substr(0, pmtInd + 1);
95 currentPixelAddress++;
99 LOG(error) <<
"CbmRichGeoHandler::Init: CbmRichGeoHandler::CreateAddressRich failed!";
104 LOG(error) <<
"CbmRichGeoHandler::Init: CbmRichGeoHandler::CreateAddressMiniRich failed!";
108 default: LOG(error) <<
"ERROR: Could not identify Detector setup!";
break;
113 auto pixelData = std::make_unique<CbmRichPixelData>();
114 pixelData->fX = curNodeTr[0];
115 pixelData->fY = curNodeTr[1];
116 pixelData->fZ = curNodeTr[2];
117 pixelData->fAddress = currentPixelAddress;
118 localPixelCoord[currentPixelAddress] =
119 std::make_tuple(localMatrix->GetTranslation()[0], localMatrix->GetTranslation()[1]);
124 fPmtPathToId.insert(std::pair<std::string, Int_t>(pmtPath, currentPmtId));
125 auto pmtData = std::make_unique<CbmRichPmtData>();
126 pmtData->fId = currentPmtId;
127 pmtData->fPixelAddresses.push_back(pixelData->fAddress);
128 pmtData->fHeight = pmtHeight;
129 pmtData->fWidth = pmtWidth;
130 pixelData->fPmtId = pmtData->fId;
132 fPmtIds.push_back(pmtData->fId);
133 fPmtIdToData.insert(std::make_pair(pmtData->fId, std::move(pmtData)));
138 if (!pmtData || pmtId != pmtData->fId) LOG(error) <<
"(!pmtData || pmtId != pmtData->fId) ";
139 pmtData->fPixelAddresses.push_back(pixelData->fAddress);
140 pixelData->fPmtId = pmtData->fId;
141 if (pmtData->fPixelAddresses.size() > 64) {
142 LOG(info) <<
"size:" << pmtData->fPixelAddresses.size() <<
" pmtData->fId:" << pmtData->fId
143 <<
" pmtPath:" << pmtPath << std::endl
153 auto pmtData = pmt.second.get();
157 for (
int pixelId : pmtData->fPixelAddresses) {
159 if (!pixelData)
continue;
160 pmtData->fX += pixelData->fX;
161 pmtData->fY += pixelData->fY;
162 pmtData->fZ += pixelData->fZ;
164 Double_t nPixels =
static_cast<Double_t
>(pmtData->fPixelAddresses.size());
165 pmtData->fX /= nPixels;
166 pmtData->fY /= nPixels;
167 pmtData->fZ /= nPixels;
172 auto pmtData = pmt.second.get();
173 std::vector<std::tuple<CbmRichPixelData*, Double_t, Double_t>> pixelsInPmt{};
174 for (
int pixelAddress : pmtData->fPixelAddresses) {
176 if (!pixelData)
continue;
177 pixelsInPmt.emplace_back(std::make_tuple(pixelData, std::get<0>(localPixelCoord[pixelAddress]),
178 std::get<1>(localPixelCoord[pixelAddress])));
182 pixelsInPmt.begin(), pixelsInPmt.end(),
183 [](std::tuple<CbmRichPixelData*, Double_t, Double_t> a, std::tuple<CbmRichPixelData*, Double_t, Double_t> b) {
184 return (std::get<2>(a) > std::get<2>(b))
185 || ((std::abs(std::get<2>(a) - std::get<2>(b)) <= 0.3) && (std::get<1>(a) < std::get<1>(b)));
191 if (pixelsInPmt.size() != 64) {
192 LOG(error) <<
"ERROR: Calculating local pixel indices failed, number of pixels in PMT is not 64. "
193 << pmtData->ToString();
195 for (std::size_t i = 0; i < pixelsInPmt.size(); i++) {
196 std::get<0>(pixelsInPmt[i])->fPixelId =
static_cast<Int_t>(i);
200 localPixelCoord.clear();
202 LOG(info) <<
"CbmRichGeoHandler is initialized";
206 LOG(info) <<
"fPmtPathToId.size() = " <<
fPmtPathToId.size();
207 LOG(info) <<
"fPmtIdToData.size() = " <<
fPmtIdToData.size();
234 std::vector<Int_t> neighbourPixels{};
235 if (n == 0)
return neighbourPixels;
240 for (
const auto& iAddr : pmtPixelAddresses) {
241 if (iAddr == address)
continue;
245 if (horizontal && !vertical && !diagonal && n == 1) {
246 if (abs(iIndX - indX) == 1 && abs(iIndY - indY) == 0) neighbourPixels.push_back(iAddr);
248 else if (vertical && !horizontal && !diagonal && n == 1) {
249 if (abs(iIndX - indX) == 0 && abs(iIndY - indY) == 1) neighbourPixels.push_back(iAddr);
251 else if (!horizontal && !vertical && diagonal && n == 1) {
252 if ((abs(iIndX - indX) == 1) && (abs(iIndY - indY) == 1)) neighbourPixels.push_back(iAddr);
254 else if (horizontal && vertical && !diagonal && n == 1) {
255 if ((abs(iIndX - indX) + abs(iIndY - indY)) == 1) neighbourPixels.push_back(iAddr);
257 else if (horizontal && vertical && diagonal) {
258 if ((abs(iIndX - indX) <= n) && (abs(iIndY - indY) <= n)) neighbourPixels.push_back(iAddr);
261 LOG(error) <<
"ERROR: Unrecogniced option in CbmRichGeoHandler::GetNeighbourPixels " << std::endl
262 <<
" n = " << n <<
" horizontal = " << horizontal <<
" vertical = " << vertical
263 <<
" diagonal = " << diagonal;
266 return neighbourPixels;
275 auto pmtPixelInd = nodePath.find_last_of(
'/');
276 if (std::string::npos == pmtPixelInd)
return 1;
279 auto pixelUnderscore = nodePath.find_last_of(
'_');
280 if (std::string::npos == pixelUnderscore)
return 1;
281 uint32_t pixelId = std::stoul(nodePath.substr(pixelUnderscore + 1)) - 1;
284 auto pmtContInd = nodePath.rfind(
'/', pmtPixelInd - 1);
285 uint32_t pmt = std::stoul(nodePath.substr(pmtContInd + 5, pmtPixelInd - pmtContInd - 5)) - 1;
286 if (std::string::npos == pmtContInd)
return 1;
289 auto backplaneInd = nodePath.rfind(
'/', pmtContInd - 1);
290 uint32_t backplane = std::stoul(nodePath.substr(backplaneInd + 15, pmtContInd - backplaneInd - 15)) - 1;
291 if (std::string::npos == backplaneInd)
return 1;
294 auto stripInd = nodePath.rfind(
'/', backplaneInd - 1);
295 uint32_t strip = std::stoul(nodePath.substr(stripInd + 14, backplaneInd - stripInd - 14)) - 1;
296 if (std::string::npos == stripInd)
return 1;
299 auto cameraInd = nodePath.rfind(
'/', stripInd - 1);
300 uint32_t camera = std::stoul(nodePath.substr(cameraInd + 13, stripInd - cameraInd - 13)) - 1;
301 if (std::string::npos == cameraInd)
return 1;
311 auto pmtInd = nodePath.find_last_of(
'/');
312 if (std::string::npos == pmtInd)
return 1;
314 Int_t channel =
static_cast<Int_t>(std::stoul(nodePath.substr(pmtInd + 11)));
315 Int_t posAtPmt = channel / 100;
316 channel = channel % 100;
318 auto pmtVolInd = nodePath.rfind(
'/', pmtInd - 1);
319 if (std::string::npos == pmtVolInd)
return 1;
321 std::stoul(nodePath.substr(pmtVolInd + 11,
322 pmtInd - pmtVolInd - 11)));
324 auto bpInd = nodePath.rfind(
'/', pmtVolInd - 1);
325 if (std::string::npos == bpInd)
return 1;
327 std::stoul(nodePath.substr(bpInd + 14,
328 pmtVolInd - bpInd - 14)));
330 Int_t x = (posBP / 10) + ((((pmtPosBP - 1) / 3) + 1) % 2);
331 Int_t y = (posBP % 10) + (2 - ((pmtPosBP - 1) % 3));
333 Int_t DiRICH_Add = ((7 & 0xF) << 12) + ((
x & 0xF) << 8) + ((
y & 0xF) << 4) + (posAtPmt & 0xF);
334 Int_t pixelUID = ((DiRICH_Add << 16) | (channel & 0x00FF));
335 Int_t pmtUID = ((
x & 0xF) << 4) + (
y & 0xF);
337 channelAddr = pixelUID;