From 36ffc5f7da0a93e10513c2e416c8265d0619b81a Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Wed, 5 Feb 2025 11:29:54 +0100 Subject: [PATCH 1/2] [MCH] introduce digit modifier in filtering workflow The digit modifier allows to change the contents of the digits in the filtering step. It is introduced in order to correct some mapping issues in the CTFs already collected, but the interface is general, and in the future it might be used for any kind of digit manipulation, if needed. --- .../MUON/MCH/DigitFiltering/CMakeLists.txt | 4 +- .../include/MCHDigitFiltering/DigitModifier.h | 28 ++++ .../MCHDigitFiltering/DigitModifierParam.h | 35 ++++ .../DigitFiltering/src/DigitFilteringSpec.cxx | 36 +++- .../MCH/DigitFiltering/src/DigitModifier.cxx | 154 ++++++++++++++++++ .../DigitFiltering/src/DigitModifierParam.cxx | 15 ++ .../src/MCHDigitFilteringLinkDef.h | 3 + 7 files changed, 270 insertions(+), 5 deletions(-) create mode 100644 Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifier.h create mode 100644 Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifierParam.h create mode 100644 Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx create mode 100644 Detectors/MUON/MCH/DigitFiltering/src/DigitModifierParam.cxx diff --git a/Detectors/MUON/MCH/DigitFiltering/CMakeLists.txt b/Detectors/MUON/MCH/DigitFiltering/CMakeLists.txt index f6d7fbd03701d..14e920debd441 100644 --- a/Detectors/MUON/MCH/DigitFiltering/CMakeLists.txt +++ b/Detectors/MUON/MCH/DigitFiltering/CMakeLists.txt @@ -13,6 +13,8 @@ o2_add_library(MCHDigitFiltering SOURCES src/DigitFilter.cxx src/DigitFilterParam.cxx + src/DigitModifier.cxx + src/DigitModifierParam.cxx src/DigitFilteringSpec.cxx PUBLIC_LINK_LIBRARIES O2::Framework @@ -27,4 +29,4 @@ o2_add_executable( COMPONENT_NAME mch PUBLIC_LINK_LIBRARIES O2::MCHDigitFiltering) -o2_target_root_dictionary(MCHDigitFiltering HEADERS include/MCHDigitFiltering/DigitFilterParam.h) +o2_target_root_dictionary(MCHDigitFiltering HEADERS include/MCHDigitFiltering/DigitFilterParam.h include/MCHDigitFiltering/DigitModifierParam.h) diff --git a/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifier.h b/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifier.h new file mode 100644 index 0000000000000..0177ea134ab1d --- /dev/null +++ b/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifier.h @@ -0,0 +1,28 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_MCH_DIGITFILTERING_DIGITMODIFIER_H_ +#define O2_MCH_DIGITFILTERING_DIGITMODIFIER_H_ + +#include "DataFormatsMCH/Digit.h" +#include + +namespace o2::mch +{ +typedef std::function DigitModifier; + +DigitModifier createDigitModifier(int runNumber, + bool updateST1, + bool updateST2); + +} // namespace o2::mch + +#endif diff --git a/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifierParam.h b/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifierParam.h new file mode 100644 index 0000000000000..dc95396835f33 --- /dev/null +++ b/Detectors/MUON/MCH/DigitFiltering/include/MCHDigitFiltering/DigitModifierParam.h @@ -0,0 +1,35 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_MCH_DIGITFILTERING_DIGIT_MODIFIER_PARAM_H_ +#define O2_MCH_DIGITFILTERING_DIGIT_MODIFIER_PARAM_H_ + +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2::mch +{ + +/** + * @class DigitModifierParam + * @brief Configurable parameters for the digit updating + */ +struct DigitModifierParam : public o2::conf::ConfigurableParamHelper { + + bool updateST1 = false; ///< whether or not to modify ST1 digits + bool updateST2 = false; ///< whether or not to modify ST2 digits + + O2ParamDef(DigitModifierParam, "MCHDigitModifier"); +}; + +} // namespace o2::mch + +#endif diff --git a/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx b/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx index fe40659bc9265..c8a2706637319 100644 --- a/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx +++ b/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx @@ -23,6 +23,8 @@ #include "MCHStatus/StatusMap.h" #include "MCHDigitFiltering/DigitFilter.h" #include "MCHDigitFiltering/DigitFilterParam.h" +#include "MCHDigitFiltering/DigitModifier.h" +#include "MCHDigitFiltering/DigitModifierParam.h" #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTruthContainer.h" #include @@ -48,6 +50,10 @@ class DigitFilteringTask mRejectBackground = DigitFilterParam::Instance().rejectBackground; mStatusMask = DigitFilterParam::Instance().statusMask; mTimeCalib = DigitFilterParam::Instance().timeOffset; + + mUpdateDigitsST1 = DigitModifierParam::Instance().updateST1; + mUpdateDigitsST2 = DigitModifierParam::Instance().updateST2; + auto stop = [this]() { LOG(info) << "digit filtering duration = " << std::chrono::duration(mElapsedTime).count() << " ms"; @@ -82,6 +88,11 @@ class DigitFilteringTask auto tStart = std::chrono::high_resolution_clock::now(); + const auto& tinfo = pc.services().get(); + if (tinfo.runNumber != 0) { + mRunNumber = tinfo.runNumber; + } + if (mSanityCheck) { LOGP(info, "performing sanity checks"); auto error = sanityCheck(iRofs, iDigits); @@ -101,8 +112,12 @@ class DigitFilteringTask auto oLabels = mUseMC ? &pc.outputs().make>(OutputRef{"labels"}) : nullptr; if (!abort) { - bool selectSignal = false; + mDigitModifier = createDigitModifier(mRunNumber, + mUpdateDigitsST1, + mUpdateDigitsST2); + + bool selectSignal = false; mIsGoodDigit = createDigitFilter(mMinADC, mRejectBackground, selectSignal, @@ -114,20 +129,29 @@ class DigitFilteringTask // the clustering resolution will suffer. // That's why we only apply the "reject background" filter, which // is a loose background cut that does not penalize the signal + int cursor{0}; for (const auto& irof : iRofs) { const auto digits = iDigits.subspan(irof.getFirstIdx(), irof.getNEntries()); // filter the digits from the current ROF for (auto i = 0; i < digits.size(); i++) { - const auto& d = digits[i]; - if (mIsGoodDigit(d)) { - oDigits.emplace_back(d); + auto digit = digits[i]; + + // modify the digit if needed + if(mDigitModifier) { + mDigitModifier(digit); + } + + // check the digit quality + if (mIsGoodDigit(digit)) { + oDigits.emplace_back(digit); if (iLabels) { oLabels->addElements(oLabels->getIndexedSize(), iLabels->getLabels(i + irof.getFirstIdx())); } } } + int nofGoodDigits = oDigits.size() - cursor; if (nofGoodDigits > 0) { // we create an ouput ROF only if at least one digit from @@ -160,6 +184,7 @@ class DigitFilteringTask } private: + int mRunNumber{0}; bool mRejectBackground{false}; bool mSanityCheck{false}; bool mUseMC{false}; @@ -167,7 +192,10 @@ class DigitFilteringTask int mMinADC{1}; int32_t mTimeCalib{0}; uint32_t mStatusMask{0}; + bool mUpdateDigitsST1{false}; + bool mUpdateDigitsST2{false}; DigitFilter mIsGoodDigit; + DigitModifier mDigitModifier; std::chrono::duration mElapsedTime{}; }; diff --git a/Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx b/Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx new file mode 100644 index 0000000000000..540929b80d193 --- /dev/null +++ b/Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx @@ -0,0 +1,154 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "MCHDigitFiltering/DigitModifier.h" + +#include "DataFormatsMCH/Digit.h" +#include "MCHRawElecMap/Mapper.h" +#include "MCHMappingInterface/Segmentation.h" +#include +#include +#include + +namespace +{ + +o2::mch::DigitModifier createST1MappingCorrector(int /*runNumber*/) +{ + return {}; +} + +/** initialization of the pad remapping table for Station 2 DEs + */ +void initST2PadsRemappingTable(std::unordered_map>& padsRemapping) +{ + // Remapping of ST2 DS boards near the rounded part + { + std::array deToRemap{ 300, 301, 302, 303, 400, 401, 402, 403 }; + std::array dsToRemap{ 99, 100, 101, 102, 103 }; + + for (auto deId : deToRemap) { + + const o2::mch::mapping::Segmentation& segment = o2::mch::mapping::segmentation(deId); + for (auto dsId : dsToRemap) { + // double loop on DS channels + // 1. find the minimum pad index of the DS board + int padIdMin = -1; + int channelForPadIdMin = -1; + for (int channel = 0; channel < 64; channel++) { + auto padId = segment.findPadByFEE(dsId, int(channel)); + if (padId < 0) { + // skip non-connected channels + // this should never occur in this specific case, should we rise an exception instead? + continue; + } + if (padIdMin < 0 || padId < padIdMin) { + padIdMin = padId; + channelForPadIdMin = channel; + } + } + + // 2. build the re-mapping table + for (int channel = 0; channel < 64; channel++) { + auto padId = segment.findPadByFEE(dsId, int(channel)); + if (padId < padIdMin) { + // something is wrong here... + continue; + } + int padIdInDS = padId - padIdMin; + int padColumn = padIdInDS / 16; + int padRow = padIdInDS % 16; + + int padIdRemapped = -1; + + switch (padColumn) { + case 0: + // shift right by 3 columns + padIdRemapped = padId + 16 * 3; + break; + case 1: + // shift right by 1 column + padIdRemapped = padId + 16; + break; + case 2: + // shift left by 1 column + padIdRemapped = padId - 16; + break; + case 3: + // shift left by 3 columns + padIdRemapped = padId - 16 * 3; + break; + } + + padsRemapping[deId][padId] = padIdRemapped; + } + } + } + } +} + +o2::mch::DigitModifier createST2MappingCorrector(int runNumber) +{ + constexpr int lastRunToBeFixed = 560402; + // ST2 mapping needs to be corrected only for data collected up to the end of 2024 Pb-Pb + if (runNumber > lastRunToBeFixed) { + // do not modify digits collected after 2024 Pb-Pb + return {}; + } + + static std::unordered_map> padsRemapping; + + if (padsRemapping.empty()) { + initST2PadsRemappingTable(padsRemapping); + } + + return [](o2::mch::Digit& digit) { + // check if the current DE needs some remapping + auto padsRemappingForDe = padsRemapping.find(digit.getDetID()); + if (padsRemappingForDe != padsRemapping.end()) { + // check if the current padID needs to be remapped + auto padIDRemapped = padsRemappingForDe->second.find(digit.getPadID()); + if (padIDRemapped != padsRemappingForDe->second.end()) { + // update the digit + digit.setPadID(padIDRemapped->second); + } + } + }; +} +} // namespace + +namespace o2::mch +{ +DigitModifier createDigitModifier(int runNumber, + bool updateST1, + bool updateST2) +{ + DigitModifier modifierST1 = updateST1 ? createST1MappingCorrector(runNumber) : DigitModifier{}; + DigitModifier modifierST2 = updateST2 ? createST2MappingCorrector(runNumber) : DigitModifier{}; + + if (modifierST1 || modifierST2) { + return [modifierST1, modifierST2](Digit& digit) { + // the ST1/ST2 modifiers are mutually exclusive, depending on the DeID associated to the digit + auto detID = digit.getDetID(); + if (modifierST1 && detID >= 100 && detID < 300) { + modifierST1(digit); + } + if (modifierST2 && detID >= 300 && detID < 500) { + modifierST2(digit); + } + }; + } else { + // return an empty function if none of the modifiers is set + return {}; + } +} + +} // namespace o2::mch diff --git a/Detectors/MUON/MCH/DigitFiltering/src/DigitModifierParam.cxx b/Detectors/MUON/MCH/DigitFiltering/src/DigitModifierParam.cxx new file mode 100644 index 0000000000000..c10a8a87d6bd7 --- /dev/null +++ b/Detectors/MUON/MCH/DigitFiltering/src/DigitModifierParam.cxx @@ -0,0 +1,15 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "MCHDigitFiltering/DigitModifierParam.h" +#include "CommonUtils/ConfigurableParam.h" + +O2ParamImpl(o2::mch::DigitModifierParam) diff --git a/Detectors/MUON/MCH/DigitFiltering/src/MCHDigitFilteringLinkDef.h b/Detectors/MUON/MCH/DigitFiltering/src/MCHDigitFilteringLinkDef.h index 1182d37654c37..c4de20393fbe0 100644 --- a/Detectors/MUON/MCH/DigitFiltering/src/MCHDigitFilteringLinkDef.h +++ b/Detectors/MUON/MCH/DigitFiltering/src/MCHDigitFilteringLinkDef.h @@ -18,4 +18,7 @@ #pragma link C++ class o2::mch::DigitFilterParam + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::mch::DigitFilterParam> + ; +#pragma link C++ class o2::mch::DigitModifierParam + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::mch::DigitModifierParam> + ; + #endif From 3d589f692a92528d6712035b4078a83db3b16b9b Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Wed, 5 Feb 2025 10:30:52 +0000 Subject: [PATCH 2/2] Please consider the following formatting changes --- .../DigitFiltering/src/DigitFilteringSpec.cxx | 2 +- .../MCH/DigitFiltering/src/DigitModifier.cxx | 36 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx b/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx index c8a2706637319..f43b04369bc6e 100644 --- a/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx +++ b/Detectors/MUON/MCH/DigitFiltering/src/DigitFilteringSpec.cxx @@ -139,7 +139,7 @@ class DigitFilteringTask auto digit = digits[i]; // modify the digit if needed - if(mDigitModifier) { + if (mDigitModifier) { mDigitModifier(digit); } diff --git a/Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx b/Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx index 540929b80d193..b2a46bc448aff 100644 --- a/Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx +++ b/Detectors/MUON/MCH/DigitFiltering/src/DigitModifier.cxx @@ -32,8 +32,8 @@ void initST2PadsRemappingTable(std::unordered_map deToRemap{ 300, 301, 302, 303, 400, 401, 402, 403 }; - std::array dsToRemap{ 99, 100, 101, 102, 103 }; + std::array deToRemap{300, 301, 302, 303, 400, 401, 402, 403}; + std::array dsToRemap{99, 100, 101, 102, 103}; for (auto deId : deToRemap) { @@ -70,22 +70,22 @@ void initST2PadsRemappingTable(std::unordered_map