diff --git a/algo/ca/core/tracking/CaTrackFinder.cxx b/algo/ca/core/tracking/CaTrackFinder.cxx index fc34c42f17b6ced732f6f61b2c7de1f95f72399c..2c9e66da7533c53b6dba0640ab46ea3a4c101f49 100644 --- a/algo/ca/core/tracking/CaTrackFinder.cxx +++ b/algo/ca/core/tracking/CaTrackFinder.cxx @@ -71,7 +71,7 @@ namespace cbm::algo::ca Vector<ca::HitIndex_t>& recoHits = output.second; //packed hits of reconstructed tracks if (input.GetNhits() < 1) { - LOG(warn) << "No hits were passed to the ca::TrackFinder. Stopping the routine"; + LOG(debug) << "No hits were passed to the ca::TrackFinder. Stopping the routine"; return output; } 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/alignment/run_BbaAlignment_mcbm.C b/macro/alignment/run_BbaAlignment_mcbm.C index 2607632273dc23161bd4951f88b6083787329587..4592f514d2a2e5e27524da1dd634df34378d9c0c 100644 --- a/macro/alignment/run_BbaAlignment_mcbm.C +++ b/macro/alignment/run_BbaAlignment_mcbm.C @@ -144,6 +144,7 @@ void run_BbaAlignment_mcbm(Int_t nEvents = -1, TString dataset = "data/mcbm_beam // ----- BBA alignment -------------------------------------------- CbmBbaAlignmentTask* alignment = new CbmBbaAlignmentTask(); + alignment->SetMatrixOutFileName(Form("AlignmentMatrices_%s_finetuning.root", setupName.Data())); alignment->SetMcbmTrackingMode(); alignment->SetSimulatedMisalignmentRange(SimulatedMisalignmentRange); diff --git a/macro/beamtime/CMakeLists.txt b/macro/beamtime/CMakeLists.txt index 6f5c5649214f13359a95e3c588e19c35ddef21c6..4a20b41b8208c3a157a5215b35fa257aec0cf786 100644 --- a/macro/beamtime/CMakeLists.txt +++ b/macro/beamtime/CMakeLists.txt @@ -5,6 +5,8 @@ add_subdirectory(mcbm2021) add_subdirectory(mcbm2022) # mCBM 2024: install parameter files add_subdirectory(mcbm2024) +# Common scripts/configs for beamtime +add_subdirectory(common) ################################################################################ #--- Deprecated (not running) diff --git a/macro/beamtime/common/.rootrc b/macro/beamtime/common/.rootrc new file mode 100644 index 0000000000000000000000000000000000000000..e20b6c43f21a332e0fd5b28d52a04224f6a645c5 --- /dev/null +++ b/macro/beamtime/common/.rootrc @@ -0,0 +1,4 @@ +# Load the rootalias file from the macro/include directory. +# The file contains some functions which are needed for several different ROOT macros. +# Instead of putting them in all ROOT macros they are defined only once and can be used everywhere. +Rint.Load: $VMCWORKDIR/macro/include/rootalias.C diff --git a/macro/beamtime/common/CMakeLists.txt b/macro/beamtime/common/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..62107b9d4a4ed6883aaf94a04638fd8f96b1efda --- /dev/null +++ b/macro/beamtime/common/CMakeLists.txt @@ -0,0 +1,35 @@ + +# ROOT macros, par files, documentation files, bash scripts +Install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION share/cbmroot/macro/beamtime + FILES_MATCHING PATTERN "*.C" + PATTERN "*.par" + PATTERN "*.md" + PATTERN "*.sh" + ) +# # RICH calibration file, resolve symlink to get the full file +# get_filename_component(_resolvedRichFile ${CMAKE_CURRENT_SOURCE_DIR}/icd_offset_it_0.data REALPATH) +# Install(FILES ${_resolvedRichFile} +# DESTINATION share/cbmroot/macro/beamtime/mcbm2022 +# ) + +# SLURM scripts, bash scripts +Install(DIRECTORY online + DESTINATION share/cbmroot/macro/beamtime/common + FILES_MATCHING PATTERN "*.sbatch" + PATTERN "*.sh" + ) + +# Just the empty folder for output +Install(DIRECTORY data + DESTINATION share/cbmroot/macro/beamtime/common + PATTERN "*" EXCLUDE) + +If(DEFINED ENV{RAW_DATA_PATH} ) + # ===== Copy the .rootrc file into the directory from which root is executed + # --- Otherwise the rootalias file is not loaded + file(COPY ${CBMROOT_SOURCE_DIR}/macro/include/.rootrc + DESTINATION ${CBMROOT_BINARY_DIR}/macro/beamtime/common) + +EndIf() # If(DEFINED ENV{RAW_DATA_PATH} ) + diff --git a/macro/beamtime/mcbm2024/reco_mcbm.sh b/macro/beamtime/common/reco_mcbm.sh similarity index 92% rename from macro/beamtime/mcbm2024/reco_mcbm.sh rename to macro/beamtime/common/reco_mcbm.sh index f004b131b993ba68abf4cfa365f8a1d8b334b348..e49c650819ac3acb4d0d8343fbcecbe4a9f4f3f3 100755 --- a/macro/beamtime/mcbm2024/reco_mcbm.sh +++ b/macro/beamtime/common/reco_mcbm.sh @@ -8,6 +8,10 @@ # @since 21.05.2024 # @author Sergei Zharko <s.zharko@gsi.de> # +# TODO: +# - set digi-event input +# - replace mcbm_reco_event_L1.C with a binary +# # ********************************************************************************************************************** # *** User Manual (v. 0.1.0, 22.01.2025) *** # ********************************************************************************************************************** @@ -29,7 +33,7 @@ # - TSA file unpacking [--unpack] # - reconstruction [--reco] # - main QA [--qa] -# - reconstruciton QA (Alex) [--qa-module] +# - reconstruction QA (Alex) [--qa-module] # - KF Particle Finder (Lambda) [--kfpf] # # Required options: @@ -74,7 +78,7 @@ # <kfp.ana>: Output from the lambda analysis: <top_dir>/<label>.kfp.ana.root # [optional] QA file: <top_dir>/<label>.qa.kfp.ana.root # -# 4. Knwon missing features +# 4. Known missing features # # - Script and its sub-process is not killed if CTEST is stopped with CTRL+C # - Error in reco of run 3105: @@ -141,6 +145,7 @@ DO_RECO=0 DO_QA=0 # Main QA Macro DO_QA_MODULE=0 # QA Macro by Alexandru DO_LAMBDA=0 # Lambda analysis using KFParticleFinder +DO_BBA=0 # BBA alignment on reconstructed data STEPS_TO_PRINT="" ONLINE_PAR=${VMCWORKDIR}/parameters/online @@ -152,6 +157,7 @@ DIR_UNPACK="" DIR_RECO="" DIR_QA="" DIR_KFPF="" +DIR_BBA="" # ----- Run information RUN=-1 @@ -186,6 +192,10 @@ while [[ $# -gt 0 ]]; do DO_LAMBDA=1 STEPS_TO_PRINT="${STEPS_TO_PRINT} --kfpf" ;; + --bba ) + DO_BBA=1 + STEPS_TO_PRINT="${STEPS_TO_PRINT} --bba" + ;; --tsa ) TSA=${2} ;; @@ -219,6 +229,9 @@ while [[ $# -gt 0 ]]; do --kfpf-dir ) DIR_KFPF=${2} ;; + --bba-dir ) + DIR_BBA=${2} + ;; --setup-only ) I_WANT_ONLY_SETUP=1 ;; @@ -267,6 +280,11 @@ else DIR_KFPF=$(realpath -m ${DIR_KFPF}) fi +if [[ -z ${DIR_BBA} ]]; then + DIR_BBA=${DATA_TOP_DIR} +else + DIR_BBA=$(realpath -m ${DIR_KFPF}) +fi # ----- Check the environment # @@ -334,6 +352,7 @@ if [[ ${I_WANT_ONLY_SETUP} -eq 1 ]]; then DO_QA=0 DO_QA_MODULE=0 DO_LAMBDA=0 + DO_BBA=0 STEPS_TO_PRINT=" --setup" if [[ ${RUN} -lt 0 ]]; then RUN=${RUN_IF_ONLY_SETUP_NEEDED} @@ -364,15 +383,18 @@ MACRO_RECO="${VMCWORKDIR}/macro/beamtime/mcbm2022/mcbm_event_reco_L1.C" MACRO_QA="${VMCWORKDIR}/macro/mcbm/mcbm_qa.C" MACRO_QA_MODULE="${VMCWORKDIR}/macro/qa/run_recoQa.C" MACRO_KFPF="${VMCWORKDIR}/macro/mcbm/mcbm_hadron_kfp_ana.C" +MACRO_BBA="${VMCWORKDIR}/macro/alignment/run_BbaAlignment_mcbm.C" SETUP_NAME=$(${RUN_INFO} --run ${RUN} --geotag) # ----- Setting selections vs. run number # if [[ ${RUN} -ge 2350 && ${RUN} -le 2610 ]]; then MACRO_RECO="${VMCWORKDIR}/macro/beamtime/mcbm2022/mcbm_event_reco_L1.C" -elif [[ ${RUN} -ge 2724 ]]; then +elif [[ ${RUN} -ge 2724 && ${RUN} -le 3199 ]]; then MACRO_RECO="${VMCWORKDIR}/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C" -else +elif [[ ${RUN} -ge 3400 ]]; then + MACRO_RECO="${VMCWORKDIR}/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C" +else printf "E- Run %5d is undefined. Exiting" "${RUN}" exit 4 fi @@ -392,7 +414,7 @@ RECO_FILE="${DIR_RECO}/${FILE_LABEL}.rec.root" KF_SETUP_FILE="${DIR_RECO}/${FILE_LABEL}.rec.kf.setup" KF_MATERIAL="${DIR_RECO}/${SETUP_NAME}.mat.kf.bin" CA_PAR_FILE="${DIR_RECO}/${FILE_LABEL}.rec.ca.par" - +BBA_FILE="${DIR_BBA}/${FILE_LABEL}.ali.root" # ----- # Log Files @@ -597,5 +619,32 @@ if [[ ${DO_LAMBDA} -eq 1 ]]; then root -b -l -q ${MACRO_KFPF}"(${PARS})" fi +# ----- Run BBA alignment +if [[ ${DO_BBA} -eq 1 ]]; then + BBA_REC="${DIR_BBA}/${FILE_LABEL}.rec.root" + BBA_GEO="${DIR_BBA}/${FILE_LABEL}.geo.root" + BBA_PAR="${DIR_BBA}/${FILE_LABEL}.par.root" + if [[ ${BBA_REC} != ${RECO_FILE} ]]; then + pushd . + cd ${DIR_BBA} + ln -s -f $(realpath ${RECO_FILE}) $(basename ${BBA_REC}) + popd + fi + if [[ ${BBA_GEO} != ${SETUP_GEO_FILE} ]]; then + pushd . + cd ${DIR_BBA} + ln -s -f $(realpath ${SETUP_GEO_FILE}) $(basename ${BBA_GEO}) + popd + fi + if [[ ${BBA_PAR} != ${RECO_PAR_FILE} ]]; then + pushd . + cd ${DIR_BBA} + ln -s -f $(realpath ${RECO_PAR_FILE}) $(basename ${BBA_PAR}) + popd + fi + BBA_DATASET="${DIR_BBA}/${FILE_LABEL}" + PARS="0,\"${BBA_DATASET}\",\"${SETUP_NAME}\",0.,kFALSE"; + root -b -l -q ${MACRO_BBA}"(${PARS})" +fi printf "Reconstruction of %s succeeded\n" "${TSA_INP}" diff --git a/macro/beamtime/mcbm2024/reco_mcbm_job.sh b/macro/beamtime/common/reco_mcbm_job.sh similarity index 100% rename from macro/beamtime/mcbm2024/reco_mcbm_job.sh rename to macro/beamtime/common/reco_mcbm_job.sh diff --git a/macro/beamtime/mcbm2022/ini_tof_clusterizer.C b/macro/beamtime/mcbm2022/ini_tof_clusterizer.C index f755cf471c19460032944eddbc366989467efc87..80e37ff27a6697aed41719ef4a886aec22f0094a 100644 --- a/macro/beamtime/mcbm2022/ini_tof_clusterizer.C +++ b/macro/beamtime/mcbm2022/ini_tof_clusterizer.C @@ -55,7 +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") 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/mcbm2022/mcbm_event_reco_L1.C b/macro/beamtime/mcbm2022/mcbm_event_reco_L1.C index 35ba48cbc86fd0b1903198e4caaef9e4bc2fee1b..5b24ce5b67017aa1a26ce2b31f80f7a535558a12 100644 --- a/macro/beamtime/mcbm2022/mcbm_event_reco_L1.C +++ b/macro/beamtime/mcbm2022/mcbm_event_reco_L1.C @@ -629,6 +629,11 @@ Bool_t mcbm_event_reco_L1(UInt_t uRunId = 2570, CbmL1GlobalTrackFinder* globalTrackFinder = new CbmL1GlobalTrackFinder(); FairTask* globalFindTracks = new CbmL1GlobalFindTracksEvents(globalTrackFinder); run->AddTask(globalFindTracks); + + auto* trdLI = new CbmTrdSetTracksPidLike("TRDLikelihood", "TRDLikelihood"); + trdLI->SetUseMCInfo(false); + trdLI->SetUseMomDependence(false); + run->AddTask(trdLI); } // ========================================================================= // === QA === diff --git a/macro/beamtime/mcbm2024/CMakeLists.txt b/macro/beamtime/mcbm2024/CMakeLists.txt index 99eb9954c6a9c0998367e1f7a8d18bf6a4bc40c4..b7c7ff3d0b75d7b31452c01ce95698ef2ae1bb02 100644 --- a/macro/beamtime/mcbm2024/CMakeLists.txt +++ b/macro/beamtime/mcbm2024/CMakeLists.txt @@ -48,7 +48,7 @@ If(DEFINED ENV{RAW_DATA_PATH} ) # ============================================================================ # ===== Create test script with all environment needed for the reco chain script - GENERATE_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2024/reco_mcbm.sh) + GENERATE_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/common/reco_mcbm.sh) # ============================================================================ ## Run only if raw data files present: 2024 @@ -84,7 +84,7 @@ If(DEFINED ENV{RAW_DATA_PATH} ) ### Complete reco chain script by S. Zharko Set(testname mcbm_2024_unp_${RUN}) Set(fixture_unp_${RUN} fixture_done_${testname}) - Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2024/reco_mcbm.sh + Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/common/reco_mcbm.sh --tsa ${RAW_DATA_PATH}/${RUN}_first20Ts.tsa --nts ${RECO_TS_NB} --setup --unpack @@ -100,7 +100,7 @@ If(DEFINED ENV{RAW_DATA_PATH} ) Set(testname mcbm_2024_rec_${RUN}) Set(fixture_rec_${RUN} fixture_done_${testname}) - Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2024/reco_mcbm.sh + Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/common/reco_mcbm.sh --tsa ${RAW_DATA_PATH}/${RUN}_first20Ts.tsa --nts ${RECO_TS_NB} --reco @@ -115,7 +115,7 @@ If(DEFINED ENV{RAW_DATA_PATH} ) Set(testname mcbm_2024_qa_${RUN}) Set(fixture_qa_${RUN} fixture_done_${testname}) - Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2024/reco_mcbm.sh + Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/common/reco_mcbm.sh --tsa ${RAW_DATA_PATH}/${RUN}_first20Ts.tsa --nts ${RECO_TS_NB} --qa --qa-module diff --git a/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C b/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C index 67e2848c2159c1ffee29f79bac6e9e4fcc8a43b2..56b57734322e630d7186be05a0d75ca279656719 100644 --- a/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C +++ b/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C @@ -632,6 +632,12 @@ Bool_t mcbm_event_reco_L1(UInt_t uRunId = 3105, FairTask* globalFindTracks = new CbmL1GlobalFindTracksEvents(globalTrackFinder); run->AddTask(globalFindTracks); + auto* trdLI = new CbmTrdSetTracksPidLike("TRDLikelihood", "TRDLikelihood"); + trdLI->SetUseMCInfo(false); + trdLI->SetUseMomDependence(false); + run->AddTask(trdLI); + + if (bPV) { CbmKF* KF = new CbmKF(); run->AddTask(KF); diff --git a/macro/beamtime/mcbm2025/mBmonCriPar.par b/macro/beamtime/mcbm2025/mBmonCriPar.par new file mode 100644 index 0000000000000000000000000000000000000000..3e36f285e2aa7db85a21bad30778d6d52fdc1bf6 --- /dev/null +++ b/macro/beamtime/mcbm2025/mBmonCriPar.par @@ -0,0 +1,35 @@ +#################################################################################################### +[CbmMcbm2018BmonPar] +//---------------------------------------------------------------------------- +NrOfGdpbs: Int_t 5 +GdpbIdArray: Int_t \ +0xabf0 0xabf1 0xabf2 0xabf3 0xabf4 +//0xabf3 0xabf2 0xabf1 0xabf0 +NrOfFeesPerGdpb: Int_t 10 +NrOfGet4PerFee: Int_t 8 +NrOfChannelsPerGet4: Int_t 4 +NrOfGbtx: Int_t 10 +NrOfModule: Int_t 0 +NrOfRpc: Int_t \ + 1 1 1 1 1 +RpcType: Int_t \ + 99 -1 99 -1 99 -1 99 -1 99 -1 +RpcSide: Int_t \ + 0 0 0 0 0 0 0 0 0 0 +ModuleId: Int_t \ + 0 -1 0 -1 0 -1 0 -1 1 -1 +NbMsTot: Int_t 100 +NbMsOverlap: Int_t 1 +SizeMsInNs: Double_t 102400.0 +//SizeMsInNs: Double_t 1638400 +StarTriggerDeadtime: Double_t \ + 1000.0 1000.0 1000.0 1000.0 1000.0 +StarTriggerDelay: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +// 2000.0 2000.0 2000.0 2000.0 2000.0 +//-23000.0 -23000.0 -23000.0 -23000.0 -23000.0 +StarTriggerWinSize: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +TsDeadtimePeriod: Double_t 62.5 + +#################################################################################################### diff --git a/macro/beamtime/mcbm2025/mTofCriPar.par b/macro/beamtime/mcbm2025/mTofCriPar.par new file mode 100644 index 0000000000000000000000000000000000000000..0d070f052f101d9964fb12978f42781adc5e1d7d --- /dev/null +++ b/macro/beamtime/mcbm2025/mTofCriPar.par @@ -0,0 +1,36 @@ +#################################################################################################### +[CbmMcbm2018TofPar] +//---------------------------------------------------------------------------- +McbmTof2024: Int_t 1 +NrOfGdpbs: Int_t 19 +GdpbIdArray: Int_t \ +0xabdd 0xabdc 0xabdb 0xabda 0xabd9 0xabd8 0xabd7 0xabd6 0xabd5 0xabd4 0xabd3 0xabd2 0xabdf 0xabde 0xabc1 0xabc0 0xabd1 0xabd0 0xbbc0 +NrOfFeesPerGdpb: Int_t 5 +NrOfGet4PerFee: Int_t 8 +NrOfChannelsPerGet4: Int_t 4 +NrOfGbtx: Int_t 19 +NrOfModule: Int_t 9 +// NrOfRpc used as RpcId +NrOfRpc: Int_t \ + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 2 +RpcType: Int_t \ + 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 0 2 2 6 +RpcSide: Int_t \ + 1 0 1 0 0 1 0 1 1 0 1 0 0 1 1 0 1 0 5 +ModuleId: Int_t \ + 0 0 1 1 0 0 1 1 2 2 2 2 3 3 4 4 0 0 0 +NbMsTot: Int_t 100 +NbMsOverlap: Int_t 1 +SizeMsInNs: Double_t 102400.0 +//SizeMsInNs: Double_t 1638400 +StarTriggerDeadtime: Double_t \ + 1000.0 1000.0 1000.0 1000.0 1000.0 +StarTriggerDelay: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +// 2000.0 2000.0 2000.0 2000.0 2000.0 +//-23000.0 -23000.0 -23000.0 -23000.0 -23000.0 +StarTriggerWinSize: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +TsDeadtimePeriod: Double_t 62.5 + +#################################################################################################### diff --git a/macro/beamtime/mcbm2025/mTofCriPar_v24e_mcbm.par b/macro/beamtime/mcbm2025/mTofCriPar_v24e_mcbm.par new file mode 100644 index 0000000000000000000000000000000000000000..c93c4f5e7b592ce140231b9a72b905d183a3e6fc --- /dev/null +++ b/macro/beamtime/mcbm2025/mTofCriPar_v24e_mcbm.par @@ -0,0 +1,36 @@ +#################################################################################################### +[CbmMcbm2018TofPar] +//---------------------------------------------------------------------------- +McbmTof2024: Int_t 1 +NrOfGdpbs: Int_t 16 +GdpbIdArray: Int_t \ +0xabdf 0xabde 0xabdd 0xabdc 0xabdb 0xabda 0xabd9 0xabd8 0xabd7 0xabd6 0xabd5 0xabd4 0xabd3 0xabd2 0xabd1 0xabd0 +NrOfFeesPerGdpb: Int_t 5 +NrOfGet4PerFee: Int_t 8 +NrOfChannelsPerGet4: Int_t 4 +NrOfGbtx: Int_t 16 +NrOfModule: Int_t 8 +// NrOfRpc used as RpcId +NrOfRpc: Int_t \ + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 +RpcType: Int_t \ + 2 2 0 0 0 0 1 1 1 1 0 0 1 1 2 2 +RpcSide: Int_t \ + 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 +ModuleId: Int_t \ + 0 0 0 0 1 1 0 0 1 1 2 2 2 2 1 1 +NbMsTot: Int_t 100 +NbMsOverlap: Int_t 1 +SizeMsInNs: Double_t 102400.0 +//SizeMsInNs: Double_t 1638400 +StarTriggerDeadtime: Double_t \ + 1000.0 1000.0 1000.0 1000.0 1000.0 +StarTriggerDelay: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +// 2000.0 2000.0 2000.0 2000.0 2000.0 +//-23000.0 -23000.0 -23000.0 -23000.0 -23000.0 +StarTriggerWinSize: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +TsDeadtimePeriod: Double_t 62.5 + +#################################################################################################### diff --git a/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C b/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C new file mode 100644 index 0000000000000000000000000000000000000000..24ae06b13f9de393a4771e0615d15bb3776a0d6b --- /dev/null +++ b/macro/beamtime/mcbm2025/mcbm_event_reco_L1.C @@ -0,0 +1,765 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/// @file mcbm_event_reco_L1.C +/// @brief Offline reconstruction of real data in mCBM (2025) +/// @since 14.02.2025 +/// @author Sergei Zharko <s.zharko@gsi.de> + + +#include <cmath> +#include <cstdio> +#include <string> + +/// FIXME: Disable clang formatting to keep easy parameters overview +/* clang-format off */ +Bool_t mcbm_event_reco_L1(UInt_t uRunId = 3453, + Int_t nTimeslices = 10, + TString sInpDir = "./data/", + TString sOutDir = "./data/", + Int_t iUnpFileIndex = -1, + Bool_t bMVD = kFALSE, + Bool_t bSTS = kTRUE, + Bool_t bTRD = kTRUE, + Bool_t bTRD2d = kTRUE, + Bool_t bRICH = kTRUE, + Bool_t bMUCH = kFALSE, + Bool_t bTOF = kTRUE, + Bool_t bTOFtr = kFALSE, + Bool_t bPSD = kFALSE, + Bool_t bAli = kTRUE, + Bool_t bEvB = kTRUE, + Bool_t bL1 = kTRUE, + Bool_t bQA = kTRUE, + Bool_t bFSD = kFALSE, + TString sInpFile = "", + Bool_t bPV = kFALSE + ) +{ + /// FIXME: Re-enable clang formatting after parameters initial values setting + /* clang-format on */ + + // --- Logger settings ---------------------------------------------------- + TString logLevel = "INFO"; //"INFO"; + TString logVerbosity = "LOW"; //"VERYLOW"; + // ------------------------------------------------------------------------ + + // ----- Environment -------------------------------------------------- + TString myName = "mcbm_event_reco_L1"; // this macro's name for screen output + TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory + // ------------------------------------------------------------------------ + + + // ----- In- and output file names ------------------------------------ + /// Standardized RUN ID + TString sRunId = TString::Format("%04u", uRunId); + + gSystem->Exec("mkdir -p " + sOutDir); + gSystem->Exec("cp $VMCWORKDIR/macro/run/.rootrc ."); + + TString outFile = sOutDir + "/" + sRunId; + /// Initial pattern + TString inFile = sInpDir + sRunId + ".digi"; + + /// Add index of splitting at unpacking level if needed + if (0 <= iUnpFileIndex) { + inFile += TString::Format("_%02u", iUnpFileIndex); + // the input par file is not split during unpacking! + outFile += TString::Format("_%02u", iUnpFileIndex); + } // if ( 0 <= uUnpFileIndex ) + /// Add ROOT file suffix + inFile += ".root"; + TString parFileOut = outFile + ".par.root"; + TString geoFileOut = outFile + ".geo.root"; + outFile += ".rec.root"; + + if ("" != sInpFile) { + inFile = sInpFile; + outFile = inFile; + outFile.ReplaceAll(".digi.root", ""); + parFileOut = outFile + ".par.root"; + geoFileOut = outFile + ".geo.root"; + outFile += ".rec.root"; + } + // --------------------------------------------- + + + // ----- TOF defaults ------------------------ + // Your folder with the Tof Calibration files; + TString cFileId = sRunId + ".5.000"; + TString TofFileFolder = ""; + + // ===> PAL 2022/11/04: overwriten by block around l.510! + Int_t calMode = 93; + Int_t calSel = 1; + Int_t calSm = 2; + Int_t RefSel = 11; + Double_t dDeadtime = 50.; + Int_t iSel2 = -1; + + // Tracking + Int_t iSel = 22002; + Int_t iTrackingSetup = 1; // 2 for checking without beam counter; + Int_t iGenCor = 1; + Double_t dScalFac = 2.5; + Double_t dChi2Lim2 = 4.; + Bool_t bUseSigCalib = kFALSE; + Int_t iCalOpt = 110; // 0=do not call CbmTofCalibrator + Int_t iTrkPar = 0; // 4 for check without beam counter + Double_t dTOffScal = 1.; + // ------------------------------------------------------------------------ + + // ----- TOF Calibration Settings --------------------------------------- + TString cCalId = "490.100.5.0"; + if (uRunId >= 759) cCalId = "759.100.4.0"; + if (uRunId >= 812) cCalId = "831.100.4.0"; + if (uRunId >= 1588) cCalId = "1588.50.6.0"; + if (uRunId >= 2160) cCalId = "2160.50.4.0"; + if (uRunId >= 2352) cCalId = "2391_1"; + if (uRunId >= 2700) cCalId = "2912.1"; + 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 corresponding cCalId in line 59 of macro + // macro/beamtime/mcbm2022/ini_tof_clusterizer.C. + + Int_t iCalSet = 30040500; // calibration settings + if (uRunId >= 759) iCalSet = 10020500; + if (uRunId >= 812) iCalSet = 10020500; + if (uRunId >= 1588) iCalSet = 12002002; + if (uRunId >= 2160) iCalSet = 700900500; + if (uRunId >= 2352) iCalSet = 22002500; + if (uRunId >= 2700) iCalSet = 12032500; + + Double_t Tint = 100.; // coincidence time interval + Int_t iTrackMode = 2; // 2 for TofTracker + const Int_t iTofCluMode = 1; + + // ------------------------------------------------------------------------ + + // --- Load the geometry setup ---- + // This is currently only required by the TRD (parameters) + cbm::mcbm::ToForceLibLoad dummy; /// Needed to trigger loading of the library as no fct dict in ROOT6 and CLING + TString geoSetupTag = ""; + try { + geoSetupTag = cbm::mcbm::GetSetupFromRunId(uRunId); + } + catch (const std::invalid_argument& e) { + std::cout << "Error in mapping from runID to setup name: " << e.what() << std::endl; + return kFALSE; + } + + TString geoFile = sInpDir + "/" + geoSetupTag + ".geo.root"; + CbmSetup* geoSetup = CbmSetup::Instance(); + geoSetup->LoadSetup(geoSetupTag); + + // You can modify the pre-defined setup by using + geoSetup->SetActive(ECbmModuleId::kMvd, bMVD); + geoSetup->SetActive(ECbmModuleId::kSts, bSTS); + geoSetup->SetActive(ECbmModuleId::kMuch, bMUCH); + geoSetup->SetActive(ECbmModuleId::kRich, bRICH); + geoSetup->SetActive(ECbmModuleId::kTrd, bTRD); + geoSetup->SetActive(ECbmModuleId::kTrd2d, bTRD2d); + geoSetup->SetActive(ECbmModuleId::kTof, bTOF); + geoSetup->SetActive(ECbmModuleId::kPsd, bPSD); + geoSetup->SetActive(ECbmModuleId::kFsd, bFSD); + + + //----- Load Parameters -------------------------------------------------- + TList* parFileList = new TList(); + TofFileFolder = Form("%s/%s", TofFileFolder.Data(), cCalId.Data()); + + // ----- TRD digitisation parameters ------------------------------------- + TString geoTagTrd; + if (geoSetup->IsActive(ECbmModuleId::kTrd)) { + if (geoSetup->GetGeoTag(ECbmModuleId::kTrd, geoTagTrd)) { + TString paramFilesTrd(Form("%s/parameters/trd/trd_%s", srcDir.Data(), geoTagTrd.Data())); + std::vector<TString> paramFilesVecTrd = {"asic", "digi", "gas", "gain"}; + for (auto parIt : paramFilesVecTrd) { + parFileList->Add(new TObjString(Form("%s.%s.par", paramFilesTrd.Data(), parIt.Data()))); + } + } + for (auto parFileVecIt : *parFileList) { + LOG(debug) << Form("TrdParams - %s - added to parameter file list\n", parFileVecIt->GetName()); + } + } + // ----- TOF digitisation parameters ------------------------------------- + TString geoTagTof; + if (geoSetup->IsActive(ECbmModuleId::kTof)) { + geoSetup->GetGeoTag(ECbmModuleId::kTof, geoTagTof); + TObjString* tofBdfFile = new TObjString(srcDir + "/parameters/tof/tof_" + geoTagTof + ".digibdf.par"); + parFileList->Add(tofBdfFile); + std::cout << "-I- " << myName << ": Using parameter file " << tofBdfFile->GetString() << std::endl; + + // TFile* fgeo = new TFile(geoFile); + // TGeoManager* geoMan = (TGeoManager*) fgeo->Get("FAIRGeom"); + // if (NULL == geoMan) { + // cout << "<E> FAIRGeom not found in geoFile " << geoFile.Data() << endl; + // return 1; + // } + } + // ------------------------------------------------------------------------ + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + + // ----- FairRunAna --------------------------------------------------- + FairRunAna* run = new FairRunAna(); + FairFileSource* inputSource = new FairFileSource(inFile); + run->SetSource(inputSource); + + FairRootFileSink* outputSink = new FairRootFileSink(outFile); + run->SetSink(outputSink); + run->SetGeomFile(geoFile); + + // Define output file for FairMonitor histograms + TString monitorFile{outFile}; + monitorFile.ReplaceAll(".rec.root", ".rec.monitor.root"); + FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile); + // ------------------------------------------------------------------------ + + + // ----- Logger settings ---------------------------------------------- + FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data()); + FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data()); + //FairLogger::GetLogger()->SetLogScreenLevel("DEBUG"); + // ------------------------------------------------------------------------ + + + // ========================================================================= + // === Alignment Correction === + // ========================================================================= + // (Fairsoft Apr21p2 or newer is needed) + if (bAli) { + + TString alignmentMatrixFileName = srcDir + "/parameters/mcbm/AlignmentMatrices_" + geoSetupTag + ".root"; + + if (alignmentMatrixFileName.Length() != 0) { + + std::cout << "-I- " << myName << ": Applying alignment for file " << alignmentMatrixFileName << std::endl; + + // Define the basic structure which needs to be filled with information + // This structure is stored in the output file and later passed to the + // FairRoot framework to do the (miss)alignment + std::map<std::string, TGeoHMatrix>* matrices{nullptr}; + + // read matrices from disk + LOG(info) << "Filename: " << alignmentMatrixFileName; + TFile* misalignmentMatrixRootfile = new TFile(alignmentMatrixFileName, "READ"); + if (misalignmentMatrixRootfile->IsOpen()) { + gDirectory->GetObject("MisalignMatrices", matrices); + misalignmentMatrixRootfile->Close(); + } + else { + LOG(error) << "Could not open file " << alignmentMatrixFileName << "\n Exiting"; + exit(1); + } + + if (matrices) { + run->AddAlignmentMatrices(*matrices); + } + else { + LOG(error) << "Alignment required but no matrices found." + << "\n Exiting"; + exit(1); + } + } + } + // ------------------------------------------------------------------------ + + + // --------------------event builder--------------------------------------- + // ----- EventBuilder Settings---------------- + // mCbm track trigger Tof, Bmon & STS (case 4 of mcbm_unp_event.C) + const Int_t eb_TriggerMinNumberBmon{1}; + const Int_t eb_TriggerMaxNumberBmon{2}; + const Int_t eb_TriggerMinNumberSts{1}; + const Int_t eb_TriggerMinNumberStsLayers{1}; + const Int_t eb_TriggerMinNumberMuch{1}; + const Int_t eb_TriggerMinNumberTof{1}; + const Int_t eb_TriggerMinNumberTofLayers{1}; + const Int_t eb_TriggerMinNumberRich{0}; + + const Int_t eb_TrigWinMinBmon{-15}; + const Int_t eb_TrigWinMaxBmon{15}; + const Int_t eb_TrigWinMinSts{-75}; + const Int_t eb_TrigWinMaxSts{75}; + const Int_t eb_TrigWinMinMuch{-50}; + const Int_t eb_TrigWinMaxMuch{500}; + const Int_t eb_TrigWinMinTrd1d{-100}; + const Int_t eb_TrigWinMaxTrd1d{300}; + const Int_t eb_TrigWinMinTrd2d{-75}; + const Int_t eb_TrigWinMaxTrd2d{200}; + const Int_t eb_TrigWinMinTof{-10}; + const Int_t eb_TrigWinMaxTof{40}; + const Int_t eb_TrigWinMinRich{-20}; + const Int_t eb_TrigWinMaxRich{120}; + + //const Int_t eb_TrigWinMinBmon{-65}; + //const Int_t eb_TrigWinMaxBmon{65}; + //const Int_t eb_TrigWinMinSts{-75}; + //const Int_t eb_TrigWinMaxSts{75}; + //const Int_t eb_TrigWinMinMuch{-50}; + //const Int_t eb_TrigWinMaxMuch{500}; + //const Int_t eb_TrigWinMinTrd1d{-100}; + //const Int_t eb_TrigWinMaxTrd1d{300}; + //const Int_t eb_TrigWinMinTrd2d{-100}; + //const Int_t eb_TrigWinMaxTrd2d{350}; + //const Int_t eb_TrigWinMinTof{-10}; + //const Int_t eb_TrigWinMaxTof{70}; + //const Int_t eb_TrigWinMinRich{-20}; + //const Int_t eb_TrigWinMaxRich{120}; + + + if (bEvB) { + CbmTaskBuildRawEvents* evBuildRaw = new CbmTaskBuildRawEvents(); + evBuildRaw->SetVerbose(3); + //Choose between NoOverlap, MergeOverlap, AllowOverlap + evBuildRaw->SetEventOverlapMode(EOverlapModeRaw::AllowOverlap); + //For time being it is needed. We will remove CbmMuchBeamTimeDigi. + evBuildRaw->ChangeMuchBeamtimeDigiFlag(); + // Remove detectors where digis not found + if (!bRICH || !geoSetup->IsActive(ECbmModuleId::kRich)) evBuildRaw->RemoveDetector(kRawEventBuilderDetRich); + if (!bMUCH || !geoSetup->IsActive(ECbmModuleId::kMuch)) evBuildRaw->RemoveDetector(kRawEventBuilderDetMuch); + if (!bPSD || !geoSetup->IsActive(ECbmModuleId::kPsd)) evBuildRaw->RemoveDetector(kRawEventBuilderDetPsd); + if (!bTRD || !geoSetup->IsActive(ECbmModuleId::kTrd)) evBuildRaw->RemoveDetector(kRawEventBuilderDetTrd); + //TODO temporary exclude 2D from event building (asked by M. Beyer) + if (!bTRD2d) evBuildRaw->RemoveDetector(kRawEventBuilderDetTrd2D); + if (!bSTS || !geoSetup->IsActive(ECbmModuleId::kSts)) evBuildRaw->RemoveDetector(kRawEventBuilderDetSts); + if (!bTOF || !geoSetup->IsActive(ECbmModuleId::kTof)) evBuildRaw->RemoveDetector(kRawEventBuilderDetTof); + if (!bFSD || !geoSetup->IsActive(ECbmModuleId::kFsd)) evBuildRaw->RemoveDetector(kRawEventBuilderDetFsd); + + // Set Bmon as reference detector. + // Select only Bmon1 [newly installed for mcbm2024 data] (AB) + //evBuildRaw->SetReferenceDetector(kRawEventBuilderDetBmon, {0, 1}); + // For making MuCh as seed detector + // evBuildRaw->SetReferenceDetector(kRawEventBuilderDetMuch); + evBuildRaw->SetReferenceDetector(kRawEventBuilderDetTof); + + + // Use sliding window seed builder with STS + //evBuildRaw->SetReferenceDetector(kRawEventBuilderDetUndef); + //evBuildRaw->AddSeedTimeFillerToList(kRawEventBuilderDetTof); + //evBuildRaw->SetSlidingWindowSeedFinder(10, 10, 50); + //evBuildRaw->SetSeedFinderQa(true); // optional QA information for seed finder + //evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, 1000); + //evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, -1); + //evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -500, 500); + + // void SetTsParameters(double TsStartTime, double TsLength, double TsOverLength): + // => TsStartTime=0, TsLength=128 + 1.28 ms in 2022, TsOverLength=1.28 ms (1MS) in mCBM2022 + evBuildRaw->SetTsParameters(0.0, 1.28e8, 1.28e6); + + if (geoSetup->IsActive(ECbmModuleId::kTof)) { + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kTof, eb_TriggerMinNumberTof); + evBuildRaw->SetTriggerMinLayersNumber(ECbmModuleId::kTof, eb_TriggerMinNumberTofLayers); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kTof, -1); + } + + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kBmon, eb_TriggerMinNumberBmon); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kBmon, eb_TriggerMaxNumberBmon); + + if (geoSetup->IsActive(ECbmModuleId::kSts)) { + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, eb_TriggerMinNumberSts); + evBuildRaw->SetTriggerMinLayersNumber(ECbmModuleId::kSts, eb_TriggerMinNumberStsLayers); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, -1); + } + if (bMUCH && geoSetup->IsActive(ECbmModuleId::kMuch)) { + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kMuch, eb_TriggerMinNumberMuch); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kMuch, -1); + } + if (geoSetup->IsActive(ECbmModuleId::kRich)) { + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kRich, eb_TriggerMinNumberRich); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kRich, -1); + } + + evBuildRaw->SetTriggerWindow(ECbmModuleId::kBmon, eb_TrigWinMinBmon, eb_TrigWinMaxBmon); + if (geoSetup->IsActive(ECbmModuleId::kTof)) + evBuildRaw->SetTriggerWindow(ECbmModuleId::kTof, eb_TrigWinMinTof, eb_TrigWinMaxTof); + if (geoSetup->IsActive(ECbmModuleId::kSts)) + evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, eb_TrigWinMinSts, eb_TrigWinMaxSts); + if (bMUCH && geoSetup->IsActive(ECbmModuleId::kMuch)) + evBuildRaw->SetTriggerWindow(ECbmModuleId::kMuch, eb_TrigWinMinMuch, eb_TrigWinMaxMuch); + if (geoSetup->IsActive(ECbmModuleId::kTrd)) + evBuildRaw->SetTriggerWindow(ECbmModuleId::kTrd, eb_TrigWinMinTrd1d, eb_TrigWinMaxTrd1d); + if (geoSetup->IsActive(ECbmModuleId::kTrd)) + evBuildRaw->SetTriggerWindow(ECbmModuleId::kTrd2d, eb_TrigWinMinTrd2d, eb_TrigWinMaxTrd2d); + if (geoSetup->IsActive(ECbmModuleId::kRich)) + evBuildRaw->SetTriggerWindow(ECbmModuleId::kRich, eb_TrigWinMinRich, eb_TrigWinMaxRich); + + run->AddTask(evBuildRaw); + } + // ------------------------------------------------------------------------ + + + // ----- Reconstruction tasks ----------------------------------------- + + + // ========================================================================= + // === local STS Reconstruction === + // ========================================================================= + + if (bSTS && geoSetup->IsActive(ECbmModuleId::kSts)) { + CbmRecoSts* recoSts = new CbmRecoSts(); + if (bEvB) { + recoSts->SetMode(ECbmRecoMode::EventByEvent); + } + else { + recoSts->SetMode(ECbmRecoMode::Timeslice); + } + recoSts->SetVerbose(3); + recoSts->SetTimeCutDigisAbs(20.0); // cluster finder: time cut in ns + recoSts->SetTimeCutClustersAbs(20.0); // hit finder: time cut in ns + + // Sensor params + CbmStsParSensor sensor6cm(CbmStsSensorClass::kDssdStereo); + sensor6cm.SetPar(0, 6.2092); // Extension in x + sensor6cm.SetPar(1, 6.2); // Extension in y + sensor6cm.SetPar(2, 0.03); // Extension in z + sensor6cm.SetPar(3, 5.9692); // Active size in y + sensor6cm.SetPar(4, 1024.); // Number of strips front side + sensor6cm.SetPar(5, 1024.); // Number of strips back side + sensor6cm.SetPar(6, 0.0058); // Strip pitch front side + sensor6cm.SetPar(7, 0.0058); // Strip pitch back side + sensor6cm.SetPar(8, 0.0); // Stereo angle front side + sensor6cm.SetPar(9, 7.5); // Stereo angle back side + + CbmStsParSensor sensor12cm(sensor6cm); // copy all parameters, change then only the y size + sensor12cm.SetPar(1, 12.4); // Extension in y + sensor12cm.SetPar(3, 12.1692); // Active size in y + + // --- Addresses for sensors + // --- They are defined in each station as sensor 1, module 1, halfladderD (2), ladder 1 + // Int_t GetAddress(UInt_t unit = 0, UInt_t ladder = 0, UInt_t halfladder = 0, UInt_t module = 0, UInt_t sensor = 0, + // UInt_t side = 0, UInt_t version = kCurrentVersion); + + // setup available starting with sts_v24b. Available if reconstructing from rra files (AB 14.05.2024) + Int_t stsAddress00 = CbmStsAddress::GetAddress(0, 0, 0, 0, 0, 0); // U0 L0 M0 6 cm + Int_t stsAddress01 = CbmStsAddress::GetAddress(1, 0, 1, 0, 0, 0); // U1 L0 M0 6 cm + Int_t stsAddress02 = CbmStsAddress::GetAddress(1, 0, 1, 1, 0, 0); // U1 L0 M1 6 cm + Int_t stsAddress03 = CbmStsAddress::GetAddress(1, 1, 1, 0, 0, 0); // U1 L1 M0 6 cm + Int_t stsAddress04 = CbmStsAddress::GetAddress(1, 1, 1, 1, 0, 0); // U1 L1 M1 6 cm + Int_t stsAddress05 = CbmStsAddress::GetAddress(2, 0, 1, 0, 0, 0); // U2 L0 M0 6 cm + Int_t stsAddress06 = CbmStsAddress::GetAddress(2, 0, 1, 1, 0, 0); // U2 L0 M1 12 cm + Int_t stsAddress07 = CbmStsAddress::GetAddress(2, 1, 1, 0, 0, 0); // U2 L1 M0 6 cm + Int_t stsAddress08 = CbmStsAddress::GetAddress(2, 1, 1, 1, 0, 0); // U2 L1 M1 12 cm + Int_t stsAddress09 = CbmStsAddress::GetAddress(2, 2, 1, 0, 0, 0); // U2 L2 M0 6 cm + Int_t stsAddress10 = CbmStsAddress::GetAddress(2, 2, 1, 1, 0, 0); // U2 L2 M1 6 cm + Int_t stsAddress11 = CbmStsAddress::GetAddress(2, 2, 1, 2, 0, 0); // U2 L2 M2 6 cm + + std::cout << "STS address00 " << std::dec << stsAddress00 << " " << std::hex << stsAddress00 << std::endl; + std::cout << "STS address01 " << std::dec << stsAddress01 << " " << std::hex << stsAddress01 << std::endl; + std::cout << "STS address02 " << std::dec << stsAddress02 << " " << std::hex << stsAddress02 << std::endl; + std::cout << "STS address03 " << std::dec << stsAddress03 << " " << std::hex << stsAddress03 << std::endl; + std::cout << "STS address04 " << std::dec << stsAddress04 << " " << std::hex << stsAddress04 << std::endl; + std::cout << "STS address05 " << std::dec << stsAddress05 << " " << std::hex << stsAddress05 << std::endl; + std::cout << "STS address06 " << std::dec << stsAddress06 << " " << std::hex << stsAddress06 << std::endl; + std::cout << "STS address07 " << std::dec << stsAddress07 << " " << std::hex << stsAddress07 << std::endl; + std::cout << "STS address08 " << std::dec << stsAddress08 << " " << std::hex << stsAddress08 << std::endl; + std::cout << "STS address09 " << std::dec << stsAddress09 << " " << std::hex << stsAddress09 << std::endl; + std::cout << "STS address10 " << std::dec << stsAddress10 << " " << std::hex << stsAddress10 << std::endl; + std::cout << "STS address11 " << std::dec << stsAddress11 << " " << std::hex << stsAddress11 << std::endl; + + // --- Now we can define the sensor parameter set and tell recoSts to use it + auto sensorParSet = new CbmStsParSetSensor("CbmStsParSetSensor", "STS sensor parameters" + "mcbm2024"); + if (stsAddress00) sensorParSet->SetParSensor(stsAddress00, sensor6cm); + sensorParSet->SetParSensor(stsAddress01, sensor6cm); + sensorParSet->SetParSensor(stsAddress02, sensor6cm); + sensorParSet->SetParSensor(stsAddress03, sensor6cm); + sensorParSet->SetParSensor(stsAddress04, sensor6cm); + sensorParSet->SetParSensor(stsAddress05, sensor6cm); + sensorParSet->SetParSensor(stsAddress06, sensor12cm); + sensorParSet->SetParSensor(stsAddress07, sensor6cm); + sensorParSet->SetParSensor(stsAddress08, sensor12cm); + sensorParSet->SetParSensor(stsAddress09, sensor6cm); + sensorParSet->SetParSensor(stsAddress10, sensor6cm); + sensorParSet->SetParSensor(stsAddress11, sensor6cm); + recoSts->UseSensorParSet(sensorParSet); + + // ASIC params: #ADC channels, dyn. range, threshold, time resol., dead time, + // noise RMS, zero-threshold crossing rate + auto parAsic = new CbmStsParAsic(128, 31, 75000., 3000., 5., 800., 1000., 3.9789e-3); + + // Module params: number of channels, number of channels per ASIC + auto parMod = new CbmStsParModule(2048, 128); + parMod->SetAllAsics(*parAsic); + recoSts->UseModulePar(parMod); + + // Sensor conditions: full depletion voltage, bias voltage, temperature, + // coupling capacitance, inter-strip capacitance + auto sensorCond = new CbmStsParSensorCond(70., 140., 268., 17.5, 1.); + recoSts->UseSensorCond(sensorCond); + + run->AddTask(recoSts); + std::cout << "-I- : Added task " << recoSts->GetName() << std::endl; + // ------------------------------------------------------------------------ + } + + // ========================================================================= + // === local MUCH Reconstruction === + // ========================================================================= + if (bMUCH) { + TString muchGeoTag; + if (geoSetup->GetGeoTag(ECbmModuleId::kMuch, muchGeoTag)) { + // --- Parameter file name + TString geoTag; + geoSetup->GetGeoTag(ECbmModuleId::kMuch, geoTag); + Int_t muchFlag = 0; + if (geoTag.Contains("mcbm")) muchFlag = 1; + TString sectorFile = gSystem->Getenv("VMCWORKDIR"); + sectorFile += "/parameters/much/much_" + geoTag(0, 4) + "_mcbm_digi_sector.root"; + //sectorFile += "/parameters/much/much_v22j_mcbm_digi_sector.root"; + std::cout << "Using parameter file " << sectorFile << std::endl; + + // --- Initialization of the digi scheme + auto muchGeoScheme = CbmMuchGeoScheme::Instance(); + if (!muchGeoScheme->IsInitialized()) { + muchGeoScheme->Init(sectorFile.Data(), muchFlag); + } + // --- Hit finder for GEMs + FairTask* muchReco = new CbmMuchFindHitsGem(sectorFile.Data(), muchFlag); + run->AddTask(muchReco); + std::cout << "-I- " << myName << ": Added task " << muchReco->GetName() << " with parameter file " << sectorFile + << std::endl; + } + } + // ------------------------------------------------------------------------ + + // ========================================================================= + // === local TRD Reconstruction === + // ========================================================================= + + if (bTRD && geoSetup->IsActive(ECbmModuleId::kTrd)) { + CbmTrdClusterFinder* trdCluster; + Double_t triggerThreshold = 0.5e-6; // SIS100 + + trdCluster = new CbmTrdClusterFinder(); + trdCluster->SetNeighbourEnable(true, false); + trdCluster->SetMinimumChargeTH(triggerThreshold); + trdCluster->SetRowMerger(true); + CbmTrdClusterFinder::UseRecoHelpers(); + run->AddTask(trdCluster); + std::cout << "-I- : Added task " << trdCluster->GetName() << std::endl; + + CbmTrdHitProducer* trdHit = new CbmTrdHitProducer(); + //trdHit->SetHitTimeOffset(363); // hit time synchronization for TRD2D determined on run 2391 + trdHit->SetHitTimeOffset(80); // hit time synchronization for TRD2D determined on run 2914 + run->AddTask(trdHit); + std::cout << "-I- : Added task " << trdHit->GetName() << std::endl; + } + + // ========================================================================= + // === RICH Reconstruction === + // ========================================================================= + + if (bRICH && geoSetup->IsActive(ECbmModuleId::kRich)) { + // ----- Local reconstruction of RICH Hits ------------------------------ + CbmRichMCbmHitProducer* hitProd = new CbmRichMCbmHitProducer(); + hitProd->SetMappingFile(std::string(srcDir.Data()) + + "/macro/rich/mcbm/beamtime/mRICH_Mapping_vert_20190318_elView.geo"); + hitProd->SetIcdFilenameBase(std::string(srcDir.Data()) + "/macro/beamtime/mcbm2022/icd_offset_it"); + hitProd->setToTLimits(23.7, 30.0); + hitProd->applyToTCut(); + hitProd->applyICDCorrection(); + run->AddTask(hitProd); + // ------------------------------------------------------------------------ + + // ----- Local reconstruction in RICh -> Finding of Rings --------------- + CbmRichReconstruction* richReco = new CbmRichReconstruction(); + richReco->UseMCbmSetup(); + run->AddTask(richReco); + // ------------------------------------------------------------------------ + } + + // ========================================================================= + // === TOF Hitfinding === + // ========================================================================= + + TString parPath = srcDir + "/parameters/mcbm/"; + if (bTOF && geoSetup->IsActive(ECbmModuleId::kTof)) { + TString cFname; + switch (iTofCluMode) { + case 1: { + // ----- TOF defaults ------------------------ + Int_t calMode = 93; + Int_t calSel = 1; + Int_t calSm = 0; + Int_t RefSel = 0; + Double_t dDeadtime = 50.; + Int_t iSel2 = 500; + Bool_t bOut = kTRUE; + + // ------------------------------------------------------------------------ + gROOT->LoadMacro(srcDir + "/macro/beamtime/mcbm2022/ini_tof_clusterizer.C"); + Char_t* cCmd = + Form("ini_tof_clusterizer(%d,%d,%d,%d,\"%s\",%d,%d,%d,%f,\"%s\",\"%s\")", calMode, calSel, calSm, RefSel, + cFileId.Data(), iCalSet, (Int_t) bOut, iSel2, dDeadtime, cCalId.Data(), parPath.Data()); + + cout << "<I> " << cCmd << endl; + gInterpreter->ProcessLine(cCmd); + // disable histogramming + CbmTofEventClusterizer* tofClust = CbmTofEventClusterizer::Instance(); + tofClust->SetDutId(-1); // to disable histogramming + } break; + + default: { + ; + } + } + // ------------------------------------------------------------------------- + + // ========================================================================= + // === Tof Tracking === + // ========================================================================= + + if (bTOFtr) { + cout << "<I> Initialize Tof tracker by ini_trks" << endl; + + gROOT->LoadMacro(srcDir + "/macro/beamtime/mcbm2022/ini_tof_trks.C"); + Char_t* cCmd = + Form("ini_tof_trks(%d,%d,%d,%6.2f,%8.1f,\"%s\",%d,%d,%d,%f,\"%s\")", iSel, iTrackingSetup, iGenCor, dScalFac, + dChi2Lim2, cCalId.Data(), (Int_t) bUseSigCalib, iCalOpt, iTrkPar, dTOffScal, parPath.Data()); + cout << "<I> " << cCmd << endl; + gInterpreter->ProcessLine(cCmd); + + CbmTofFindTracks* tofFindTracks = CbmTofFindTracks::Instance(); + Int_t iNStations = tofFindTracks->GetNStations(); + } + } + + + //Constant Field + // CbmConstField *fMagField = new CbmConstField(); + // fMagField->SetFieldXYZ(0, 0 ,0 ); // values are in kG + // fMagField->SetFieldRegions(-10, -10 ,-10 , 10, 10 , 10 ); + // run->SetField(fMagField); + + // ========================================================================= + // === L1 === + // ========================================================================= + if (bL1) { + run->AddTask(new CbmTrackingDetectorInterfaceInit()); + + CbmL1* l1 = new CbmL1("L1"); + l1->SetMcbmMode(); + l1->SetVerbose(3); + run->AddTask(l1); + + CbmL1GlobalTrackFinder* globalTrackFinder = new CbmL1GlobalTrackFinder(); + FairTask* globalFindTracks = new CbmL1GlobalFindTracksEvents(globalTrackFinder); + run->AddTask(globalFindTracks); + + auto* trdLI = new CbmTrdSetTracksPidLike("TRDLikelihood", "TRDLikelihood"); + trdLI->SetUseMCInfo(false); + trdLI->SetUseMomDependence(false); + run->AddTask(trdLI); + + if (bPV) { + CbmKF* KF = new CbmKF(); + run->AddTask(KF); + + auto* pvFinder = new CbmPVFinderKFGlobal(); + CbmFindPrimaryVertex* findVertex = new CbmFindPrimaryVertex(pvFinder); + findVertex->SetTrackType(ECbmDataType::kGlobalTrack); + run->AddTask(findVertex); + } + } + // ========================================================================= + // === QA === + // ========================================================================= + if (bQA) { + CbmRecoQaTask* recoQa = new CbmRecoQaTask(); + recoQa->SetSetupClass(CbmRecoQaTask::kMcbm24); + // USER : Uncomment this line if you like to select only track multiplicities 1 and 2 per event + // recoQa->AddEventFilter(CbmRecoQaTask::EventFilter::eEventCut::kMultTrk)->SetFilter({1, 2}); + // USER : All track cuts are EXCLUSIVE (they ALL have to be met in order that tracks are selected) + // USER : Uncomment this line if you like to select ONLY tracks with AT LEAST 3 STS hits + // recoQa->AddTrackFilter(CbmRecoQaTask::TrackFilter::eTrackCut::kSts)->SetFilter({3}); + // USER : Uncomment this line if you like to select ONLY tracks with AT LEAST 2 TRD hits + // recoQa->AddTrackFilter(CbmRecoQaTask::TrackFilter::eTrackCut::kTrd)->SetFilter({2}); + // USER : Uncomment this line if you like to select ONLY tracks with AT LEAST 1 ToF hit + // recoQa->AddTrackFilter(CbmRecoQaTask::TrackFilter::eTrackCut::kTof)->SetFilter({1}); + run->AddTask(recoQa); + } + // ------------------------------------------------------------------------ + + // ----- Parameter database -------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Set runtime DB" << std::endl; + FairRuntimeDb* rtdb = run->GetRuntimeDb(); + FairParRootFileIo* parIo1 = new FairParRootFileIo(); + FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo(); + FairParRootFileIo* parIo3 = new FairParRootFileIo(); + //parIo1->open(parFileIn.Data(), "READ"); + //rtdb->setFirstInput(parIo1); + parIo2->open(parFileList, "in"); + rtdb->setSecondInput(parIo2); + parIo3->open(parFileOut.Data(), "RECREATE"); + // ------------------------------------------------------------------------ + rtdb->setOutput(parIo3); + + // ----- Run initialisation ------------------------------------------- + std::cout << std::endl; + std::cout << "-I- " << myName << ": Initialise run" << std::endl; + run->Init(); + rtdb->print(); + // ------------------------------------------------------------------------ + + + // ----- Start run ---------------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Starting run" << std::endl; + run->Run(0, nTimeslices); + // ------------------------------------------------------------------------ + + + // ----- Finish ------------------------------------------------------- + + rtdb->print(); + rtdb->saveOutput(); + run->CreateGeometryFile(geoFileOut); + + timer.Stop(); + FairMonitor::GetMonitor()->Print(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + std::cout << std::endl << std::endl; + std::cout << "Macro finished successfully." << std::endl; + std::cout << "Output file is " << outFile << std::endl; + std::cout << "Parameter file is " << parFileOut << std::endl; + std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl; + std::cout << std::endl; + // ------------------------------------------------------------------------ + + + // ----- Resource monitoring ------------------------------------------ + // Extract the maximal used memory an add is as Dart measurement + // This line is filtered by CTest and the value send to CDash + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"; + std::cout << maxMemory; + std::cout << "</DartMeasurement>" << std::endl; + + Float_t cpuUsage = ctime / rtime; + std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"; + std::cout << cpuUsage; + std::cout << "</DartMeasurement>" << std::endl; + // ------------------------------------------------------------------------ + + + // ----- Function needed for CTest runtime dependency ----------------- + RemoveGeoManager(); + // ------------------------------------------------------------------------ + + /// --- Screen output for automatic tests + std::cout << " Test passed" << std::endl; + std::cout << " All ok " << std::endl; + + return kTRUE; +} diff --git a/reco/L1/OffLineInterface/CbmL1GlobalTrackFinder.cxx b/reco/L1/OffLineInterface/CbmL1GlobalTrackFinder.cxx index c1f15963b2f5b3ce19368dfb8e5b742776878cf1..cb69970661e23adbac33e4910aa749a74101a4da 100644 --- a/reco/L1/OffLineInterface/CbmL1GlobalTrackFinder.cxx +++ b/reco/L1/OffLineInterface/CbmL1GlobalTrackFinder.cxx @@ -190,6 +190,9 @@ void CbmL1GlobalTrackFinder::CbmL1TrackToCbmStsTrack(CbmL1Track l1track, CbmStsT track->SetParamFirst(cbm::kf::ConvertTrackParam(T)); track->SetParamLast(cbm::kf::ConvertTrackParam(T.TLast)); + + double dEdXSts = this->CalculateEloss(track); + track->SetELoss(dEdXSts); } // ------------------------------------------------------------------------- diff --git a/reco/alignment/CbmBbaAlignmentTask.cxx b/reco/alignment/CbmBbaAlignmentTask.cxx index 255b7686d01e68208da66026bf53e8622a011767..e36f8b7d05febaf203e9b6283edede5135834acf 100644 --- a/reco/alignment/CbmBbaAlignmentTask.cxx +++ b/reco/alignment/CbmBbaAlignmentTask.cxx @@ -326,7 +326,7 @@ void CbmBbaAlignmentTask::Exec(Option_t* /*opt*/) fFitter.SetDefaultMomentumForMs(0.1); for (int iTr = 0; iTr < fInputStsTracks->GetEntriesFast(); iTr++) { - if (static_cast<int>(fTracks.size()) >= fMaxNtracks) { + if (fMaxNtracks && static_cast<int>(fTracks.size()) >= fMaxNtracks) { break; } const CbmStsTrack* stsTrack = dynamic_cast<CbmStsTrack*>(fInputStsTracks->At(iTr)); @@ -1044,10 +1044,9 @@ void CbmBbaAlignmentTask::Finish() } // sensors // save matrices to disk - TFile* misalignmentMatrixRootfile = - new TFile("AlignmentMatrices_mcbm_beam_2022_05_23_nickel_finetuning.root", "RECREATE"); + TFile* misalignmentMatrixRootfile = new TFile(fsMatrixOutFileName, "RECREATE"); if (misalignmentMatrixRootfile->IsOpen()) { - gDirectory->WriteObject(&alignmentMatrices, "AlignmentMatrices"); + gDirectory->WriteObject(&alignmentMatrices, "MisalignMatrices"); misalignmentMatrixRootfile->Write(); misalignmentMatrixRootfile->Close(); } diff --git a/reco/alignment/CbmBbaAlignmentTask.h b/reco/alignment/CbmBbaAlignmentTask.h index 0aa2f513198dec1a00790cfcefb61d62f9ee7c27..5db2bb39b8c9900ef0701183764364e3b81c69fc 100644 --- a/reco/alignment/CbmBbaAlignmentTask.h +++ b/reco/alignment/CbmBbaAlignmentTask.h @@ -35,7 +35,7 @@ class CbmBbaAlignmentTask : public FairTask { public: // Constructors/Destructors --------- CbmBbaAlignmentTask(const char* name = "CbmBbaAlignmentTask", Int_t iVerbose = 0, - TString histoFileName = "CbmBbaAlignmentHisto.root"); + TString histoFileName = "./CbmBbaAlignmentHisto.root"); ~CbmBbaAlignmentTask(); Int_t GetZtoNStation(Double_t getZ); @@ -50,6 +50,8 @@ class CbmBbaAlignmentTask : public FairTask { void SetSimulatedMisalignmentRange(double range) { fSimulatedMisalignmentRange = range; } void SetRandomSeed(int seed) { fRandomSeed = seed; } + void SetMatrixOutFileName(TString sMatrixOutFileName) { fsMatrixOutFileName = sMatrixOutFileName; } + public: enum TrackingMode { @@ -133,14 +135,16 @@ class CbmBbaAlignmentTask : public FairTask { // collection of selected tracks and hits std::vector<TrackContainer> fTracks; + //output file with histograms + TString fsMatrixOutFileName{"AlignmentMatrices_finetuning.root"}; TString fHistoFileName{"CbmBbaAlignmentHisto.root"}; TFile* fHistoFile{nullptr}; TDirectory* fHistoDir{nullptr}; Int_t fNEvents{0}; - Int_t fMaxNtracks{100000}; + Int_t fMaxNtracks{0}; int fNtrackingStations{0}; int fNalignmentBodies{0}; @@ -156,6 +160,7 @@ class CbmBbaAlignmentTask : public FairTask { long fNdfTotal{0}; long fFixedNdf{-1}; + std::vector<Sensor> fSensors; std::vector<AlignmentBody> fAlignmentBodies; 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;