diff --git a/core/detectors/rich/CbmRichDetectorData.h b/core/detectors/rich/CbmRichDetectorData.h index 8800dd7a35e21a885fc88f0286ec2e3496d2d947..41179c4b06e701977b7f12b1457c87b1ed2c18f9 100644 --- a/core/detectors/rich/CbmRichDetectorData.h +++ b/core/detectors/rich/CbmRichDetectorData.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2020 GSI/JINR-LIT, Darmstadt/Dubna +/* Copyright (C) 2015-2023 GSI/JINR-LIT, Darmstadt/Dubna SPDX-License-Identifier: GPL-3.0-only Authors: Semen Lebedev, Andrey Lebedev [committer], Florian Uhlig */ @@ -21,9 +21,10 @@ class CbmRichPixelData { public: Int_t fAddress; - Double_t fX; - Double_t fY; - Double_t fZ; + Double_t fX; // global x coordinate + Double_t fY; // global y coordinate + Double_t fZ; // global z coordinate + Int_t fPixelId; // pixel index [0, 63] row major, view from -z to z Int_t fPmtId; }; diff --git a/core/detectors/rich/CbmRichDigiMapManager.cxx b/core/detectors/rich/CbmRichDigiMapManager.cxx index 8b41e9650254bc4705085e9bd975eac5e25914f3..087740cbdf0408f3674e2f401488262011db1dc9 100644 --- a/core/detectors/rich/CbmRichDigiMapManager.cxx +++ b/core/detectors/rich/CbmRichDigiMapManager.cxx @@ -1,6 +1,6 @@ -/* Copyright (C) 2015-2020 GSI/JINR-LIT, Darmstadt/Dubna +/* Copyright (C) 2015-2023 GSI/JINR-LIT, Darmstadt/Dubna SPDX-License-Identifier: GPL-3.0-only - Authors: Semen Lebedev, Adrian Amatus Weber, Andrey Lebedev [committer], Florian Uhlig */ + Authors: Semen Lebedev, Martin Beyer, Adrian Amatus Weber, Andrey Lebedev [committer], Florian Uhlig */ /* * CbmRichDigiMapManager.cxx @@ -22,6 +22,7 @@ #include <TRandom.h> // for TRandom, gRandom #include <string> // for operator<, stoul +#include <tuple> // for tuple, make_tuple, get #include <utility> // for pair #include <stddef.h> // for size_t @@ -43,6 +44,8 @@ CbmRichDigiMapManager::~CbmRichDigiMapManager() {} void CbmRichDigiMapManager::Init() { + // temporary map storing local x and y coordinates of pixels in its PMT volume + std::map<Int_t, tuple<Double_t, Double_t>> localPixelCoord; fPixelPathToAddressMap.clear(); fPixelAddressToDataMap.clear(); @@ -87,6 +90,7 @@ void CbmRichDigiMapManager::Init() //std::cout<<"RICH"<<std::endl; const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix(); const Double_t* curNodeTr = curMatrix->GetTranslation(); + const TGeoMatrix* localMatrix = curNode->GetMatrix(); // local transformation of pixel in MAPMT volume string path = string(nodePath.Data()); size_t pmtInd = path.find_last_of("/"); @@ -99,6 +103,8 @@ void CbmRichDigiMapManager::Init() pixelData->fY = curNodeTr[1]; pixelData->fZ = curNodeTr[2]; pixelData->fAddress = currentPixelAddress; + localPixelCoord[currentPixelAddress] = + make_tuple(localMatrix->GetTranslation()[0], localMatrix->GetTranslation()[1]); fPixelAddressToDataMap.insert(pair<Int_t, CbmRichPixelData*>(pixelData->fAddress, pixelData)); fPixelAddresses.push_back(currentPixelAddress); currentPixelAddress++; @@ -139,6 +145,7 @@ void CbmRichDigiMapManager::Init() //std::cout<<"mRICH"<<std::endl; const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix(); const Double_t* curNodeTr = curMatrix->GetTranslation(); + const TGeoMatrix* localMatrix = curNode->GetMatrix(); // local transformation of pixel in MAPMT volume string path = string(nodePath.Data()); size_t pmtInd = path.find_last_of("/"); @@ -157,7 +164,7 @@ void CbmRichDigiMapManager::Init() size_t bpInd = path.rfind("/", pmtVolInd - 1); if (string::npos == bpInd) continue; Int_t posBP = std::stoul(path.substr(bpInd + 14, - pmtVolInd - bpInd - 14)); // cut away "/pmt_vol_*_" ; position on BP + pmtVolInd - bpInd - 14)); // cut away "/pmt_cont_vol_" ; position on BP Int_t x = (posBP / 10) + ((((pmtPosBP - 1) / 3) + 1) % 2); Int_t y = (posBP % 10) + (2 - ((pmtPosBP - 1) % 3)); @@ -173,6 +180,7 @@ void CbmRichDigiMapManager::Init() pixelData->fY = curNodeTr[1]; pixelData->fZ = curNodeTr[2]; pixelData->fAddress = pixelUID; + localPixelCoord[pixelUID] = make_tuple(localMatrix->GetTranslation()[0], localMatrix->GetTranslation()[1]); fPixelAddressToDataMap.insert(pair<Int_t, CbmRichPixelData*>(pixelData->fAddress, pixelData)); fPixelAddresses.push_back(pixelUID); //currentPixelAddress++; @@ -232,6 +240,37 @@ void CbmRichDigiMapManager::Init() pmtData->fZ /= pmtData->fPixelAddresses.size(); } + // calculate fPixelId for each pixel by sorting x and y translation inside PMT volume + for (auto const& pmt : fPmtIdToDataMap) { + CbmRichPmtData* pmtData = pmt.second; + std::vector<tuple<CbmRichPixelData*, Double_t, Double_t>> pixelsInPmt; + for (int pixelAddress : pmtData->fPixelAddresses) { + CbmRichPixelData* pixelData = fPixelAddressToDataMap[pixelAddress]; + if (pixelData == nullptr) continue; + pixelsInPmt.push_back( + make_tuple(pixelData, get<0>(localPixelCoord[pixelAddress]), get<1>(localPixelCoord[pixelAddress]))); + } + + std::sort( + pixelsInPmt.begin(), pixelsInPmt.end(), + [](tuple<CbmRichPixelData*, Double_t, Double_t> a, tuple<CbmRichPixelData*, Double_t, Double_t> b) { + return (get<2>(a) > get<2>(b)) || ((abs(get<2>(a) - get<2>(b)) <= 0.3) && (get<1>(a) < get<1>(b))); + // first sort by y (up to down) coordinate, then by x (left to right) coordinate + // stop sorting by y when y coordinate difference is less than 0.3 (to start sorting by x when y is the "same") + // needed because edge/corner pixels are slightly larger + }); + + if (pixelsInPmt.size() != 64) { + LOG(error) << "ERROR: Calculating local pixel indices failed, number of pixels in PMT is not 64. " + << pmtData->ToString(); + } + for (unsigned int i = 0; i < pixelsInPmt.size(); i++) { + get<0>(pixelsInPmt[i])->fPixelId = i; + } + } + + localPixelCoord.clear(); + LOG(info) << "CbmRichDigiMapManager is initialized"; LOG(info) << "fPixelPathToAddressMap.size() = " << fPixelPathToAddressMap.size(); LOG(info) << "fPixelAddressToDataMap.size() = " << fPixelAddressToDataMap.size(); @@ -283,18 +322,33 @@ CbmRichPmtData* CbmRichDigiMapManager::GetPmtDataById(Int_t id) return it->second; } -vector<Int_t> CbmRichDigiMapManager::GetDirectNeighbourPixels(Int_t /*address*/) +vector<Int_t> CbmRichDigiMapManager::GetNeighbourPixels(Int_t address, Int_t N, Bool_t direct, Bool_t diagonal) { - std::vector<Int_t> v; - - return v; -} - -vector<Int_t> CbmRichDigiMapManager::GetDiagonalNeighbourPixels(Int_t /*address*/) -{ - std::vector<Int_t> v; - - return v; + vector<Int_t> neighbourPixels; + CbmRichPixelData* addressPixelData = GetPixelDataByAddress(address); + Int_t indX = addressPixelData->fPixelId % 8; + Int_t indY = addressPixelData->fPixelId / 8; + vector<Int_t> pmtPixelAddresses = GetPmtDataById(addressPixelData->fPmtId)->fPixelAddresses; + for (auto const& iAddr : pmtPixelAddresses) { + if (iAddr == address) continue; + CbmRichPixelData* iPixelData = GetPixelDataByAddress(iAddr); + Int_t iIndX = iPixelData->fPixelId % 8; + Int_t iIndY = iPixelData->fPixelId / 8; + if (direct && !diagonal && N == 1) { // direct neighbours + if ((abs(iIndX - indX) + abs(iIndY - indY)) == 1) neighbourPixels.push_back(iAddr); + } + else if (!direct && diagonal && N == 1) { // diagonal neighbours + if ((abs(iIndX - indX) == 1) && (abs(iIndY - indY) == 1)) neighbourPixels.push_back(iAddr); + } + else if (direct && diagonal) { // all neighbours in (2N+1)*(2N+1) grid + if ((abs(iIndX - indX) <= N) && (abs(iIndY - indY) <= N)) neighbourPixels.push_back(iAddr); + } + else { + LOG(error) << "ERROR: Unrecogniced option in CbmRichDigiMapManager::GetNeighbourPixels " << endl + << " N = " << N << " direct = " << direct << " diagonal = " << diagonal; + } + } + return neighbourPixels; } int CbmRichDigiMapManager::getDetectorSetup(TString const nodePath) diff --git a/core/detectors/rich/CbmRichDigiMapManager.h b/core/detectors/rich/CbmRichDigiMapManager.h index 4c64a82038afc097a5494eee86bebdf4b53a5c55..54a6323b279d6cbc37db3f1708e9acb57933d7e5 100644 --- a/core/detectors/rich/CbmRichDigiMapManager.h +++ b/core/detectors/rich/CbmRichDigiMapManager.h @@ -1,6 +1,6 @@ -/* Copyright (C) 2015-2020 GSI/JINR-LIT, Darmstadt/Dubna +/* Copyright (C) 2015-2023 GSI/JINR-LIT, Darmstadt/Dubna SPDX-License-Identifier: GPL-3.0-only - Authors: Semen Lebedev, Andrey Lebedev [committer], Florian Uhlig */ + Authors: Semen Lebedev, Martin Beyer, Andrey Lebedev [committer], Florian Uhlig */ /* * CbmRichDigiMap.h @@ -28,8 +28,8 @@ private: public: /** - * Return Instance of CbmRichGeoManager. - */ + * Return Instance of CbmRichGeoManager. + */ static CbmRichDigiMapManager& GetInstance() { static CbmRichDigiMapManager fInstance; @@ -37,47 +37,60 @@ public: } /* - * \brief Return digi address by path to node. - */ + * \brief Return digi address by path to node. + */ Int_t GetPixelAddressByPath(const std::string& path); /* - * \brief Return CbmRichDataPixel by digi address. - */ + * \brief Return CbmRichDataPixel by digi address. + */ CbmRichPixelData* GetPixelDataByAddress(Int_t address); /* - * \brief Return the addresses of the direct neighbour pixels. - * C++11 efficient way to return vector - */ - std::vector<Int_t> GetDirectNeighbourPixels(Int_t address); + * \brief Return random address. Needed for noise digi. + */ + Int_t GetRandomPixelAddress(); /* - * \brief Return the addresses of the diagonal neighbour pixels. - * C++11 efficient way to return vector - */ - std::vector<Int_t> GetDiagonalNeighbourPixels(Int_t address); + * \brief Return addresses of all pixels + */ + std::vector<Int_t> GetPixelAddresses(); /* - * \brief Return random address. Needed for noise digi. - */ - Int_t GetRandomPixelAddress(); + * \brief Return ids for all pmts + */ + std::vector<Int_t> GetPmtIds(); + /* + * \brief Return CbmRichDataPmt by id. + */ + CbmRichPmtData* GetPmtDataById(Int_t id); /* - * \brief Return addresses of all pixels - */ - std::vector<Int_t> GetPixelAddresses(); + * \brief Return the addresses of the neighbour pixels. + */ + std::vector<Int_t> GetNeighbourPixels(Int_t address, Int_t N, Bool_t direct = true, Bool_t diagonal = true); /* - * \brief Return ids for all pmts - */ - std::vector<Int_t> GetPmtIds(); + * \brief Return the addresses of the direct neighbour pixels. + */ + std::vector<Int_t> GetDirectNeighbourPixels(Int_t address) { return GetNeighbourPixels(address, 1, true, false); } /* - * \brief Return CbmRichDataPmt by id. - */ - CbmRichPmtData* GetPmtDataById(Int_t id); + * \brief Return the addresses of the diagonal neighbour pixels. + */ + std::vector<Int_t> GetDiagonalNeighbourPixels(Int_t address) { return GetNeighbourPixels(address, 1, false, true); } + + /* + * \brief Return the addresses of pixels in a (2N+1)*(2N+1) grid, + * with the address pixel in the center of the grid. + * Addresses are limited to the same MAPMT as the input address. + * Needed for noise digis caused by charged particles. + */ + std::vector<Int_t> GetNxNNeighbourPixels(Int_t address, Int_t N) + { + return GetNeighbourPixels(address, N, true, true); + } public: virtual ~CbmRichDigiMapManager(); @@ -94,18 +107,18 @@ private: int getDetectorSetup(TString const nodePath); /* - * \brief Initialize maps. - */ + * \brief Initialize maps. + */ void Init(); /** - * \brief Copy constructor. - */ + * \brief Copy constructor. + */ CbmRichDigiMapManager(const CbmRichDigiMapManager&); /** - * \brief Assignment operator. - */ + * \brief Assignment operator. + */ CbmRichDigiMapManager& operator=(const CbmRichDigiMapManager&); };