diff --git a/algo/data/CMakeLists.txt b/algo/data/CMakeLists.txt index e684dc5462a4c9c6d81d6fc614a2392d7e5a7b84..eea39c14db2196d0152f4b17908fb5ec60182ce2 100644 --- a/algo/data/CMakeLists.txt +++ b/algo/data/CMakeLists.txt @@ -27,6 +27,10 @@ set(SRCS ${CMAKE_SOURCE_DIR}/core/data/psd/CbmPsdDigi.cxx ${CMAKE_SOURCE_DIR}/core/data/psd/CbmPsdAddress.cxx + ${CMAKE_SOURCE_DIR}/core/data/fsd/CbmFsdDigi.cxx + ${CMAKE_SOURCE_DIR}/core/data/fsd/CbmFsdAddress.cxx + + ${CMAKE_SOURCE_DIR}/core/data/raw/CriGet4Mess001.cxx ${CMAKE_SOURCE_DIR}/core/data/raw/StsXyterMessage.cxx ) @@ -43,6 +47,7 @@ target_include_directories(OnlineData PUBLIC ${CMAKE_SOURCE_DIR}/core/data/trd PUBLIC ${CMAKE_SOURCE_DIR}/core/data/tof PUBLIC ${CMAKE_SOURCE_DIR}/core/data/psd + PUBLIC ${CMAKE_SOURCE_DIR}/core/data/fsd PUBLIC ${CMAKE_SOURCE_DIR}/core/data/global PUBLIC ${CMAKE_SOURCE_DIR}/core/data/raw ) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index f83c7f001975f915de4c119c4227621758eb382e..7fa667426b023d1307b541fb9ed0f8921059f9b8 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -14,6 +14,7 @@ add_subdirectory(detectors/mvd) add_subdirectory(detectors/tof) add_subdirectory(detectors/sts) add_subdirectory(detectors/psd) +add_subdirectory(detectors/fsd) If(ROOT_opengl_FOUND) Message(STATUS "OpenGL support found. Build the eventdisplay.") diff --git a/core/base/CbmDigiManager.cxx b/core/base/CbmDigiManager.cxx index 75fe067181a9997f1f2ad09018ad489888a3d592..d47ba112474bf4e0d6af2a69aea624d687c314ca 100644 --- a/core/base/CbmDigiManager.cxx +++ b/core/base/CbmDigiManager.cxx @@ -11,6 +11,7 @@ #include "CbmBmonDigi.h" // for CbmBmonDigi #include "CbmDefs.h" // for kMuch #include "CbmDigiBranch.h" // for CbmDigiBranch +#include "CbmFsdDigi.h" // for CbmFsdDigi #include "CbmMuchBeamTimeDigi.h" // for CbmMuchBeamTimeDigi #include "CbmMuchDigi.h" // for CbmMuchDigi #include "CbmMvdDigi.h" // for CbmMvdDigi @@ -91,6 +92,7 @@ InitStatus CbmDigiManager::Init() SetBranch<CbmTrdDigi>(); SetBranch<CbmTofDigi>(); SetBranch<CbmPsdDigi>(); + SetBranch<CbmFsdDigi>(); SetBranch<CbmBmonDigi>(); LOG(info) << "Present branches:"; for (auto const& branch : fBranches) { diff --git a/core/base/CbmMatchRecoToMC.cxx b/core/base/CbmMatchRecoToMC.cxx index 3e11ab73f44d3136033124feaf2b2db85f1fdcde..a47936a52854ac99a2fc383f29999a9c24263dc1 100644 --- a/core/base/CbmMatchRecoToMC.cxx +++ b/core/base/CbmMatchRecoToMC.cxx @@ -111,6 +111,11 @@ CbmMatchRecoToMC::~CbmMatchRecoToMC() fTofHitMatches->Delete(); delete fTofHitMatches; } + + if (fFsdHitMatches != nullptr) { + fFsdHitMatches->Delete(); + delete fFsdHitMatches; + } } InitStatus CbmMatchRecoToMC::Init() @@ -121,7 +126,7 @@ InitStatus CbmMatchRecoToMC::Init() if (fbSuppressReMatching) { std::stringstream msg; msg << "\033[1;31mCbmMatchRecoToMC (\"" << fName << "\"): the cluster and hit matching routines for MVD, STS, "; - msg << "MuCh, TRD, TOF will be suppressed by a request from CbmMatchRecoToMC::SuppressHitMatching():\033[0m\n"; + msg << "MuCh, TRD, TOF, FSD will be suppressed by a request from CbmMatchRecoToMC::SuppressHitMatching():\033[0m\n"; LOG(warn) << msg.str(); } @@ -140,6 +145,7 @@ void CbmMatchRecoToMC::Exec(Option_t* /*opt*/) if (fMuchClusterMatches != nullptr) fMuchClusterMatches->Delete(); if (fMuchPixelHitMatches != nullptr) fMuchPixelHitMatches->Delete(); if (fTofHitMatches != nullptr) fTofHitMatches->Delete(); + if (fFsdHitMatches != nullptr) fFsdHitMatches->Delete(); } if (fTrdClusterMatches != nullptr) fTrdClusterMatches->Delete(); if (fStsTrackMatches != nullptr) fStsTrackMatches->Delete(); @@ -201,6 +207,14 @@ void CbmMatchRecoToMC::Exec(Option_t* /*opt*/) // TOF: (Digi->MC)+(Hit->Digi)=>(Hit->MC) if (!fbSuppressReMatching) { MatchHitsTof(fTofHitDigiMatches, fTofHits, fTofHitMatches); } + + // ----- FSD ----- + if (!fbSuppressReMatching) { + // FSD: digi->hit + if (fFsdHits && fFsdHitMatches) { MatchHitsFsd(fFsdHits, fFsdHitMatches); } + } + + //static Int_t eventNo = 0; LOG(info) << "CbmMatchRecoToMC::Exec eventNo=" << fEventNumber++; } @@ -419,6 +433,19 @@ void CbmMatchRecoToMC::ReadAndCreateDataBranches() else LOG(info) << "Found calibrated tof digi to point match vector in one of the input files"; } + + // FSD + fFsdPoints = mcManager->InitBranch("FsdPoint"); + + fFsdHits = static_cast<TClonesArray*>(ioman->GetObject("FsdHit")); + if (nullptr != fFsdHits) { + fFsdHitMatches = static_cast<TClonesArray*>(ioman->GetObject("FsdHitMatch")); + if (nullptr == fFsdHitMatches) { + fbSuppressReMatching = false; // Ensure, that matching is done, if matches are absent + fFsdHitMatches = new TClonesArray("CbmMatch", 100); + ioman->Register("FsdHitMatch", "FSD", fFsdHitMatches, IsOutputBranchPersistent("FsdHitMatch")); + } + } } @@ -506,6 +533,18 @@ void CbmMatchRecoToMC::MatchHitsMvd(const TClonesArray* hits, TClonesArray* hitM } } +void CbmMatchRecoToMC::MatchHitsFsd(const TClonesArray* hits, TClonesArray* hitMatches) +{ + if (!(hits && hitMatches)) return; + Int_t nofHits = hits->GetEntriesFast(); + for (Int_t iHit = 0; iHit < nofHits; iHit++) { + CbmPixelHit* hit = static_cast<CbmPixelHit*>(hits->At(iHit)); + CbmMatch* hitMatch = new ((*hitMatches)[iHit]) CbmMatch(); + const CbmMatch* digiMatch = fDigiManager->GetMatch(ECbmModuleId::kFsd, hit->GetRefId()); + hitMatch->AddLinks(*digiMatch); + } +} + void CbmMatchRecoToMC::MatchHitsTof(const TClonesArray* HitDigiMatches, const TClonesArray* hits, TClonesArray* hitMatches) { diff --git a/core/base/CbmMatchRecoToMC.h b/core/base/CbmMatchRecoToMC.h index b6867576962eb9ab51dbd54d4308ace889042cb1..e76b6abafe34f75ee1fc357364f4771cd8cf7092 100644 --- a/core/base/CbmMatchRecoToMC.h +++ b/core/base/CbmMatchRecoToMC.h @@ -101,6 +101,8 @@ private: void MatchHitsMvd(const TClonesArray* hits, TClonesArray* hitMatches); + void MatchHitsFsd(const TClonesArray* hits, TClonesArray* hitMatches); + void MatchHitsTof(const TClonesArray* HitDigiMatches, const TClonesArray* hits, TClonesArray* hitMatches); void MatchHitsToPoints(CbmMCDataArray* points, const TClonesArray* hits, TClonesArray* hitMatches); @@ -195,6 +197,10 @@ private: TClonesArray* fTofHitDigiMatches = nullptr; //! Match Hit -> Digi [out] TClonesArray* fTofHitMatches = nullptr; //! Match Hit -> MC point [out] + // FSD + CbmMCDataArray* fFsdPoints = nullptr; //! MC points [in] + TClonesArray* fFsdHits = nullptr; //! Hits [in] + TClonesArray* fFsdHitMatches = nullptr; //! Hit matches [out] CbmMatchRecoToMC(const CbmMatchRecoToMC&); CbmMatchRecoToMC& operator=(const CbmMatchRecoToMC&); diff --git a/core/config/CbmConfigBase.h b/core/config/CbmConfigBase.h index 8fb0706b5587e7d95b821aee71f99156f875347c..7d09363b9e55d8a4718816b5eae312b4252ef89b 100644 --- a/core/config/CbmConfigBase.h +++ b/core/config/CbmConfigBase.h @@ -117,11 +117,11 @@ public: static ECbmModuleId stringToECbmModuleId(std::string s) { std::map<std::string, ECbmModuleId> stringToModuleId = { - {"cave", ECbmModuleId::kCave}, {"magnet", ECbmModuleId::kMagnet}, {"pipe", ECbmModuleId::kPipe}, - {"target", ECbmModuleId::kTarget}, {"mvd", ECbmModuleId::kMvd}, {"sts", ECbmModuleId::kSts}, - {"rich", ECbmModuleId::kRich}, {"much", ECbmModuleId::kMuch}, {"trd", ECbmModuleId::kTrd}, - {"tof", ECbmModuleId::kTof}, {"psd", ECbmModuleId::kPsd}, {"hodo", ECbmModuleId::kHodo}, - {"shield", ECbmModuleId::kShield}, {"platform", ECbmModuleId::kPlatform}}; + {"cave", ECbmModuleId::kCave}, {"magnet", ECbmModuleId::kMagnet}, {"pipe", ECbmModuleId::kPipe}, + {"target", ECbmModuleId::kTarget}, {"mvd", ECbmModuleId::kMvd}, {"sts", ECbmModuleId::kSts}, + {"rich", ECbmModuleId::kRich}, {"much", ECbmModuleId::kMuch}, {"trd", ECbmModuleId::kTrd}, + {"tof", ECbmModuleId::kTof}, {"psd", ECbmModuleId::kPsd}, {"fsd", ECbmModuleId::kFsd}, + {"hodo", ECbmModuleId::kHodo}, {"shield", ECbmModuleId::kShield}, {"platform", ECbmModuleId::kPlatform}}; if (stringToModuleId.find(s) == stringToModuleId.end()) { LOG(error) << "CbmConfig: detector subsystem not recognized: " << s; std::cout << "list of available detector subsystems:\n"; diff --git a/core/data/CMakeLists.txt b/core/data/CMakeLists.txt index 4d1ee4e36b4543414e1e5a6950a5cb1c2e01dae4..568015be6d91590ce263c7cc7abf26646edf8408 100644 --- a/core/data/CMakeLists.txt +++ b/core/data/CMakeLists.txt @@ -14,6 +14,7 @@ set(INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/tof ${CMAKE_CURRENT_SOURCE_DIR}/rich ${CMAKE_CURRENT_SOURCE_DIR}/psd + ${CMAKE_CURRENT_SOURCE_DIR}/fsd ${CMAKE_CURRENT_SOURCE_DIR}/global ) @@ -100,6 +101,11 @@ set(SRCS psd/CbmPsdPoint.cxx psd/CbmPsdAddress.cxx psd/CbmPsdMCbmHit.cxx + + fsd/CbmFsdDigi.cxx + fsd/CbmFsdHit.cxx + fsd/CbmFsdPoint.cxx + fsd/CbmFsdAddress.cxx global/CbmGlobalTrack.cxx global/CbmVertex.cxx @@ -128,7 +134,7 @@ SET_SOURCE_FILES_PROPERTIES(tof/etof/star_rhicf.c PROPERTIES COMPILE_FLAGS -Wno- list(APPEND HEADERS base/CbmDigiData.h global/CbmDigiEvent.h global/CbmDigiTimeslice.h bmon/CbmBmonDigiData.h sts/CbmStsDigiData.h much/CbmMuchDigiData.h rich/CbmRichDigiData.h trd/CbmTrdDigiData.h -tof/CbmTofDigiData.h psd/CbmPsdDigiData.h) +tof/CbmTofDigiData.h psd/CbmPsdDigiData.h fsd/CbmFsdDigiData.h) set(LIBRARY_NAME CbmData) set(LINKDEF ${LIBRARY_NAME}LinkDef.h) @@ -157,6 +163,7 @@ Install(FILES bmon/CbmBmonDigiData.h much/CbmMuchDigiData.h psd/CbmPsdDigiData.h + fsd/CbmFsdDigiData.h rich/CbmRichDigiData.h rich/CbmRichRingLight.h sts/CbmStsDigiData.h trd/CbmTrdDigiData.h @@ -166,4 +173,3 @@ Install(FILES DESTINATION include ) - diff --git a/core/data/CbmDataLinkDef.h b/core/data/CbmDataLinkDef.h index 67b82b4b7cdbcc59eda1f7f82b94ef7da33465fc..4c0a08a60dd29c2e286e2a6ec69eb1b02ff34c0a 100644 --- a/core/data/CbmDataLinkDef.h +++ b/core/data/CbmDataLinkDef.h @@ -99,6 +99,12 @@ #pragma link C++ class CbmPsdAddress; #pragma link C++ class CbmPsdMCbmHit; +#pragma link C++ class CbmFsdDigi + ; +#pragma link C++ class CbmFsdDigiData + ; +#pragma link C++ class CbmFsdHit + ; +#pragma link C++ class CbmFsdPoint + ; +#pragma link C++ class CbmFsdAddress + ; + // --- data/global #pragma link C++ class CbmGlobalTrack + ; #pragma link C++ class CbmVertex + ; @@ -134,6 +140,7 @@ #pragma link C++ class vector < CbmBmonDigi> + ; #pragma link C++ class vector < CbmPsdDigi> + ; #pragma link C++ class vector < CbmPsdDsp> + ; +#pragma link C++ class vector < CbmFsdDigi> + ; #pragma link C++ class vector < CbmMatch> + ; #pragma link C++ class CbmDigiVector < CbmMvdDigi> + ; #pragma link C++ class CbmDigiVector < CbmStsDigi> + ; @@ -144,6 +151,7 @@ #pragma link C++ class CbmDigiVector < CbmTofDigi> + ; #pragma link C++ class CbmDigiVector < CbmPsdDigi> + ; #pragma link C++ class CbmDigiVector < CbmPsdDsp> + ; +#pragma link C++ class CbmDigiVector < CbmFsdDigi> + ; #pragma link C++ class vector < CbmEventStore> + ; #pragma link C++ class std::vector < CbmEvent> + ; diff --git a/core/data/CbmDefs.cxx b/core/data/CbmDefs.cxx index d5e6ec3e5397b1bd092bf3ab06342dce94fc8881..6e37c66c852c6aa1989093ba11c90610788f8cba 100644 --- a/core/data/CbmDefs.cxx +++ b/core/data/CbmDefs.cxx @@ -41,7 +41,7 @@ std::ostream& operator<<(std::ostream& strm, const ECbmModuleId& modId) } // conversion functions between ECbmModuleId and std::string -static const std::array<std::pair<ECbmModuleId, std::string>, 22> ModIdStrMap = { +static const std::array<std::pair<ECbmModuleId, std::string>, 23> ModIdStrMap = { {{ECbmModuleId::kRef, "Ref"}, {ECbmModuleId::kMvd, "Mvd"}, {ECbmModuleId::kSts, "Sts"}, @@ -55,6 +55,7 @@ static const std::array<std::pair<ECbmModuleId, std::string>, 22> ModIdStrMap = {ECbmModuleId::kDummyDet, "DummyDet"}, {ECbmModuleId::kT0, "T0"}, {ECbmModuleId::kTrd2d, "Trd2d"}, + {ECbmModuleId::kFsd, "Fsd"}, {ECbmModuleId::kNofSystems, "NofSystems"}, {ECbmModuleId::kMagnet, "Magnet"}, {ECbmModuleId::kTarget, "Target"}, diff --git a/core/data/CbmDefs.h b/core/data/CbmDefs.h index 64ddc7fcbf744f1c2d92fbd6a0a193803b3a6629..e77d04ccaf847f326a364d6de19d9619a0742d93 100644 --- a/core/data/CbmDefs.h +++ b/core/data/CbmDefs.h @@ -50,7 +50,8 @@ enum class ECbmModuleId kDummyDet = 10, ///< Dummy for tutorials or tests kT0 = 11, ///< ToF start Detector (FIXME) kTrd2d = 12, ///< TRD-FASP Detector (FIXME) - kNofSystems = 13, ///< For loops over active systems + kFsd = 13, ///< Forward spectator detector + kNofSystems = 14, ///< For loops over active systems kMagnet = 17, ///< Magnet kTarget = 18, ///< Target kPipe = 19, ///< Beam pipe @@ -126,6 +127,9 @@ enum class ECbmDataType kT0Digi, kT0CalDigi, kT0Hit, // T0 + kFsdPoint = ToIntegralType(ECbmModuleId::kFsd) * 100, + kFsdDigi, + kFsdHit, // Fsd kGlobalTrack = 2000 // Global }; diff --git a/core/data/CbmHit.h b/core/data/CbmHit.h index da47e229b301e7725e8dcb8307ac1f9c8c4db229..7fc5ca610cf797def843cde73c4b796d155d8220 100644 --- a/core/data/CbmHit.h +++ b/core/data/CbmHit.h @@ -29,7 +29,8 @@ enum HitType kMUCHSTRAWHIT, kTRDHIT, kTOFHIT, - kECALHIT + kECALHIT, + kFSDHIT }; #include <Rtypes.h> // for THashConsistencyHolder, ClassDef diff --git a/core/data/CbmMCTrack.cxx b/core/data/CbmMCTrack.cxx index 40066d4ccaaa0fd8aa94a0743dc30da4286aee72..06cfeeb6744d80e7a7711fc7f88ca7c1b949f6bc 100644 --- a/core/data/CbmMCTrack.cxx +++ b/core/data/CbmMCTrack.cxx @@ -213,6 +213,8 @@ int32_t CbmMCTrack::GetNPoints(ECbmModuleId detId) const return ((fNPoints & (1 << 24)) >> 24); else if (detId == ECbmModuleId::kPsd) return ((fNPoints & (1 << 25)) >> 25); + else if (detId == ECbmModuleId::kFsd) + return ((fNPoints & (1 << 26)) >> 26); else { LOG(error) << "GetNPoints: Unknown detector ID " << detId; return 0; @@ -288,6 +290,13 @@ void CbmMCTrack::SetNPoints(ECbmModuleId iDet, int32_t nPoints) fNPoints = (fNPoints & (~(1 << 25))) | (nPoints << 25); } + else if (iDet == ECbmModuleId::kFsd) { + if (nPoints < 0) nPoints = 0; + else if (nPoints > 1) + nPoints = 1; + fNPoints = (fNPoints & (~(1 << 26))) | (nPoints << 26); + } + else LOG(error) << "Unknown detector ID " << iDet; } @@ -304,7 +313,7 @@ std::string CbmMCTrack::ToString() const << GetNPoints(ECbmModuleId::kSts) << ", RICH " << GetNPoints(ECbmModuleId::kRich) << ", MUCH " << GetNPoints(ECbmModuleId::kMuch) << ", TRD " << GetNPoints(ECbmModuleId::kTrd) << ", TOF " << GetNPoints(ECbmModuleId::kTof) << ", ECAL " << GetNPoints(ECbmModuleId::kEcal) << ", PSD " - << GetNPoints(ECbmModuleId::kPsd) << std::endl; + << GetNPoints(ECbmModuleId::kPsd) << ", FSD " << GetNPoints(ECbmModuleId::kFsd) << std::endl; return ss.str(); } // ------------------------------------------------------------------------- diff --git a/core/data/CbmMCTrack.h b/core/data/CbmMCTrack.h index d7c7ca95a02288669c6aa3a4e6b30221695d7a60..5ac230f11e006ade08405d1186e3ce24159812d0 100644 --- a/core/data/CbmMCTrack.h +++ b/core/data/CbmMCTrack.h @@ -145,9 +145,10 @@ private: ** TOF: Bit 20 - 23 (4 bits, max. value 15) ** ECAL: Bit 24 (1 bit, max. value 1) ** ZDC: Bit 25 (1 bit, max. value 1) + ** FSD: Bit 26 (1 bit, max. value 1) ** The respective point numbers can be accessed and modified ** with the inline functions. - ** Bits 26-31 are spare for potential additional detectors. + ** Bits 27-31 are spare for potential additional detectors. **/ int32_t fNPoints; diff --git a/core/data/CbmModuleList.cxx b/core/data/CbmModuleList.cxx index 7f0cbf82afbfe7f6e452e44a6bdb6b24f7ebf3bb..de8ff14260b0455f401b0b9d4ca3cba835d8ccc8 100644 --- a/core/data/CbmModuleList.cxx +++ b/core/data/CbmModuleList.cxx @@ -29,10 +29,11 @@ map<ECbmModuleId, TString> CbmModuleList::DefineModules() data[ECbmModuleId::kTrd] = "trd"; data[ECbmModuleId::kTof] = "tof"; data[ECbmModuleId::kEcal] = "ecal"; - data[ECbmModuleId::kPsd] = "psd"; + data[ECbmModuleId::kFsd] = "fsd"; data[ECbmModuleId::kHodo] = "hodo"; data[ECbmModuleId::kDummyDet] = "dummy"; data[ECbmModuleId::kT0] = "t0"; + data[ECbmModuleId::kPsd] = "psd"; data[ECbmModuleId::kMagnet] = "magnet"; data[ECbmModuleId::kTarget] = "target"; data[ECbmModuleId::kPipe] = "pipe"; diff --git a/core/data/CbmTsEventHeader.cxx b/core/data/CbmTsEventHeader.cxx index 524f2384567dbe0e9bbb9d5363a978105edcdbd7..75439e6103711f556e8036754976a6097d45eeaa 100644 --- a/core/data/CbmTsEventHeader.cxx +++ b/core/data/CbmTsEventHeader.cxx @@ -15,6 +15,7 @@ void CbmTsEventHeader::Reset() // Reset the digi counters fNDigisMuch = 0; fNDigisPsd = 0; + fNDigisFsd = 0; fNDigisRich = 0; fNDigisSts = 0; fNDigisTof = 0; diff --git a/core/data/CbmTsEventHeader.h b/core/data/CbmTsEventHeader.h index d77d7343d5fb87efefce13263d30eaaa6fc6f7c7..6cbb3c8e82fb69b9c64d3e37d72f3b9a503ccd9b 100644 --- a/core/data/CbmTsEventHeader.h +++ b/core/data/CbmTsEventHeader.h @@ -24,6 +24,8 @@ public: /** @brief Add a number of digis from this Ts */ void AddNDigisPsd(uint64_t value) { fNDigisPsd += value; } /** @brief Add a number of digis from this Ts */ + void AddNDigisFsd(uint64_t value) { fNDigisFsd += value; } + /** @brief Add a number of digis from this Ts */ void AddNDigisRich(uint64_t value) { fNDigisRich += value; } /** @brief Add a number of digis from this Ts */ void AddNDigisSts(uint64_t value) { fNDigisSts += value; } @@ -41,6 +43,8 @@ public: /** @brief Get the number of digis in this Ts */ uint64_t GetNDigisPsd() const { return fNDigisPsd; } /** @brief Get the number of digis in this Ts */ + uint64_t GetNDigisFsd() const { return fNDigisFsd; } + /** @brief Get the number of digis in this Ts */ uint64_t GetNDigisRich() const { return fNDigisRich; } /** @brief Get the number of digis in this Ts */ uint64_t GetNDigisSts() const { return fNDigisSts; } @@ -66,6 +70,8 @@ public: /** @brief Set the number of digis in this Ts */ void SetNDigisPsd(uint64_t value) { fNDigisPsd = value; } /** @brief Set the number of digis in this Ts */ + void SetNDigisFsd(uint64_t value) { fNDigisFsd = value; } + /** @brief Set the number of digis in this Ts */ void SetNDigisRich(uint64_t value) { fNDigisRich = value; } /** @brief Set the number of digis in this Ts */ void SetNDigisSts(uint64_t value) { fNDigisSts = value; } @@ -97,6 +103,8 @@ protected: uint64_t fNDigisMuch = 0; /** @brief nDigis in "this" timeslice measured by the PSD */ uint64_t fNDigisPsd = 0; + /** @brief nDigis in "this" timeslice measured by the FSD */ + uint64_t fNDigisFsd = 0; /** @brief nDigis in "this" timeslice measured by the RICH */ uint64_t fNDigisRich = 0; /** @brief nDigis in "this" timeslice measured by the STS */ diff --git a/core/data/base/CbmDigiData.h b/core/data/base/CbmDigiData.h index d44185d8dedb4b3614f03f576e43dc5e31c1414e..36282ed401580490206cdd62f4314f3517dd34d3 100644 --- a/core/data/base/CbmDigiData.h +++ b/core/data/base/CbmDigiData.h @@ -7,6 +7,7 @@ #define CBMDIGIDATA_H 1 #include "CbmBmonDigiData.h" +#include "CbmFsdDigiData.h" #include "CbmMuchDigiData.h" #include "CbmPsdDigiData.h" #include "CbmRichDigiData.h" @@ -39,6 +40,7 @@ public: CbmTrdDigiData fTrd2d; ///< TRD2D data CbmTofDigiData fTof; ///< TOF data CbmPsdDigiData fPsd; ///< PSD data + CbmFsdDigiData fFsd; ///< FSD data friend class boost::serialization::access; /** @brief BOOST serializer**/ @@ -53,12 +55,13 @@ public: ar& fTrd2d; ar& fTof; ar& fPsd; + ar& fFsd; ar& fRich; } // --- ROOT serializer #ifndef NO_ROOT - ClassDefNV(CbmDigiData, 3); + ClassDefNV(CbmDigiData, 5); #endif /** @brief Clear content **/ @@ -71,9 +74,10 @@ public: fTrd2d.Clear(); fTof.Clear(); fPsd.Clear(); + fFsd.Clear(); fRich.Clear(); } }; -BOOST_CLASS_VERSION(CbmDigiData, 4) +BOOST_CLASS_VERSION(CbmDigiData, 5) #endif /* CBMDIGIDATA_H */ diff --git a/core/data/fsd/CbmFsdAddress.cxx b/core/data/fsd/CbmFsdAddress.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2e00ae4c02f11bb3acff6362a8fb204294029eca --- /dev/null +++ b/core/data/fsd/CbmFsdAddress.cxx @@ -0,0 +1,134 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Andrey Lebedev, Lukas Chlad [committer] */ + +/** @file CbmFsdAddress.cxx + ** @author Lukas Chlad <l.chlad@gsi.de> + ** @date 16.06.2023 + ** + ** Inspired by CbmStsAddress and only accomodate physical properties of expected FSD detector + ** + **/ + +#include "CbmFsdAddress.h" + +#include "CbmDefs.h" // for kFsd + +#include <cassert> // for assert +#include <sstream> // for operator<<, basic_ostream, stringstream + +#include "AlgoFairloggerCompat.h" // for Logger, LOG + +// ----- Construct address from element Ids ------------------------------ +int32_t CbmFsdAddress::GetAddress(uint32_t Unit, uint32_t Module, uint32_t PhotoDet, uint32_t Version) +{ + using namespace Detail; + + assert(Version <= kCurrentVersion); + + // Catch overrun of allowed ranges + if (Unit > static_cast<uint32_t>(kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Unit)])) { + LOG(error) << "Unit Id " << Unit << " exceeds maximum " + << kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Unit)]; + return 0; + } + if (Module > static_cast<uint32_t>(kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Module)])) { + LOG(error) << "Module Id " << Module << " exceeds maximum " + << kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::Module)]; + return 0; + } + if (PhotoDet > static_cast<uint32_t>(kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)])) { + LOG(error) << "PhotoDetector Id " << PhotoDet << " exceeds maximum " + << kMask[Version][static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)]; + return 0; + } + + return ToIntegralType(ECbmModuleId::kFsd) << kShift[Version][static_cast<uint32_t>(CbmFsdAddress::Level::System)] + | Unit << kShift[Version][static_cast<int32_t>(CbmFsdAddress::Level::Unit)] + | Module << kShift[Version][static_cast<int32_t>(CbmFsdAddress::Level::Module)] + | PhotoDet << kShift[Version][static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)] | Version << kVersionShift; +} +// --------------------------------------------------------------------------- + + +// ----- Construct address from address of descendant element ------------ +int32_t CbmFsdAddress::GetMotherAddress(int32_t address, int32_t level) +{ + using namespace Detail; + if (!(level >= static_cast<int32_t>(CbmFsdAddress::Level::System) + && level < static_cast<int32_t>(CbmFsdAddress::Level::NumLevels))) { + throw std::out_of_range("CbmFsdAddress: Illegal element level" + level); + return 0; + } + if (level == static_cast<uint32_t>(CbmFsdAddress::Level::NumLevels) - 1) return address; + uint32_t version = GetVersion(address); + int32_t motherAdd = (address & ((1 << kShift[version][level + 1]) - 1)); + motherAdd = motherAdd | (version << kVersionShift); + return motherAdd; +} +// --------------------------------------------------------------------------- + + +// ----- Get the index of an element ------------------------------------- +uint32_t CbmFsdAddress::GetElementId(int32_t address, int32_t level) +{ + using namespace Detail; + if (!(level >= static_cast<int32_t>(CbmFsdAddress::Level::System) + && level < static_cast<int32_t>(CbmFsdAddress::Level::NumLevels))) { + throw std::out_of_range("CbmFsdAddress: Illegal element level" + level); + return 0; + } + uint32_t version = GetVersion(address); + return (address & (kMask[version][level] << kShift[version][level])) >> kShift[version][level]; +} +// --------------------------------------------------------------------------- + + +// ----- Get System ID --------------------------------------------------- +uint32_t CbmFsdAddress::GetSystemId(int32_t address) +{ + return GetElementId(address, static_cast<uint32_t>(CbmFsdAddress::Level::System)); +} +// --------------------------------------------------------------------------- + + +// ----- Get the version number from the address ------------------------- +uint32_t CbmFsdAddress::GetVersion(int32_t address) +{ + return uint32_t((address & (kVersionMask << kVersionShift)) >> kVersionShift); +} +// --------------------------------------------------------------------------- + + +// ----- Construct address by changing the index of an element ------------ +int32_t CbmFsdAddress::SetElementId(int32_t address, int32_t level, uint32_t newId) +{ + using namespace Detail; + if (!(level >= static_cast<int32_t>(CbmFsdAddress::Level::System) + && level < static_cast<int32_t>(CbmFsdAddress::Level::NumLevels))) { + throw std::out_of_range("CbmFsdAddress: Illegal element level" + level); + return 0; + } + uint32_t version = GetVersion(address); + uint32_t maxId = (1 << kBits[version][level]) - 1; + if (newId > maxId) { + LOG(fatal) << "Id " << newId << " for FSD level " << level << " exceeds maximum " << maxId; + return 0; + } + return (address & (~(kMask[version][level] << kShift[version][level]))) | (newId << kShift[version][level]); +} +// ------------------------------------------------------------------------- + +// ----- String output ------------------------------------------------- +std::string CbmFsdAddress::ToString(int32_t address) +{ + std::stringstream ss; + + ss << "FsdAddress: address " << address << " (version " << GetVersion(address) << ")" + << ": system " << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::System)) << ", unit " + << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::Unit)) << ", module " + << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::Module)) << ", photo detector " + << GetElementId(address, static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)); + return ss.str(); +} +// ------------------------------------------------------------------------- diff --git a/core/data/fsd/CbmFsdAddress.h b/core/data/fsd/CbmFsdAddress.h new file mode 100644 index 0000000000000000000000000000000000000000..ffae9d59d1c9f9205fcbbb908f4c25b55b637c05 --- /dev/null +++ b/core/data/fsd/CbmFsdAddress.h @@ -0,0 +1,151 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Andrey Lebedev, Lukas Chlad [committer] */ + +/** @file CbmFsdAddress.h + ** @author Lukas Chlad <l.chlad@gsi.de> + ** @date 16.06.2023 + ** + ** Inspired by CbmStsAddress and only accomodate physical properties of expected FSD detector + ** + **/ + +#ifndef CBMFSDADDRESS_H +#define CBMFSDADDRESS_H 1 + +#include "CbmDefs.h" // for ECbmModuleId + +#include <cassert> // for assert +#include <cstdint> // for uint32_t +#include <sstream> // for string + +/** Namespace CbmFsdAddress + ** @brief Functions to encode or decode the address field of FSD data. + ** @author Lukas Chlad <l.chlad@gsi.de> + ** + ** Inspired by the structure used by STS. + ** The current definition (version 0) of the address bit field for the FSD is: + ** + ** Level Bits Max. Elements Bit Position + ** System (kFSD) 4 16 0 - 3 + ** Unit 4 16 4 - 7 + ** Module 15 32768 8 - 22 + ** PhotoDetector 2 4 23 - 24 + ** Unused 3 25 - 27 + ** Version 4 16 28 - 31 + **/ +namespace CbmFsdAddress +{ + /** Enumerator for the hierarchy levels of the FSD setup **/ + enum class Level + { + System, + Unit, + Module, + PhotoDet, + NumLevels + }; + + inline constexpr uint32_t kCurrentVersion = 0; + + // --- These values are not to be changed if backward compatibility + // --- shall be maintained. + inline constexpr int32_t kVersionSize = 4; // Bits for version number + inline constexpr int32_t kVersionShift = 28; // First bit for version number + inline constexpr int32_t kVersionMask = (1 << kVersionSize) - 1; + + namespace Detail + { + // clang-format off + // ----- Definition of address bit field ------------------------------ + inline constexpr uint16_t kBits[kCurrentVersion + 1][static_cast<uint32_t>(CbmFsdAddress::Level::NumLevels)] = { + + // Version 0 + { + 4, // system + 4, // unit + 15, // module + 2 // photodet + } + + }; + // ------------------------------------------------------------------------- + + // ----- Bit shifts ----------------------------------------------------- + inline constexpr int32_t kShift[kCurrentVersion + 1][static_cast<uint32_t>(CbmFsdAddress::Level::NumLevels)] = { + {0, kShift[0][0] + kBits[0][0], kShift[0][1] + kBits[0][1], kShift[0][2] + kBits[0][2]} + }; + // ------------------------------------------------------------------------- + + // ----- Bit masks ----------------------------------------------------- + inline constexpr int32_t kMask[kCurrentVersion + 1][static_cast<uint32_t>(CbmFsdAddress::Level::NumLevels)] = { + {(1 << kBits[0][0]) - 1, (1 << kBits[0][1]) - 1, (1 << kBits[0][2]) - 1, (1 << kBits[0][3]) - 1} + }; + // ------------------------------------------------------------------------- + // clang-format on + } // Namespace Detail + + + /** @brief Construct address + ** @param unit Unit index + ** @param module Module index in unit + ** @param photodet PhotoDetector index in module + ** @return Unique element address + **/ + int32_t GetAddress(uint32_t Unit = 0, uint32_t Module = 0, uint32_t PhotoDet = 0, uint32_t Version = kCurrentVersion); + + + /** @brief Construct the address of an element from the address of a + ** descendant element. + ** @param address Address of descendant element + ** @param level Desired hierarchy level + ** @return Address of element at desired hierarchy level + ** + ** This strips of the address information of all hierarchy levels + ** below the desired one. + **/ + int32_t GetMotherAddress(int32_t address, int32_t level); + + + /** @brief Get the index of an element + ** @param address Unique element address + ** @param level Hierarchy level + ** @return Element index + **/ + uint32_t GetElementId(int32_t address, int32_t level); + + + /** @brief Get system Id (should be integer value of ECbmModuleId::kFsd) + ** @param address Unique element address + **/ + uint32_t GetSystemId(int32_t address); + + + /** @brief Extract version number + ** @param address Unique element address + ** @value Version number + ** + ** The version is encoded in the last 4 bits (28 to 31). + ** The maximal number of versions is 16. + **/ + uint32_t GetVersion(int32_t address); + + + /** @brief Set the index of an element, leaving the other element levels + ** untouched + ** @param address Unique element address + ** @param level Hierarchy level + ** @param newId New element index + ** @return New address + **/ + int32_t SetElementId(int32_t address, int32_t level, uint32_t newId); + + /** @brief String output + ** @param address Unique element address + **/ + std::string ToString(int32_t address); + +} // Namespace CbmFsdAddress + + +#endif // CBMFSDADDRESS_H diff --git a/core/data/fsd/CbmFsdDigi.cxx b/core/data/fsd/CbmFsdDigi.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d090b41b379ab199c40a6298f58ce506b757b42c --- /dev/null +++ b/core/data/fsd/CbmFsdDigi.cxx @@ -0,0 +1,40 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Florian Uhlig, Lukas Chlad [committer] */ + +/** @file CbmFsdDigi.cxx + ** @author Lukas Chlad <l.chlad@gsi.de> + ** @date 15.06.2023 + ** + ** Code for Data class for FSD digital information + **/ + +#include "CbmFsdDigi.h" + +#include <iomanip> // for hex, setw, setfill, fixed, setprecission +#include <sstream> // for operator<<, basic_ostream, char_trait +#include <string> // for basic_string + +// --- Set address from module and section number +// --- version in CbmFsdAddress is taken the latest +void CbmFsdDigi::SetAddress(uint32_t unitId, uint32_t moduleId, uint32_t photodetId) +{ + fAddress = CbmFsdAddress::GetAddress(unitId, moduleId, photodetId); +} + + +// --- Info to string +std::string CbmFsdDigi::ToString() const +{ + // Example output + // CbmFsdDigi: address = 0x00001018 Charge = 0.011590 Time = 1006.438294 + + std::stringstream ss; + ss << "CbmFsdDigi: address = 0x" << std::uppercase << std::hex << std::setw(8) << std::setfill('0') << fAddress + << " Charge = " << std::fixed << std::setprecision(6) << fEdep << " Time = " << fTime; + return ss.str(); +} + +#ifndef NO_ROOT +ClassImp(CbmFsdDigi) +#endif diff --git a/core/data/fsd/CbmFsdDigi.h b/core/data/fsd/CbmFsdDigi.h new file mode 100644 index 0000000000000000000000000000000000000000..42fc8bb5db3fec58953ff230d675e08b6f84beda --- /dev/null +++ b/core/data/fsd/CbmFsdDigi.h @@ -0,0 +1,174 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Pierre-Alain Loizeau, Lukas Chlad [committer] */ + +/** \file CbmFsdDigi.h + ** \author Lukas Chlad <l.chlad@gsi.de> + ** \date 15.06.2023 + **/ + +/** \class CbmFsdDigi + ** \brief Data class for FSD digital information + ** \version 1 + ** + ** Unique Address: 32 bits following CbmFsdAddress + ** Time: 64 bits double + ** Energy deposition: 64 bits double + **/ + +#ifndef CBMFSDDIGI_H +#define CBMFSDDIGI_H 1 + +#include "CbmDefs.h" // for ECbmModuleId::kFsd +#include "CbmFsdAddress.h" // for CbmFsdAddress + +#ifndef NO_ROOT +#include <Rtypes.h> // for ClassDefNV +#endif + +#include <boost/serialization/access.hpp> +#include <boost/serialization/base_object.hpp> + +#include <cstdint> +#include <string> // for string + + +class CbmFsdDigi { + +public: + /**@brief Default constructor. + **/ + CbmFsdDigi() {} + + + /** @brief Constructor with assignment + ** @param address Unique channel address + ** @param time Time [ns] + ** @param edep Energy deposition + **/ + CbmFsdDigi(uint32_t address, double time, double edep) : fAddress(address), fTime(time), fEdep(edep) {} + + + /** @brief Constructor with detailed assignment. + ** @param unitId Unit Identifier + ** @param moduleId Module Identifier + ** @param photodetId PhotoDetector Identifier + ** @param time Time [ns] + ** @param edep Energy deposition + **/ + CbmFsdDigi(uint32_t unitId, uint32_t moduleId, uint32_t photodetId, double time, double edep) + : fAddress(CbmFsdAddress::GetAddress(unitId, moduleId, photodetId)) + , fTime(time) + , fEdep(edep) + { + } + + + /** Destructor **/ + ~CbmFsdDigi() {} + + + /** @brief Class name (static) + ** @return CbmFsdDigi + **/ + static const char* GetClassName() { return "CbmFsdDigi"; } + + + /** @brief Address + ** @return Unique channel address (see CbmFsdAddress) + **/ + uint32_t GetAddress() const { return fAddress; }; + + + /** @brief Get the desired name of the branch for this obj in the cbm output tree (static) + ** @return "FsdDigi" + **/ + static const char* GetBranchName() { return "FsdDigi"; } + + + /** @brief Time + ** @return Time [ns] + **/ + double GetTime() const { return fTime; }; + + + /** @brief Charge + ** @return Charge (energy deposition) + ** + ** Alias for GetEdep(), for compatibility with template methods + */ + double GetCharge() const { return fEdep; }; + + + /** @brief Energy deposit + ** @return Energy deposit + **/ + double GetEdep() const { return fEdep; }; + + + /** @brief Module Identifier + ** @return Module number + **/ + double GetModuleID() const + { + return CbmFsdAddress::GetElementId(GetAddress(), static_cast<int32_t>(CbmFsdAddress::Level::Module)); + } + + + /** @brief Unit Identifier + ** @return Unit number + **/ + double GetUnitID() const + { + return CbmFsdAddress::GetElementId(GetAddress(), static_cast<int32_t>(CbmFsdAddress::Level::Unit)); + } + + + /** @brief PhotoDet Identifier + ** @return PhotoDet number + **/ + double GetPhotoDetID() const + { + return CbmFsdAddress::GetElementId(GetAddress(), static_cast<int32_t>(CbmFsdAddress::Level::PhotoDet)); + } + + /** @brief System identifier + ** @return System ID (ECbmModuleId) + **/ + static ECbmModuleId GetSystem() { return ECbmModuleId::kFsd; } + + + /** Modifiers **/ + void SetAddress(uint32_t address) { fAddress = address; }; + void SetAddress(uint32_t unitId, uint32_t moduleId, uint32_t photodetId); + void SetTime(double time) { fTime = time; } + void SetEdep(double edep) { fEdep = edep; } + + + /** @brief String output + ** @return Info + **/ + std::string ToString() const; + + +private: + uint32_t fAddress = 0; /// Unique channel address + double fTime = -1.; /// Time of measurement [ns] + double fEdep = 0.; /// Energy deposition from FPGA [MeV] + + /// BOOST serialization interface + friend class boost::serialization::access; + template<class Archive> + void serialize(Archive& ar, const unsigned int /*version*/) + { + ar& fAddress; + ar& fTime; + ar& fEdep; + } + +#ifndef NO_ROOT + ClassDefNV(CbmFsdDigi, 1); +#endif +}; + +#endif // CBMFSDDIGI_H diff --git a/core/data/fsd/CbmFsdDigiData.h b/core/data/fsd/CbmFsdDigiData.h new file mode 100644 index 0000000000000000000000000000000000000000..0c34eb8c447327853a4f5bac0f3bdfa29b6a2c09 --- /dev/null +++ b/core/data/fsd/CbmFsdDigiData.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Lukas Chlad [committer] */ + +#ifndef CBMFSDDIGIDATA_H +#define CBMFSDDIGIDATA_H 1 + + +#include "CbmFsdDigi.h" + +#ifndef NO_ROOT +#include <Rtypes.h> // for ClassDef +#endif + +#include <boost/serialization/access.hpp> +#include <boost/serialization/base_object.hpp> + +#include <vector> + +/** @class CbmFsdDigiData + ** @brief Container class for CbmFsdDigi objects + ** @author Volker Friese <v.friese@gsi.de> + ** @since 7.12.2022 + ** @version 1.0 + ** + ** Container class for transporting CbmFsdDigi objects. + ** The current implementation is the simplest one: a std::vector. + **/ +class CbmFsdDigiData { + +public: + std::vector<CbmFsdDigi> fDigis = {}; ///< Data vector + + friend class boost::serialization::access; + + /** @brief BOOST serializer**/ + template<class Archive> + void serialize(Archive& ar, const unsigned int /*version*/) + { + ar& fDigis; + } + + /** @brief Clear content **/ + void Clear() { fDigis.clear(); } + + // --- ROOT serializer +#ifndef NO_ROOT + ClassDefNV(CbmFsdDigiData, 1); +#endif +}; + +#endif diff --git a/core/data/fsd/CbmFsdHit.cxx b/core/data/fsd/CbmFsdHit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1f6082ec615e67bc42b13b1fd0c2e94b205bedd3 --- /dev/null +++ b/core/data/fsd/CbmFsdHit.cxx @@ -0,0 +1,43 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Florian Uhlig, Lukas Chlad [committer] */ + +/** CbmFsdHit.cxx + **@author Lukas Chlad <l.chlad@gsi.de> + **@since 15.06.2023 + ** + **/ +#include "CbmFsdHit.h" + +#include "CbmHit.h" // for kFSDHIT + +#include <Logger.h> // for Logger, LOG + +// ----- Default constructor ------------------------------------------- +CbmFsdHit::CbmFsdHit() : CbmPixelHit(), fModuleID(-1), fEdep(-1) +{ + SetType(kFSDHIT); + SetTime(0.); +} +CbmFsdHit::CbmFsdHit(int32_t module, double edep) : CbmPixelHit(), fModuleID(module), fEdep(edep) +{ + SetType(kFSDHIT); + SetTime(0.); +} + + +// ----- Destructor ---------------------------------------------------- +CbmFsdHit::~CbmFsdHit() {} +// ------------------------------------------------------------------------- + +void CbmFsdHit::Print(Option_t*) const { LOG(info) << ToString(); } + +std::string CbmFsdHit::ToString() const +{ + std::stringstream ss; + ss << "module : " << fModuleID << "position: [" << GetX() << "," << GetY() << "," << GetZ() << "] " + << " ELoss " << fEdep; + return ss.str(); +} + +ClassImp(CbmFsdHit) diff --git a/core/data/fsd/CbmFsdHit.h b/core/data/fsd/CbmFsdHit.h new file mode 100644 index 0000000000000000000000000000000000000000..8989a540c9b92383d7c9864d40708a92ac855cef --- /dev/null +++ b/core/data/fsd/CbmFsdHit.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Lukas Chlad [committer] */ + +/** CbmFsdHit.h + **@author Lukas Chlad <l.chlad@gsi.de> + **@since 15.06.2023 + **@version 1 + ** + ** Data class for FSD reconstruction + ** Energy deposition per module + ** + **/ + + +#ifndef CBMFSDHIT_H +#define CBMFSDHIT_H 1 + +#include "CbmPixelHit.h" // for CbmPixelHit + +#include <Rtypes.h> // for ClassDef + +#include <cstdint> + +class CbmFsdHit : public CbmPixelHit { + +public: + /** Default constructor **/ + CbmFsdHit(); + + CbmFsdHit(int32_t module, double edep); + + + /** Destructor **/ + virtual ~CbmFsdHit(); + + + /** Setters - Getters **/ + + double GetEdep() const { return fEdep; } + void SetEdep(double edep) { fEdep = edep; } + + int32_t GetModuleID() const { return fModuleID; } + void SetModuleID(int32_t mod) { fModuleID = mod; } + + void Print(Option_t* = "") const; + + std::string ToString() const; + +private: + /** Data members **/ + + int32_t fModuleID; + double fEdep; + + + ClassDef(CbmFsdHit, 1); +}; + + +#endif diff --git a/core/data/fsd/CbmFsdPoint.cxx b/core/data/fsd/CbmFsdPoint.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b200a6de42090f9dc9f1e035d4fa2d5d5447072c --- /dev/null +++ b/core/data/fsd/CbmFsdPoint.cxx @@ -0,0 +1,46 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Florian Uhlig, Lukas Chlad [committer] */ + +#include "CbmFsdPoint.h" + +#include <FairMCPoint.h> // for FairMCPoint +#include <Logger.h> // for Logger, LOG + +#include <sstream> // for stringstream + +// ----- Default constructor ------------------------------------------- +CbmFsdPoint::CbmFsdPoint() : FairMCPoint(), fModuleID(0) {} +// ------------------------------------------------------------------------- + + +// ----- Standard constructor ------------------------------------------ +CbmFsdPoint::CbmFsdPoint(int32_t trackID, int32_t detID, TVector3 pos, TVector3 mom, double tof, double length, + double eLoss) + : FairMCPoint(trackID, detID, pos, mom, tof, length, eLoss) + , fModuleID(0) +{ +} +// ------------------------------------------------------------------------- + + +// ----- Destructor ---------------------------------------------------- +CbmFsdPoint::~CbmFsdPoint() {} +// ------------------------------------------------------------------------- + + +// ----- Public method Print ------------------------------------------- +void CbmFsdPoint::Print(const Option_t* /*opt*/) const { LOG(info) << ToString(); } + +std::string CbmFsdPoint::ToString() const +{ + std::stringstream ss; + ss << "Fsd point for track " << fTrackID << " in detector " << fDetectorID << "\n" + << " Position (" << fX << ", " << fY << ", " << fZ << ") cm\n" + << " Momentum (" << fPx << ", " << fPy << ", " << fPz << ") GeV\n" + << " Time " << fTime << " ns, Length " << fLength << " cm, Energy loss " << fELoss * 1.0e06 << " keV"; + return ss.str(); +} +// ------------------------------------------------------------------------- + +ClassImp(CbmFsdPoint) diff --git a/core/data/fsd/CbmFsdPoint.h b/core/data/fsd/CbmFsdPoint.h new file mode 100644 index 0000000000000000000000000000000000000000..329c2bb9c10b057a4bc4f1525daf578fe1262461 --- /dev/null +++ b/core/data/fsd/CbmFsdPoint.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Florian Uhlig, Lukas Chlad [committer] */ + +/** @class CbmFsdPoint + ** @author L. Chlad + ** + ** @brief Interception of MC track with the plane representing the FSD. + **/ + + +#ifndef CBMFSDPOINT_H +#define CBMFSDPOINT_H 1 + +#include <FairMCPoint.h> // for FairMCPoint + +#include <Rtypes.h> // for ClassDef +#include <TVector3.h> // for TVector3 + +#include <cstdint> +#include <string> // for string + +class CbmFsdPoint : public FairMCPoint { + +public: + /** Default constructor **/ + CbmFsdPoint(); + + + /** Constructor with arguments + *@param trackID Index of MCTrack + *@param detID Detector ID + *@param pos Ccoordinates at entrance to active volume [cm] + *@param mom Momentum of track at entrance [GeV] + *@param tof Time since event start [ns] + *@param length Track length since creation [cm] + *@param eLoss Energy deposit [GeV] + **/ + CbmFsdPoint(int32_t trackID, int32_t detID, TVector3 pos, TVector3 mom, double tof, double length, double eLoss); + + + /** Copy constructor **/ + // CbmFsdPoint(const CbmFsdPoint& point) { *this = point; }; + + + /** Destructor **/ + virtual ~CbmFsdPoint(); + + + /** Output to screen **/ + virtual void Print(const Option_t* opt) const; + + /** Modifiers **/ + void SetModuleID(int32_t mod) { fModuleID = mod; } + /** Accessors **/ + int32_t GetModuleID() const { return fModuleID; } + + std::string ToString() const; + +private: + int32_t fModuleID; //number of module + + + ClassDef(CbmFsdPoint, 1) +}; + + +#endif diff --git a/core/detectors/fsd/CMakeLists.txt b/core/detectors/fsd/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e3582ed7bcfe7e85777955eb43a6ec31f5af6f04 --- /dev/null +++ b/core/detectors/fsd/CMakeLists.txt @@ -0,0 +1,27 @@ +set(INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + ) + +set(SRCS + CbmFsdContFact.cxx + CbmFsdDetectorMapManager.cxx + ) + +set(LIBRARY_NAME CbmFsdBase) +set(LINKDEF ${LIBRARY_NAME}LinkDef.h) +set(PUBLIC_DEPENDENCIES + FairRoot::ParBase + ) + +set(PRIVATE_DEPENDENCIES + FairLogger::FairLogger + ROOT::Core + ) + +generate_cbm_library() + +# Install file which has no corresponding source file +install(FILES + CbmFsdDetectorData.h + DESTINATION include + ) diff --git a/core/detectors/fsd/CbmFsdBaseLinkDef.h b/core/detectors/fsd/CbmFsdBaseLinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..26be7730a4e02d96c364422330cb9fa3d45a90e5 --- /dev/null +++ b/core/detectors/fsd/CbmFsdBaseLinkDef.h @@ -0,0 +1,16 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Pierre-Alain Loizeau, Florian Uhlig, Lukas Chlad [committer] */ + +// $Id: TofLinkDef.h,v 1.3 2006/03/07 11:51:55 friese Exp $ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class CbmFsdContFact + ; +#pragma link C++ class CbmFsdDetectorMapManager + ; + +#endif diff --git a/core/detectors/fsd/CbmFsdContFact.cxx b/core/detectors/fsd/CbmFsdContFact.cxx new file mode 100644 index 0000000000000000000000000000000000000000..550b8ebcf2d8a1ede57c08a6938ac8054dad5c1f --- /dev/null +++ b/core/detectors/fsd/CbmFsdContFact.cxx @@ -0,0 +1,54 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Florian Uhlig, Lukas Chlad [committer] */ + +/** CbmFsdContFact.h + * + * @author F. Uhlig <f.uhlig@gsi.de> + * @version 1 + * @since 25.01.21 + * + * Factory for the parameter containers of the FSD detector + * + */ +#include "CbmFsdContFact.h" + +#include <FairContFact.h> // for FairContainer +#include <FairRuntimeDb.h> // for FairRuntimeDb +#include <Logger.h> // for LOG + +#include <TList.h> // for TList +#include <TString.h> // for TString + +#include <string.h> // for strcmp + +ClassImp(CbmFsdContFact) + + static CbmFsdContFact gCbmFsdContFact; + +CbmFsdContFact::CbmFsdContFact() +{ + // Constructor (called when the library is loaded) + fName = "CbmFsdContFact"; + fTitle = "Factory for parameter containers in libFsdBase"; + setAllContainers(); + FairRuntimeDb::instance()->addContFactory(this); +} + +void CbmFsdContFact::setAllContainers() +{ + /** Creates the Container objects with all accepted contexts and adds them to + * the list of containers for the FsdBase library.*/ +} + +FairParSet* CbmFsdContFact::createContainer(FairContainer* c) +{ + /** Calls the constructor of the corresponding parameter container. + * For an actual context, which is not an empty string and not the default context + * of this container, the name is concatinated with the context. */ + const char* name = c->GetName(); + LOG(info) << " -I container name " << name; + FairParSet* p = 0; + + return p; +} diff --git a/core/detectors/fsd/CbmFsdContFact.h b/core/detectors/fsd/CbmFsdContFact.h new file mode 100644 index 0000000000000000000000000000000000000000..dbc5f34503c2101236757cfb33cf32296e4b5617 --- /dev/null +++ b/core/detectors/fsd/CbmFsdContFact.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Florian Uhlig, Lukas Chlad [committer] */ + +/** CbmFsdContFact.h + * + * @author F. Uhlig <f.uhlig@gsi.de> + * @version 1 + * @since 25.01.21 + * + * Factory for the parameter containers of the FSD detector + * + */ + +#ifndef CBMFSDCONTFACT_H +#define CBMFSDCONTFACT_H + +#include <FairContFact.h> // for FairContFact + +#include <Rtypes.h> // for THashConsistencyHolder, ClassDef + +class FairParIo; +class FairParSet; +class FairContainer; + +class CbmFsdContFact : public FairContFact { +public: + CbmFsdContFact(); + ~CbmFsdContFact() {} + FairParSet* createContainer(FairContainer*); + +private: + void setAllContainers(); + + ClassDef(CbmFsdContFact, 0) // Factory for all Fsd parameter containers +}; + +#endif /* !CBMFSDCONTFACT_H */ diff --git a/core/detectors/fsd/CbmFsdDetectorData.h b/core/detectors/fsd/CbmFsdDetectorData.h new file mode 100644 index 0000000000000000000000000000000000000000..5bab1cfbaed0e5cdfbc7f6e829fe09bea18ad997 --- /dev/null +++ b/core/detectors/fsd/CbmFsdDetectorData.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Lukas Chlad [committer] */ + +#ifndef CBMFSDDETECTORDATA_H +#define CBMFSDDETECTORDATA_H + +#include <RtypesCore.h> // for Double_t, Int_t + +struct CbmFsdModuleData { + // module index + Int_t fId; + // module center position + Double_t fX; + Double_t fY; + Double_t fZ; + // module half-lengths + Double_t dX; + Double_t dY; + Double_t dZ; +}; + +#endif /* CBMFSDDETECTORDATA_H */ diff --git a/core/detectors/fsd/CbmFsdDetectorMapManager.cxx b/core/detectors/fsd/CbmFsdDetectorMapManager.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bfbed6a7e1fdf8ba4bffa140a71a5e3c7bc80d3b --- /dev/null +++ b/core/detectors/fsd/CbmFsdDetectorMapManager.cxx @@ -0,0 +1,111 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Lukas Chlad [committer] */ + +#include "CbmFsdDetectorMapManager.h" + +#include "CbmFsdDetectorData.h" // for CbmFsdModuleData + +#include <Logger.h> // for LOG, Logger + +#include <TGeoBBox.h> // for TGeoBBox +#include <TGeoManager.h> // for TGeoManager, gGeoManager +#include <TGeoMatrix.h> // for TGeoMatrix +#include <TGeoNode.h> // for TGeoIterator, TGeoNode +#include <TGeoVolume.h> // for TGeoVolume +#include <TRandom.h> // for TRandom, gRandom + +#include <string> // for operator<, stoul +#include <utility> // for pair + +#include <stddef.h> // for size_t + +using namespace std; + +CbmFsdDetectorMapManager::CbmFsdDetectorMapManager() : fModulePathToIdMap(), fModuleIdToDataMap(), fModuleIds() +{ + Init(); +} + +CbmFsdDetectorMapManager::~CbmFsdDetectorMapManager() {} + +void CbmFsdDetectorMapManager::Init() +{ + + fModulePathToIdMap.clear(); + fModuleIdToDataMap.clear(); + fModuleIds.clear(); + + Int_t currentModuleId = 0; + + TGeoIterator geoIterator(gGeoManager->GetTopNode()->GetVolume()); + + TGeoNode* curNode; + TString branchStr("fsd_"); // stored in path of nodes, fsd_geoTag_0 + TString moduleStr("fsdmodule"); + TString scintStr("scintillator"); + geoIterator.Reset(); // safety to reset to "cave" befor the loop starts + while ((curNode = geoIterator())) { + TString nodePath; + geoIterator.GetPath(nodePath); + if (!nodePath.Contains(branchStr)) { + geoIterator.Skip(); // skip current branch when it is not FSD => should speed up + continue; // don't do anything for this branch + } + + TString nodeName(curNode->GetName()); + // FSD detector -> all modules names contain "fsdmodule" + if (TString(curNode->GetVolume()->GetName()).Contains(moduleStr)) { + + const TGeoMatrix* curMatrix = geoIterator.GetCurrentMatrix(); + const Double_t* curNodeTr = curMatrix->GetTranslation(); + string path = string(nodePath.Data()); + + TGeoVolume* curScintillator = nullptr; + for (int idn = 0; idn < curNode->GetNdaughters(); idn++) { + TGeoNode* daughterNode = curNode->GetDaughter(idn); + if (TString(daughterNode->GetVolume()->GetName()).Contains(scintStr)) { + curScintillator = daughterNode->GetVolume(); + break; + } + } + const TGeoBBox* shape = (const TGeoBBox*) (curScintillator->GetShape()); + + fModulePathToIdMap.insert(pair<string, Int_t>(path, currentModuleId)); + CbmFsdModuleData* moduleData = new CbmFsdModuleData(); + moduleData->fX = curNodeTr[0]; + moduleData->fY = curNodeTr[1]; + moduleData->fZ = curNodeTr[2]; + moduleData->dX = shape->GetDX(); + moduleData->dY = shape->GetDY(); + moduleData->dZ = shape->GetDZ(); + moduleData->fId = currentModuleId; + fModuleIdToDataMap.insert(pair<Int_t, CbmFsdModuleData*>(moduleData->fId, moduleData)); + fModuleIds.push_back(currentModuleId); + currentModuleId++; + } + } + + LOG(info) << "CbmFsdDetectorMapManager is initialized"; + LOG(info) << "fModulePathToIdMap.size() = " << fModulePathToIdMap.size(); + LOG(info) << "fModuleIdToDataMap.size() = " << fModuleIdToDataMap.size(); +} + +Int_t CbmFsdDetectorMapManager::GetModuleIdByPath(const string& path) +{ + std::map<string, Int_t>::iterator it; + it = fModulePathToIdMap.find(path); + if (it == fModulePathToIdMap.end()) return -1; + return it->second; +} + + +CbmFsdModuleData* CbmFsdDetectorMapManager::GetModuleDataById(Int_t modId) +{ + std::map<Int_t, CbmFsdModuleData*>::iterator it; + it = fModuleIdToDataMap.find(modId); + if (it == fModuleIdToDataMap.end()) return nullptr; + return it->second; +} + +vector<Int_t> CbmFsdDetectorMapManager::GetModuleIds() { return fModuleIds; } diff --git a/core/detectors/fsd/CbmFsdDetectorMapManager.h b/core/detectors/fsd/CbmFsdDetectorMapManager.h new file mode 100644 index 0000000000000000000000000000000000000000..5afe83850a7cfbaa33a64f6da51d1f88586a01d2 --- /dev/null +++ b/core/detectors/fsd/CbmFsdDetectorMapManager.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2023 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen + SPDX-License-Identifier: GPL-3.0-only + Authors: Lukas Chlad [committer] */ + +#ifndef CBMFSDDETECTORMAPMANAGER_H +#define CBMFSDDETECTORMAPMANAGER_H + +#include <RtypesCore.h> // for Int_t, Double_t + +#include <iostream> // for string +#include <map> // for map +#include <vector> // for vector + +struct CbmFsdModuleData; + +class CbmFsdDetectorMapManager { + +private: + /** Default constructor **/ + CbmFsdDetectorMapManager(); + + /** Default destructor **/ + ~CbmFsdDetectorMapManager(); + +public: + CbmFsdDetectorMapManager(const CbmFsdDetectorMapManager&) = delete; + CbmFsdDetectorMapManager& operator=(const CbmFsdDetectorMapManager&) = delete; + + /** + * Return Instance of CbmFsdDetectorMapManager. + */ + static CbmFsdDetectorMapManager& GetInstance() + { + static CbmFsdDetectorMapManager fInstance; + return fInstance; + } + + /* + * \brief Return digi moduleId by path to node. + */ + Int_t GetModuleIdByPath(const std::string& path); + + /* + * \brief Return CbmFsdModuleData by digi moduleId. + */ + CbmFsdModuleData* GetModuleDataById(Int_t id); + + /* + * \brief Return ids of all modules + */ + std::vector<Int_t> GetModuleIds(); + +private: + std::map<std::string, Int_t> fModulePathToIdMap; + std::map<Int_t, CbmFsdModuleData*> fModuleIdToDataMap; + std::vector<Int_t> fModuleIds; // vector of all module ids + + /* + * \brief Initialize maps. + */ + void Init(); +}; + +#endif /* CBMFSDDETECTORMAPMANAGER_H */