From 89869dc521f7236f2671bc418b16ddadcf6ff546 Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 14 Oct 2026 10:37:25 +0200 Subject: [PATCH 1/4] ITS2 - anomalous clusters task improvement --- .../studies/include/ITSStudies/Efficiency.h | 23 ---- .../postprocessing/studies/src/Efficiency.cxx | 32 ++++- .../studies/src/ITSBeamBackgroundStudy.cxx | 114 ++++++++++-------- .../postprocessing/workflow/CMakeLists.txt | 25 +++- 4 files changed, 118 insertions(+), 76 deletions(-) diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h index 1c9bb6f7e568a..d263504ae666c 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/Efficiency.h @@ -28,29 +28,6 @@ namespace study using mask_t = o2::dataformats::GlobalTrackID::mask_t; o2::framework::DataProcessorSpec getEfficiencyStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr kineReader, bool itsStag); -float mEtaCuts[2] = {-1.0, 1.0}; -float mPtCuts[2] = {0, 10}; /// no cut for B=0 - -// values obtained from the dca study for B=5 -// float dcaXY[3] = {-0.000326, -0.000217, -0.000187}; -// float dcaZ[3] = {0.000020, -0.000004, 0.000032}; -// float sigmaDcaXY[3] = {0.001375, 0.001279, 0.002681}; -// float sigmaDcaZ[3] = {0.002196, 0.002083, 0.004125}; - -// values obtained from the dca study for B=0 -float dcaXY[3] = {-0.000328, -0.000213, -0.000203}; -float dcaZ[3] = {-0.000000543, -0.000013, 0.000001}; -float sigmaDcaXY[3] = {0.00109, 0.000895, 0.001520}; -float sigmaDcaZ[3] = {0.001366, 0.001149, 0.001868}; - -int dcaCut = 8; - -float mDCACutsXY[3][2] = {{dcaXY[0] - dcaCut * sigmaDcaXY[0], dcaXY[0] + dcaCut* sigmaDcaXY[0]}, {dcaXY[1] - dcaCut * sigmaDcaXY[1], dcaXY[1] + dcaCut* sigmaDcaXY[1]}, {dcaXY[2] - dcaCut * sigmaDcaXY[2], dcaXY[2] + dcaCut* sigmaDcaXY[2]}}; // cuts at 8 sigma for each layer for xy. The values represent m-8sigma and m+8sigma -float mDCACutsZ[3][2] = {{dcaZ[0] - dcaCut * sigmaDcaZ[0], dcaZ[0] + dcaCut* sigmaDcaZ[0]}, {dcaZ[1] - dcaCut * sigmaDcaZ[1], dcaZ[1] + dcaCut* sigmaDcaZ[1]}, {dcaZ[2] - dcaCut * sigmaDcaZ[2], dcaZ[2] + dcaCut* sigmaDcaZ[2]}}; - -/// excluding bad chips in MC that are not present in data: to be checked based on the anchoring -std::vector mExcludedChipMC = {66, 67, 68, 75, 76, 77, 84, 85, 86, 93, 94, 95, 102, 103, 104, 265, 266, 267, 274, 275, 276, 283, 284, 285, 413, 414, 415, 422, 423, 424, 431, 432, 433}; - } // namespace study } // namespace its } // namespace o2 diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx index 314ed025b799e..3f3e7a4ac4c39 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/Efficiency.cxx @@ -47,11 +47,41 @@ #include #include #include +#include #define NLAYERS 3 namespace o2::its::study { +namespace +{ +// Keep study settings local to this translation unit. Definitions in the public +// header would be initialized and destroyed by both the library and workflow. +float mEtaCuts[2] = {-1.0, 1.0}; +float mPtCuts[2] = {0, 10}; /// no cut for B=0 + +// values obtained from the dca study for B=5 +// float dcaXY[3] = {-0.000326, -0.000217, -0.000187}; +// float dcaZ[3] = {0.000020, -0.000004, 0.000032}; +// float sigmaDcaXY[3] = {0.001375, 0.001279, 0.002681}; +// float sigmaDcaZ[3] = {0.002196, 0.002083, 0.004125}; + +// values obtained from the dca study for B=0 +float dcaXY[3] = {-0.000328, -0.000213, -0.000203}; +float dcaZ[3] = {-0.000000543, -0.000013, 0.000001}; +float sigmaDcaXY[3] = {0.00109, 0.000895, 0.001520}; +float sigmaDcaZ[3] = {0.001366, 0.001149, 0.001868}; + +int dcaCut = 8; + +float mDCACutsXY[3][2] = {{dcaXY[0] - dcaCut * sigmaDcaXY[0], dcaXY[0] + dcaCut* sigmaDcaXY[0]}, {dcaXY[1] - dcaCut * sigmaDcaXY[1], dcaXY[1] + dcaCut* sigmaDcaXY[1]}, {dcaXY[2] - dcaCut * sigmaDcaXY[2], dcaXY[2] + dcaCut* sigmaDcaXY[2]}}; // cuts at 8 sigma for each layer for xy. The values represent m-8sigma and m+8sigma +float mDCACutsZ[3][2] = {{dcaZ[0] - dcaCut * sigmaDcaZ[0], dcaZ[0] + dcaCut* sigmaDcaZ[0]}, {dcaZ[1] - dcaCut * sigmaDcaZ[1], dcaZ[1] + dcaCut* sigmaDcaZ[1]}, {dcaZ[2] - dcaCut * sigmaDcaZ[2], dcaZ[2] + dcaCut* sigmaDcaZ[2]}}; + +/// excluding bad chips in MC that are not present in data: to be checked based on the anchoring +std::vector mExcludedChipMC = {66, 67, 68, 75, 76, 77, 84, 85, 86, 93, 94, 95, 102, 103, 104, 265, 266, 267, 274, 275, 276, 283, 284, 285, 413, 414, 415, 422, 423, 424, 431, 432, 433}; + +} // namespace + using namespace o2::framework; using namespace o2::globaltracking; @@ -64,7 +94,7 @@ class EfficiencyStudy final : public Task mask_t src, bool useMC, std::shared_ptr kineReader, - std::shared_ptr gr) : mDataRequest(dr), mTracksSrc(src), mUseMC(useMC), mKineReader(kineReader), mGGCCDBRequest(gr){}; + std::shared_ptr gr) : mDataRequest(dr), mTracksSrc(src), mUseMC(useMC), mKineReader(kineReader), mGGCCDBRequest(gr) {}; ~EfficiencyStudy() final = default; void init(InitContext&) final; diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx index 80742c2dd6503..f84141434af23 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx @@ -19,10 +19,13 @@ #include "DataFormatsITSMFT/CompCluster.h" #include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsITSMFT/TopologyDictionary.h" +#include "ITSBase/GeometryTGeo.h" +#include "ITSMFTReconstruction/ChipMappingITS.h" #include #include #include +#include #include #include @@ -57,16 +60,16 @@ class ITSBeamBackgroundStudy : public Task void updateTimeDependentParams(ProcessingContext& pc); private: + void prepareOutput(); void getClusterPatterns(gsl::span&, gsl::span&, const o2::itsmft::TopologyDictionary&); std::vector mPatterns; // ITS layout - int NStaves[7] = {12, 16, 20, 24, 30, 42, 48}; - int N_STAVES_IB = 48; - int N_CHIP_IB = 432; + static constexpr int N_CHIP_IB = o2::itsmft::ChipMappingITS::getNChips(o2::itsmft::ChipMappingITS::IB); + o2::itsmft::ChipMappingITS mChipMapping; + o2::its::GeometryTGeo* mGeom = nullptr; // Utilities - int ChipToLayer(int chip); double ChipToPhi(int chip); bool searchBCfromMap(std::map>& BCperorbit, long target_orbit, int target_bc); @@ -92,8 +95,8 @@ class ITSBeamBackgroundStudy : public Task int targetClusterMinCol = 128; // definition of anomalous cluster int targetClusterMaxRow = 29; // definition of anomalous cluster - int mDumpEveryTF = 10; // use -1 to save only at the end - int mSkimmedOnlyAfterTF = 15000; + int mDumpEveryTF = 5; // use -1 to save only at the end + int mSkimmedOnlyAfterTF = 150; std::string mOutputChip = "chipevents"; std::string mOutoutChipSkim = "chipeventstarget"; @@ -111,6 +114,10 @@ class ITSBeamBackgroundStudy : public Task long Torbit; int Tchip; double Tphi; + // Cluster vectors share the input cluster order within this chip/ROF. + // Positions are global: phi in radians [-pi, pi], r and z in cm. + std::vector TclusterPhi, TclusterR, TclusterZ; + std::vector TclusterSize, TclusterColSpan, TclusterRowSpan; int TZDCtag; int Tnhit, Tnclus, Tnhit_no1pix, Tnclus_no1pix; int Tnclus_s20, Tnclus_s100, Tnclus_s150; @@ -123,24 +130,26 @@ class ITSBeamBackgroundStudy : public Task void ITSBeamBackgroundStudy::updateTimeDependentParams(ProcessingContext& pc) { - // o2::base::GRPGeomHelper::instance().checkUpdates(pc); - // static bool initOnceDone = false; - // if (!initOnceDone) { // this param need to be queried only once - // initOnceDone = true; - // // mGeom = o2::its::GeometryTGeo::Instance(); - // // mGeom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G)); - // } + o2::base::GRPGeomHelper::instance().checkUpdates(pc); + mGeom = o2::its::GeometryTGeo::Instance(); + mGeom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); } void ITSBeamBackgroundStudy::init(InitContext& ic) { LOGP(info, "Initializing ITSBeamBackgroundStudy"); + o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); LOGP(info, "Fetching ClusterDictionary"); auto& mgr = o2::ccdb::BasicCCDBManager::instance(); mgr.setURL("http://alice-ccdb.cern.ch"); mgr.setTimestamp(o2::ccdb::getCurrentTimestamp()); mDict = mgr.get("ITS/Calib/ClusterDictionary"); + prepareOutput(); +} + +void ITSBeamBackgroundStudy::prepareOutput() +{ LOGP(info, "Setting up trees and histograms. They will be dumped on file every {} TFs", mDumpEveryTF); TimeWindowCut = new TH1F("ZDC bkg region", "ZNAr, ZNCr, -ZNAl, -ZNCl", 8, 0, 8); @@ -177,6 +186,12 @@ void ITSBeamBackgroundStudy::init(InitContext& ic) ITSChipEvtTree->Branch("bc", &Tbc, "bc/I"); ITSChipEvtTree->Branch("chip", &Tchip, "chip/I"); ITSChipEvtTree->Branch("phi", &Tphi, "phi/D"); + ITSChipEvtTree->Branch("cluster_phi", &TclusterPhi); + ITSChipEvtTree->Branch("cluster_r", &TclusterR); + ITSChipEvtTree->Branch("cluster_z", &TclusterZ); + ITSChipEvtTree->Branch("cluster_size", &TclusterSize); + ITSChipEvtTree->Branch("cluster_colspan", &TclusterColSpan); + ITSChipEvtTree->Branch("cluster_rowspan", &TclusterRowSpan); ITSChipEvtTree->Branch("zdctag", &TZDCtag, "zdctag/I"); ITSChipEvtTree->Branch("nhit", &Tnhit, "nhit/I"); ITSChipEvtTree->Branch("nhit_no1pix", &Tnhit_no1pix, "nhit_no1pix/I"); @@ -273,14 +288,14 @@ void ITSBeamBackgroundStudy::run(ProcessingContext& pc) o2::globaltracking::RecoContainer recoData; recoData.collectData(pc, *mDataRequest.get()); - // updateTimeDependentParams(pc); + updateTimeDependentParams(pc); LOGP(info, "Calling process() for TF: {}", mTFn); process(recoData); } void ITSBeamBackgroundStudy::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) { - return; + o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj); } // Custom area @@ -512,9 +527,11 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData std::set AvailableChips{}; std::map> MAPsize{}; // MAP[chip] = {list if sizes} std::map> MAPcols{}; // MAP[chip] = {list of column span} - std::map MAPntarget{}; // MAP[chip] = number of bad clusters in chip - std::map MAPcoo_mincol{}; // MAP[chip] = minimum of column coordinate - std::map MAPcoo_maxcol{}; // MAP[chip] = maximum of (column coordinate + colspan) + std::map> MAProws{}; // MAP[chip] = {list of row span} + std::map>> MAPcoordinates{}; + std::map MAPntarget{}; // MAP[chip] = number of bad clusters in chip + std::map MAPcoo_mincol{}; // MAP[chip] = minimum of column coordinate + std::map MAPcoo_maxcol{}; // MAP[chip] = maximum of (column coordinate + colspan) // Finally loop over clusters int ntarget_in_rof = 0; @@ -525,7 +542,7 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData auto chipid = compClus.getSensorID(); // Analyze only IB - if (ChipToLayer(chipid) > 2) { + if (o2::itsmft::ChipMappingITS::getLayer(chipid) > 2) { continue; } @@ -534,7 +551,7 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData int coo_col = (int)compClus.getCol(); int coo_row = (int)compClus.getRow(); - auto patti = patternsInRof[iclus]; + const auto& patti = patternsInRof[iclus]; int npix = patti.getNPixels(); int colspan = patti.getColumnSpan(); int rowspan = patti.getRowSpan(); @@ -543,6 +560,7 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData if (newchip) { MAPsize[chipid] = std::vector{}; MAPcols[chipid] = std::vector{}; + MAProws[chipid] = std::vector{}; MAPntarget[chipid] = 0; MAPcoo_mincol[chipid] = coo_col; MAPcoo_maxcol[chipid] = coo_col + colspan; @@ -550,6 +568,15 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData MAPsize[chipid].push_back(npix); MAPcols[chipid].push_back(colspan); + MAProws[chipid].push_back(rowspan); + // Grouped topologies store a rounded COG in the compact cluster; invalid + // pattern IDs store the bounding-box corner instead. + const auto pattID = compClus.getPatternID(); + auto local = pattID == o2::itsmft::CompCluster::InvalidPatternID + ? mDict->getClusterCoordinates(compClus, patti, false) + : (mDict->isGroup(pattID) ? mDict->getClusterCoordinates(compClus, patti) + : mDict->getClusterCoordinates(compClus)); + MAPcoordinates[chipid].push_back(mGeom->getMatrixL2G(chipid)(local)); if (colspan >= targetClusterMinCol && rowspan <= targetClusterMaxRow) { // Anomalous cluster found MAPntarget[chipid] += 1; @@ -588,6 +615,17 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData Tphi = ChipToPhi(ic); Tnclus = MAPsize[ic].size(); + TclusterSize = MAPsize[ic]; // Save before sorting the sizes for the summaries. + TclusterColSpan = MAPcols[ic]; + TclusterRowSpan = MAProws[ic]; + TclusterPhi.clear(); + TclusterR.clear(); + TclusterZ.clear(); + for (const auto& global : MAPcoordinates[ic]) { + TclusterPhi.push_back(std::atan2(global.Y(), global.X())); + TclusterR.push_back(std::hypot(global.X(), global.Y())); + TclusterZ.push_back(global.Z()); + } Tmincol = MAPcoo_mincol[ic]; Tmaxcol = MAPcoo_maxcol[ic]; @@ -644,38 +682,12 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData } // end of loop over ROFs } -// TODO: To be improved using geometry tools -int ITSBeamBackgroundStudy::ChipToLayer(int chip) -{ - if (chip < 108) { - return 0; - } - if (chip < 252) { - return 1; - } - if (chip < 432) { - return 2; - } - if (chip < 3120) { - return 3; - } - if (chip < 6480) { - return 4; - } - if (chip < 14712) { - return 5; - } - return 6; -} - -// TODO: To be improved using geometry tools double ITSBeamBackgroundStudy::ChipToPhi(int chip) { - int staveinlayer = (int)(chip / 9); - for (int il = 0; il < ChipToLayer(chip); il++) { - staveinlayer -= NStaves[il]; - } - return 2. * TMath::Pi() * (0.5 + staveinlayer) / NStaves[ChipToLayer(chip)]; + int layer, stave, substave, module, chipInModule; + mChipMapping.expandChipInfoSW(chip, layer, stave, substave, module, chipInModule); + const int staveInLayer = stave - o2::itsmft::ChipMappingITS::getFirstStavesOnLr(layer); + return 2. * TMath::Pi() * (0.5 + staveInLayer) / o2::itsmft::ChipMappingITS::getNStavesOnLr(layer); } bool ITSBeamBackgroundStudy::searchBCfromMap(std::map>& BCperorbit, long its_orbit, int its_bc) @@ -738,7 +750,7 @@ DataProcessorSpec getITSBeamBackgroundStudy(mask_t srcTracksMask, mask_t srcClus dataRequest->inputs, true); return DataProcessorSpec{ - "its-beambkg-study", + "its-beambkg-study-task", dataRequest->inputs, outputs, AlgorithmSpec{adaptFromTask(dataRequest, ggRequest, useMC)}, diff --git a/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt b/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt index 8ec0d3b2ff325..ba7aa85e6e9e2 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt @@ -11,5 +11,28 @@ o2_add_executable(postprocessing-workflow COMPONENT_NAME its-standalone + TARGETVARNAME postprocessingWorkflowTarget SOURCES standalone-postprocessing-workflow.cxx - PUBLIC_LINK_LIBRARIES O2::ITSPostprocessing) \ No newline at end of file + PUBLIC_LINK_LIBRARIES O2::ITSPostprocessing) + +if(BUILD_TESTING) + # Help constructs the workflow and exits, exercising static initialization and + # destruction without input data or CCDB access. + set(helpTestDirectory "${CMAKE_CURRENT_BINARY_DIR}/test-workflow-help") + set(beambkgHelpTestDirectory "${CMAKE_CURRENT_BINARY_DIR}/test-workflow-beambkg-help") + file(MAKE_DIRECTORY "${helpTestDirectory}" "${beambkgHelpTestDirectory}") + add_test(NAME its-standalone-postprocessing-help + COMMAND $ --disable-mc --help) + add_test(NAME its-standalone-postprocessing-beambkg-help + COMMAND $ + --disable-mc --input-from-upstream --its-beambkg-study + --cluster-sources ITS --track-sources "" --help) + set_tests_properties(its-standalone-postprocessing-help + its-standalone-postprocessing-beambkg-help PROPERTIES + LABELS "its;workflow;itsmft" + TIMEOUT 60) + set_tests_properties(its-standalone-postprocessing-help PROPERTIES + WORKING_DIRECTORY "${helpTestDirectory}") + set_tests_properties(its-standalone-postprocessing-beambkg-help PROPERTIES + WORKING_DIRECTORY "${beambkgHelpTestDirectory}") +endif() From a2eae503c743d77230a9d72c07e3ac8b1a881ed6 Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 14 Oct 2026 11:00:43 +0200 Subject: [PATCH 2/4] Removing unnecessary instructions --- .../postprocessing/workflow/CMakeLists.txt | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt b/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt index ba7aa85e6e9e2..116a0e738331c 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/postprocessing/workflow/CMakeLists.txt @@ -13,26 +13,4 @@ o2_add_executable(postprocessing-workflow COMPONENT_NAME its-standalone TARGETVARNAME postprocessingWorkflowTarget SOURCES standalone-postprocessing-workflow.cxx - PUBLIC_LINK_LIBRARIES O2::ITSPostprocessing) - -if(BUILD_TESTING) - # Help constructs the workflow and exits, exercising static initialization and - # destruction without input data or CCDB access. - set(helpTestDirectory "${CMAKE_CURRENT_BINARY_DIR}/test-workflow-help") - set(beambkgHelpTestDirectory "${CMAKE_CURRENT_BINARY_DIR}/test-workflow-beambkg-help") - file(MAKE_DIRECTORY "${helpTestDirectory}" "${beambkgHelpTestDirectory}") - add_test(NAME its-standalone-postprocessing-help - COMMAND $ --disable-mc --help) - add_test(NAME its-standalone-postprocessing-beambkg-help - COMMAND $ - --disable-mc --input-from-upstream --its-beambkg-study - --cluster-sources ITS --track-sources "" --help) - set_tests_properties(its-standalone-postprocessing-help - its-standalone-postprocessing-beambkg-help PROPERTIES - LABELS "its;workflow;itsmft" - TIMEOUT 60) - set_tests_properties(its-standalone-postprocessing-help PROPERTIES - WORKING_DIRECTORY "${helpTestDirectory}") - set_tests_properties(its-standalone-postprocessing-beambkg-help PROPERTIES - WORKING_DIRECTORY "${beambkgHelpTestDirectory}") -endif() + PUBLIC_LINK_LIBRARIES O2::ITSPostprocessing) \ No newline at end of file From bfea7de42d5020eb575dc487c6c66ac1941c517b Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Wed, 14 Oct 2026 12:07:23 +0200 Subject: [PATCH 3/4] Adding configurable keys --- .../ITSStudies/ITSStudiesConfigParam.h | 10 ++- .../studies/src/ITSBeamBackgroundStudy.cxx | 88 +++++++++++-------- .../studies/src/ITSStudiesConfigParam.cxx | 2 + .../studies/src/ITSStudiesLinkDef.h | 4 +- .../standalone-postprocessing-workflow.cxx | 16 +++- 5 files changed, 80 insertions(+), 40 deletions(-) diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h index 85e114e0fb739..cc9460f87c6ce 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/include/ITSStudies/ITSStudiesConfigParam.h @@ -94,6 +94,14 @@ struct AnomalyStudyParamConfig : public o2::conf::ConfigurableParamHelper { + int dumpEveryTF = 5; // <= 0: write only at end of stream + int skimmedOnlyAfterTF = 150; // TF threshold above which only the skimmed output file is written + bool saveClusterParameters = true; // Write per-cluster coordinates, size and row/column spans + + O2ParamDef(ITSBeamBackgroundStudyParamConfig, "ITSBeamBackgroundStudyParam"); +}; + struct ITSEfficiencyParamConfig : public o2::conf::ConfigurableParamHelper { std::string outFileName = "ITS_efficiencyStudy.root"; double b = 0; // Solenoid field in kG (+/-) @@ -115,4 +123,4 @@ struct ITSImpactParameterParamConfig : public o2::conf::ConfigurableParamHelper< } // namespace its } // namespace o2 -#endif \ No newline at end of file +#endif diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx index f84141434af23..84eb95811e393 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx @@ -10,6 +10,7 @@ // or submit itself to any jurisdiction. #include "ITSStudies/ITSBeamBackgroundStudy.h" +#include "ITSStudies/ITSStudiesConfigParam.h" #include "DataFormatsGlobalTracking/RecoContainer.h" #include "DetectorsBase/GRPGeomHelper.h" #include "DataFormatsParameters/GRPObject.h" @@ -26,6 +27,7 @@ #include #include #include +#include #include #include @@ -95,8 +97,9 @@ class ITSBeamBackgroundStudy : public Task int targetClusterMinCol = 128; // definition of anomalous cluster int targetClusterMaxRow = 29; // definition of anomalous cluster - int mDumpEveryTF = 5; // use -1 to save only at the end - int mSkimmedOnlyAfterTF = 150; + int mDumpEveryTF = ITSBeamBackgroundStudyParamConfig::Instance().dumpEveryTF; + int mSkimmedOnlyAfterTF = ITSBeamBackgroundStudyParamConfig::Instance().skimmedOnlyAfterTF; + bool mSaveClusterParameters = ITSBeamBackgroundStudyParamConfig::Instance().saveClusterParameters; std::string mOutputChip = "chipevents"; std::string mOutoutChipSkim = "chipeventstarget"; @@ -131,8 +134,10 @@ class ITSBeamBackgroundStudy : public Task void ITSBeamBackgroundStudy::updateTimeDependentParams(ProcessingContext& pc) { o2::base::GRPGeomHelper::instance().checkUpdates(pc); - mGeom = o2::its::GeometryTGeo::Instance(); - mGeom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); + if (mSaveClusterParameters) { + mGeom = o2::its::GeometryTGeo::Instance(); + mGeom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); + } } void ITSBeamBackgroundStudy::init(InitContext& ic) @@ -151,6 +156,7 @@ void ITSBeamBackgroundStudy::init(InitContext& ic) void ITSBeamBackgroundStudy::prepareOutput() { LOGP(info, "Setting up trees and histograms. They will be dumped on file every {} TFs", mDumpEveryTF); + LOGP(info, "Skimmed-only output after TF {}; saving cluster parameters: {}", mSkimmedOnlyAfterTF, mSaveClusterParameters); TimeWindowCut = new TH1F("ZDC bkg region", "ZNAr, ZNCr, -ZNAl, -ZNCl", 8, 0, 8); TimeWindowCut->SetBinContent(1, TimeWindowZNAr.first); @@ -186,12 +192,14 @@ void ITSBeamBackgroundStudy::prepareOutput() ITSChipEvtTree->Branch("bc", &Tbc, "bc/I"); ITSChipEvtTree->Branch("chip", &Tchip, "chip/I"); ITSChipEvtTree->Branch("phi", &Tphi, "phi/D"); - ITSChipEvtTree->Branch("cluster_phi", &TclusterPhi); - ITSChipEvtTree->Branch("cluster_r", &TclusterR); - ITSChipEvtTree->Branch("cluster_z", &TclusterZ); - ITSChipEvtTree->Branch("cluster_size", &TclusterSize); - ITSChipEvtTree->Branch("cluster_colspan", &TclusterColSpan); - ITSChipEvtTree->Branch("cluster_rowspan", &TclusterRowSpan); + if (mSaveClusterParameters) { + ITSChipEvtTree->Branch("cluster_phi", &TclusterPhi); + ITSChipEvtTree->Branch("cluster_r", &TclusterR); + ITSChipEvtTree->Branch("cluster_z", &TclusterZ); + ITSChipEvtTree->Branch("cluster_size", &TclusterSize); + ITSChipEvtTree->Branch("cluster_colspan", &TclusterColSpan); + ITSChipEvtTree->Branch("cluster_rowspan", &TclusterRowSpan); + } ITSChipEvtTree->Branch("zdctag", &TZDCtag, "zdctag/I"); ITSChipEvtTree->Branch("nhit", &Tnhit, "nhit/I"); ITSChipEvtTree->Branch("nhit_no1pix", &Tnhit_no1pix, "nhit_no1pix/I"); @@ -560,7 +568,6 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData if (newchip) { MAPsize[chipid] = std::vector{}; MAPcols[chipid] = std::vector{}; - MAProws[chipid] = std::vector{}; MAPntarget[chipid] = 0; MAPcoo_mincol[chipid] = coo_col; MAPcoo_maxcol[chipid] = coo_col + colspan; @@ -568,15 +575,17 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData MAPsize[chipid].push_back(npix); MAPcols[chipid].push_back(colspan); - MAProws[chipid].push_back(rowspan); - // Grouped topologies store a rounded COG in the compact cluster; invalid - // pattern IDs store the bounding-box corner instead. - const auto pattID = compClus.getPatternID(); - auto local = pattID == o2::itsmft::CompCluster::InvalidPatternID - ? mDict->getClusterCoordinates(compClus, patti, false) - : (mDict->isGroup(pattID) ? mDict->getClusterCoordinates(compClus, patti) - : mDict->getClusterCoordinates(compClus)); - MAPcoordinates[chipid].push_back(mGeom->getMatrixL2G(chipid)(local)); + if (mSaveClusterParameters) { + MAProws[chipid].push_back(rowspan); + // Grouped topologies store a rounded COG in the compact cluster; invalid + // pattern IDs store the bounding-box corner instead. + const auto pattID = compClus.getPatternID(); + auto local = pattID == o2::itsmft::CompCluster::InvalidPatternID + ? mDict->getClusterCoordinates(compClus, patti, false) + : (mDict->isGroup(pattID) ? mDict->getClusterCoordinates(compClus, patti) + : mDict->getClusterCoordinates(compClus)); + MAPcoordinates[chipid].push_back(mGeom->getMatrixL2G(chipid)(local)); + } if (colspan >= targetClusterMinCol && rowspan <= targetClusterMaxRow) { // Anomalous cluster found MAPntarget[chipid] += 1; @@ -587,7 +596,7 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData } // end of loop over clusters in rof - if (ntarget_in_rof == 0 && mTFn > mSkimmedOnlyAfterTF + 2) { // extra 2 to avoid edge effects? + if (ntarget_in_rof == 0 && static_cast(mTFn) > static_cast(mSkimmedOnlyAfterTF) + 2) { // extra 2 to avoid edge effects? // do not need extra computations for this rof since it will not be saved in any case continue; } @@ -615,16 +624,18 @@ void ITSBeamBackgroundStudy::process(o2::globaltracking::RecoContainer& recoData Tphi = ChipToPhi(ic); Tnclus = MAPsize[ic].size(); - TclusterSize = MAPsize[ic]; // Save before sorting the sizes for the summaries. - TclusterColSpan = MAPcols[ic]; - TclusterRowSpan = MAProws[ic]; - TclusterPhi.clear(); - TclusterR.clear(); - TclusterZ.clear(); - for (const auto& global : MAPcoordinates[ic]) { - TclusterPhi.push_back(std::atan2(global.Y(), global.X())); - TclusterR.push_back(std::hypot(global.X(), global.Y())); - TclusterZ.push_back(global.Z()); + if (mSaveClusterParameters) { + TclusterSize = MAPsize[ic]; // Save before sorting the sizes for the summaries. + TclusterColSpan = MAPcols[ic]; + TclusterRowSpan = MAProws[ic]; + TclusterPhi.clear(); + TclusterR.clear(); + TclusterZ.clear(); + for (const auto& global : MAPcoordinates[ic]) { + TclusterPhi.push_back(std::atan2(global.Y(), global.X())); + TclusterR.push_back(std::hypot(global.X(), global.Y())); + TclusterZ.push_back(global.Z()); + } } Tmincol = MAPcoo_mincol[ic]; Tmaxcol = MAPcoo_maxcol[ic]; @@ -741,12 +752,15 @@ DataProcessorSpec getITSBeamBackgroundStudy(mask_t srcTracksMask, mask_t srcClus dataRequest->requestTracks(srcTracksMask, useMC); - auto ggRequest = std::make_shared(false, // orbitResetTime - true, // GRPECS=true - false, // GRPLHCIF - false, // GRPMagField - false, // askMatLUT - o2::base::GRPGeomRequest::Aligned, // geometry + const auto geometry = ITSBeamBackgroundStudyParamConfig::Instance().saveClusterParameters + ? o2::base::GRPGeomRequest::Aligned + : o2::base::GRPGeomRequest::None; + auto ggRequest = std::make_shared(false, // orbitResetTime + true, // GRPECS=true + false, // GRPLHCIF + false, // GRPMagField + false, // askMatLUT + geometry, dataRequest->inputs, true); return DataProcessorSpec{ diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx index c0b2d2863f3cc..e57265bc593a8 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesConfigParam.cxx @@ -22,6 +22,7 @@ static auto& sPIDStudyParamITS = o2::its::study::PIDStudyParamConfig::Instance() static auto& sCheckTracksParamsITS = o2::its::study::ITSCheckTracksParamConfig::Instance(); static auto& sImpactParameterParamsITS = o2::its::study::ITSImpactParameterParamConfig::Instance(); static auto& sAnomalyStudy = o2::its::study::AnomalyStudyParamConfig::Instance(); +static auto& sBeamBackgroundStudy = o2::its::study::ITSBeamBackgroundStudyParamConfig::Instance(); static auto& sEfficiencyParamsITS = o2::its::study::ITSEfficiencyParamConfig::Instance(); O2ParamImpl(o2::its::study::ITSAvgClusSizeParamConfig); @@ -29,6 +30,7 @@ O2ParamImpl(o2::its::study::PIDStudyParamConfig); O2ParamImpl(o2::its::study::ITSCheckTracksParamConfig); O2ParamImpl(o2::its::study::ITSImpactParameterParamConfig); O2ParamImpl(o2::its::study::AnomalyStudyParamConfig); +O2ParamImpl(o2::its::study::ITSBeamBackgroundStudyParamConfig); O2ParamImpl(o2::its::study::ITSEfficiencyParamConfig); } // namespace study diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h index d56d718390b47..195692616e4fe 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSStudiesLinkDef.h @@ -19,13 +19,15 @@ #pragma link C++ class o2::its::study::PIDStudyParamConfig + ; #pragma link C++ class o2::its::study::ITSImpactParameterParamConfig + ; #pragma link C++ class o2::its::study::AnomalyStudyParamConfig + ; +#pragma link C++ class o2::its::study::ITSBeamBackgroundStudyParamConfig + ; #pragma link C++ class o2::its::study::ITSEfficiencyParamConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSAvgClusSizeParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::PIDStudyParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSCheckTracksParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSImpactParameterParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::AnomalyStudyParamConfig> + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSBeamBackgroundStudyParamConfig> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::its::study::ITSEfficiencyParamConfig> + ; #pragma link C++ function o2::its::studies::makeLogBinning + ; -#endif \ No newline at end of file +#endif diff --git a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx index 754cb2deac684..5c5284906faf8 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/workflow/standalone-postprocessing-workflow.cxx @@ -24,6 +24,7 @@ #include "ITSStudies/PIDStudy.h" #include "ITSStudies/AnomalyStudy.h" #include "ITSStudies/ITSBeamBackgroundStudy.h" +#include "ITSStudies/ITSStudiesConfigParam.h" #include "ITSStudies/Efficiency.h" #include "ITSStudies/TrackCheck.h" #include "ITSStudies/TrackExtension.h" @@ -41,6 +42,19 @@ void customize(std::vector& policies) // we need to add workflow options before including Framework/runDataProcessing void customize(std::vector& workflowOptions) { + const auto& beamParams = o2::its::study::ITSBeamBackgroundStudyParamConfig::Instance(); + const std::string configHelp = + "Semicolon-separated key=value strings. ITS beam-background study parameters:\n" + "Key prefix: ITSBeamBackgroundStudyParam.\n" + "dumpEveryTF= (default: " + + std::to_string(beamParams.dumpEveryTF) + + "): dump ROOT files every N TFs; <= 0 writes only at end of stream.\n" + "skimmedOnlyAfterTF= (default: " + + std::to_string(beamParams.skimmedOnlyAfterTF) + + "): TF threshold above which only the skimmed output file is written.\n" + "saveClusterParameters= (default: " + + (beamParams.saveClusterParameters ? "true" : "false") + + "): save cluster phi, r, z, size, colspan and rowspan vectors in output trees."; // option allowing to set parameters std::vector options{ {"input-from-upstream", VariantType::Bool, false, {"read clusters from the clusterer"}}, @@ -56,7 +70,7 @@ void customize(std::vector& workflowOptions) {"its-beambkg-study", VariantType::Bool, false, {"Perform the ITS beam background study"}}, {"track-extension-study", VariantType::Bool, false, {"Perform the track extension study"}}, {"efficiency-study", VariantType::Bool, false, {"Perform the efficiency study"}}, - {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; + {"configKeyValues", VariantType::String, "", {configHelp}}}; o2::itsmft::DPLAlpideParamInitializer::addITSConfigOption(options); // o2::raw::HBFUtilsInitializer::addConfigOption(options, "o2_tfidinfo.root"); std::swap(workflowOptions, options); From 7d0b5e742214b05c23f16f9033fdbc0aecc28010 Mon Sep 17 00:00:00 2001 From: Nicolo Valle Date: Thu, 15 Oct 2026 08:56:06 +0200 Subject: [PATCH 4/4] dummy --- .../ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx index 84eb95811e393..e83b76768edd5 100644 --- a/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx +++ b/Detectors/ITSMFT/ITS/postprocessing/studies/src/ITSBeamBackgroundStudy.cxx @@ -86,7 +86,7 @@ class ITSBeamBackgroundStudy : public Task int mStrobeFallBack = 594; int mStrobe = mStrobeFallBack; - // TODO: the following should be make configurable + // TODO: the following should be made configurable std::pair TimeWindowZDC = std::make_pair(5., 11.); std::pair TimeWindowZNAr = std::make_pair(5.64507, 9.64507);