diff --git a/algo/detectors/bmon/CalibrateSetup.h b/algo/detectors/bmon/CalibrateSetup.h index eeeb58e1784c7ff8896bb5050157171aff162e79..975175a10e60f3a16140a9459c16c3a6097769df 100644 --- a/algo/detectors/bmon/CalibrateSetup.h +++ b/algo/detectors/bmon/CalibrateSetup.h @@ -32,7 +32,7 @@ namespace cbm::algo::bmon CBM_YAML_PROPERTIES(yaml::Property(&Channel::vCPTOff, "vCPTOff", "CPT offset"), yaml::Property(&Channel::vCPTotGain, "vCPTotGain", "CP time over threshold gain"), yaml::Property(&Channel::vCPTotOff, "vCPTotOff", "CP time over threshold offset"), - yaml::Property(&Channel::vCPWalk, "vCPWalk", "CP walk correction", YAML::Block, YAML::Flow)); + yaml::Property(&Channel::vCPWalk, "vCPWalk", "CP walk correction", YAML::Flow)); }; struct Diamond { @@ -44,7 +44,7 @@ namespace cbm::algo::bmon std::vector<Channel> chanPar; CBM_YAML_PROPERTIES( - yaml::Property(&Diamond::refAddress, "refAddress", "reference HW address to distinguish this BMON"), + yaml::Property(&Diamond::refAddress, "refAddress", "reference HW address to distinguish this BMON", YAML::Hex), yaml::Property(&Diamond::numClWalkBinX, "numClWalkBinX", "number of walk correction bins"), yaml::Property(&Diamond::TOTMax, "TOTMax", "maximum time over threshold"), yaml::Property(&Diamond::TOTMin, "TOTMin", "minimum time over threshold"), @@ -57,7 +57,7 @@ namespace cbm::algo::bmon std::vector<Diamond> diamonds; CBM_YAML_PROPERTIES( - yaml::Property(&CalibrateSetup::selectionMask, "selectionMask", "A bit mask to distinguish between different diamonds"), + yaml::Property(&CalibrateSetup::selectionMask, "selectionMask", "A bit mask to distinguish between different diamonds", YAML::Hex), yaml::Property(&CalibrateSetup::diamonds, "diamonds", "Parameters of each diamond")); }; diff --git a/algo/detectors/bmon/HitfindSetup.h b/algo/detectors/bmon/HitfindSetup.h index c958cbc17ca2ffcdc2f5027a42f3e6f8f09b1e22..96431fb0268c67883093e873ddaa06e80ed6c575 100644 --- a/algo/detectors/bmon/HitfindSetup.h +++ b/algo/detectors/bmon/HitfindSetup.h @@ -27,8 +27,8 @@ namespace cbm::algo::bmon double timeRes; CBM_YAML_PROPERTIES( - yaml::Property(&Diamond::refAddress, "refAddress", "reference address of the diamond"), - yaml::Property(&Diamond::deadStrips, "deadStrips", "bit mask for dead strips"), + yaml::Property(&Diamond::refAddress, "refAddress", "reference address of the diamond", YAML::Hex), + yaml::Property(&Diamond::deadStrips, "deadStrips", "bit mask for dead strips", YAML::Hex), yaml::Property(&Diamond::maxTimeDist, "maxTimeDist", "maximum time distance"), yaml::Property(&Diamond::timeRes, "timeRes", "time resolution")); }; @@ -37,7 +37,7 @@ namespace cbm::algo::bmon std::vector<Diamond> diamonds; CBM_YAML_PROPERTIES( - yaml::Property(&HitfindSetup::selectionMask, "selectionMask", "A bit mask to distinguish between different diamonds"), + yaml::Property(&HitfindSetup::selectionMask, "selectionMask", "A bit mask to distinguish between different diamonds", YAML::Hex), yaml::Property(&HitfindSetup::diamonds, "diamonds", "Parameters of diamonds")); }; } // namespace cbm::algo::bmon diff --git a/macro/beamtime/mcbm2022/ini_tof_clusterizer.C b/macro/beamtime/mcbm2022/ini_tof_clusterizer.C index 0d3a29489dbf54044dc7f4eee606109fef6ffbcc..80e37ff27a6697aed41719ef4a886aec22f0094a 100644 --- a/macro/beamtime/mcbm2022/ini_tof_clusterizer.C +++ b/macro/beamtime/mcbm2022/ini_tof_clusterizer.C @@ -55,8 +55,9 @@ void ini_tof_clusterizer(Int_t calMode = 53, Int_t calSel = 0, Int_t calSm = 900 if (cCalId != "XXX") cFname = Form("%s/%s_set%09d_%02d_%01dtofClust.hst.root", parPath.Data(), cCalId.Data(), iCalSet, calMode, calSelRead); - - if (cCalId == "2391_1" || cCalId == "3026_1" || cCalId == "3310_1") cFname = Form("%s/%s_TofCal.hst.root", parPath.Data(), cCalId.Data()); + + if (cCalId == "2391_1" || cCalId == "3026_1" || cCalId == "3310_1") + cFname = Form("%s/%s_TofCal.hst.root", parPath.Data(), cCalId.Data()); tofClust->SetCalParFileName(cFname); LOG(info) << "\n\n!!!!! Using TOF calibration " << cFname << " !!!!!\n\n"; diff --git a/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C b/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C index aaf4f130dc1c81107fe9840d0aee8271cff30b34..24ae06b13f9de393a4771e0615d15bb3776a0d6b 100644 --- a/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C +++ b/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C @@ -121,7 +121,7 @@ Bool_t mcbm_event_reco_L1(UInt_t uRunId = 3453, if (uRunId >= 2900) cCalId = "3026_1"; if (uRunId >= 3399) cCalId = "3310_1"; - // NOTE: To introduce here a new run, one has to add a selection of the cCalId in line 59 of macro + // NOTE: To introduce here a new run, one has to add a selection of the corresponding cCalId in line 59 of macro // macro/beamtime/mcbm2022/ini_tof_clusterizer.C. Int_t iCalSet = 30040500; // calibration settings @@ -135,7 +135,7 @@ Bool_t mcbm_event_reco_L1(UInt_t uRunId = 3453, Double_t Tint = 100.; // coincidence time interval Int_t iTrackMode = 2; // 2 for TofTracker const Int_t iTofCluMode = 1; - + // ------------------------------------------------------------------------ // --- Load the geometry setup ---- diff --git a/reco/tasks/CbmTaskTofClusterizerParWrite.cxx b/reco/tasks/CbmTaskTofClusterizerParWrite.cxx index ee6a4448aa945497970231a1cd3b6de13773782c..e8e8df40802b660799adb94422150c823bd595cb 100644 --- a/reco/tasks/CbmTaskTofClusterizerParWrite.cxx +++ b/reco/tasks/CbmTaskTofClusterizerParWrite.cxx @@ -20,6 +20,8 @@ #include "FairRootManager.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" +#include "bmon/CalibrateSetup.h" +#include "bmon/HitfindSetup.h" #include "tof/CalibrateSetup.h" #include "tof/HitfindSetup.h" #include "yaml/Yaml.h" @@ -88,7 +90,8 @@ InitStatus CbmTaskTofClusterizerParWrite::Init() LOG(info) << "CbmTaskTofClusterizerParWrite initializing... expect Digis in ns units! "; if (false == InitParameters()) return kFATAL; if (false == InitCalibParameter()) return kFATAL; - if (false == InitAlgos()) return kFATAL; + if (false == InitAlgosTof()) return kFATAL; + if (false == InitAlgosBmon()) return kFATAL; return kSUCCESS; } @@ -406,7 +409,7 @@ bool CbmTaskTofClusterizerParWrite::InitCalibParameter() return true; } -bool CbmTaskTofClusterizerParWrite::InitAlgos() +bool CbmTaskTofClusterizerParWrite::InitAlgosTof() { // Needed as external TOT values might be different than ones used for input histo reading (TO DO: FIX) if (fTotMax != 0.) fdTOTMax = fTotMax; @@ -542,3 +545,103 @@ bool CbmTaskTofClusterizerParWrite::InitAlgos() return true; } + + +bool CbmTaskTofClusterizerParWrite::InitAlgosBmon() +{ + // Needed as external TOT values might be different than ones used for input histo reading (TO DO: FIX) + if (fTotMax != 0.) fdTOTMax = fTotMax; + if (fTotMin != 0.) fdTOTMin = fTotMin; + LOG(info) << "ToT init to Min " << fdTOTMin << " Max " << fdTOTMax; + + /// Go to Top volume of the geometry in the GeoManager to make sure our nodes are found + gGeoManager->CdTop(); + + int32_t iNbSmTypes = fDigiBdfPar->GetNbSmTypes(); + + // Create map with unique detector IDs and fill (needed only for dead strip array) + std::map<uint32_t, uint32_t> detIdIndexMap; + for (int32_t ind = 0; ind < fDigiBdfPar->GetNbDet(); ind++) { + int32_t iUniqueId = fDigiBdfPar->GetDetUId(ind); + detIdIndexMap[iUniqueId] = ind; + } + + // Provide a selection mask between different diamonds + auto EstimateSelectionMask = [&](const auto& diamonds) -> uint32_t { + uint32_t selectionMask = 0; + for (auto itL = diamonds.begin(); itL != diamonds.end(); ++itL) { + for (auto itR = std::next(itL); itR != diamonds.end(); ++itR) { + selectionMask |= (itL->refAddress ^ itR->refAddress); + } + } + return selectionMask; + }; + + + /* Hitfinding parameters */ + int32_t iNbSm = fDigiBdfPar->GetNbSm(kBmonAssignedSmType); + int32_t iNbRpc = fDigiBdfPar->GetNbRpc(kBmonAssignedSmType); + + cbm::algo::bmon::HitfindSetup setupHit; + cbm::algo::bmon::CalibrateSetup setupCal; + setupCal.diamonds.resize(iNbSm * iNbRpc); + setupHit.diamonds.resize(iNbSm * iNbRpc); + + for (int32_t iSm = 0; iSm < iNbSm; iSm++) { + for (int32_t iRpc = 0; iRpc < iNbRpc; iRpc++) { + + const int32_t rpcAddress = CbmTofAddress::GetUniqueAddress(iSm, iRpc, 0, 0, kBmonAssignedSmType); + CbmTofCell* channelInfo = fDigiPar->GetCell(rpcAddress); + if (channelInfo == nullptr) { + continue; + } + + //* Hitfinder + const int32_t iDetIndx = detIdIndexMap[rpcAddress]; + cbm::algo::bmon::HitfindSetup::Diamond parHit; + parHit.refAddress = rpcAddress; + parHit.deadStrips = fvDeadStrips[iDetIndx]; + parHit.maxTimeDist = fdMaxTimeDist; + parHit.timeRes = 0.08; + + setupHit.diamonds[iSm * iNbRpc + iRpc] = parHit; + + //* Calibration + cbm::algo::bmon::CalibrateSetup::Diamond parCal; + parCal.refAddress = rpcAddress; + parCal.numClWalkBinX = nbClWalkBinX; + parCal.TOTMax = fdTOTMax; + parCal.TOTMin = fdTOTMin; + parCal.channelDeadtime = fdChannelDeadtime; + int32_t iNbChan = fDigiBdfPar->GetNbChan(kBmonAssignedSmType, iRpc); + parCal.chanPar.resize(iNbChan); + + for (int32_t iCh = 0; iCh < iNbChan; iCh++) { + cbm::algo::bmon::CalibrateSetup::Channel& chan = parCal.chanPar[iCh]; + + chan.vCPTOff = fvCPTOff[kBmonAssignedSmType][iSm * iNbRpc + iRpc][iCh][kBmonAssignedSide]; + chan.vCPTotGain = fvCPTotGain[kBmonAssignedSmType][iSm * iNbRpc + iRpc][iCh][kBmonAssignedSide]; + chan.vCPTotOff = fvCPTotOff[kBmonAssignedSmType][iSm * iNbRpc + iRpc][iCh][kBmonAssignedSide]; + chan.vCPWalk = fvCPWalk[kBmonAssignedSmType][iSm * iNbRpc + iRpc][iCh][kBmonAssignedSide]; + } + + setupCal.diamonds[iSm * iNbRpc + iRpc] = parCal; + } // iRpc + } // iSm + setupHit.selectionMask = EstimateSelectionMask(setupHit.diamonds); + setupCal.selectionMask = setupHit.selectionMask; + + + /* Write Yaml files */ + + cbm::algo::yaml::Dump dump; + std::ofstream fout("BmonHitfinderPar.yaml"); + fout << dump(setupHit); + fout.close(); + + std::ofstream fcalout("BmonCalibratePar.yaml"); + fcalout << dump(setupCal); + fcalout.close(); + + return true; +} diff --git a/reco/tasks/CbmTaskTofClusterizerParWrite.h b/reco/tasks/CbmTaskTofClusterizerParWrite.h index 80fe8bf0d713fab8b02982d1bbbea1ff89db8031..7e2adcfe8c4172819fd8f2441c4f280a129b0161 100644 --- a/reco/tasks/CbmTaskTofClusterizerParWrite.h +++ b/reco/tasks/CbmTaskTofClusterizerParWrite.h @@ -30,6 +30,9 @@ class TClonesArray; class CbmTaskTofClusterizerParWrite : public FairTask { public: + static constexpr int kBmonAssignedSmType = 5; ///< A SmType, assigned to BMON diamonds + static constexpr int kBmonAssignedSide = 0; ///< An RPC side, assigned to BMON diamonds + /** ** @brief Constructor. **/ @@ -104,9 +107,14 @@ class CbmTaskTofClusterizerParWrite : public FairTask { bool InitCalibParameter(); /** - ** @brief Create one algo object for each RPC + ** @brief Create one algo object for each TOF RPC **/ - bool InitAlgos(); + bool InitAlgosTof(); + + /** @brief Creates hit-finding and calibration parameters for BMON diamonds + ** + **/ + bool InitAlgosBmon(); // ToF geometry variables CbmTofDetectorId* fTofId;