diff --git a/algo/detectors/sts/StsReadoutConfigLegacy.cxx b/algo/detectors/sts/StsReadoutConfigLegacy.cxx index 47cfcf5e92724bfdd20dd18ee6e1184a42efcc58..12ff10f26548b8f3d9486fa75b9d185da1dd9c18 100644 --- a/algo/detectors/sts/StsReadoutConfigLegacy.cxx +++ b/algo/detectors/sts/StsReadoutConfigLegacy.cxx @@ -74,13 +74,14 @@ namespace cbm::algo // consecutively within one component. // Constants - const uint16_t numModules = 13; // Number of modules in the setup - const uint16_t numComp = 5; // Number of components - const uint16_t numCrobPerComp = 1; // Number of CROBs per component - const uint16_t numFebsPerCrob = 5; // Number of FEBs per CROB - const uint16_t numAsicsPerFeb = 8; // Number of ASICs per FEB - const uint16_t numAsicsPerMod = 16; // Number of ASICs per module - const uint16_t numElinksPerCrob = 42; // Number of elinks per CROB + const uint16_t numModules = 13; ///< Number of modules in the setup + const uint16_t numComp = 5; ///< Number of components + const uint16_t numCrobPerComp = 1; ///< Number of CROBs per component + const uint16_t numFebsPerCrob = 5; ///< Number of FEBs per CROB + const uint16_t numAsicsPerFeb = 8; ///< Number of ASICs per FEB + const uint16_t numAsicsPerMod = 16; ///< Number of ASICs per module + const uint16_t numElinksPerCrob = 42; ///< Number of elinks per CROB + const uint16_t numChanPerAsic = 128; ///< Number of channels per ASIC // Equipment IDs for each component // This number is written to the data stream (MicrosliceDescriptor). @@ -146,6 +147,8 @@ namespace cbm::algo modAddress[11] = 0x10008012; modAddress[12] = 0x10018012; + std::map<size_t, std::unordered_set<uint16_t>> maskedchans = BuildMaskSet(); + // Constructing the map (equipmentId, eLink) -> (module, ASIC within module) uint16_t numElinksPerComp = numCrobPerComp * numElinksPerCrob; for (uint16_t comp = 0; comp < numComp; comp++) { @@ -172,6 +175,22 @@ namespace cbm::algo uint32_t asicInFeb = asicIndex % numAsicsPerFeb; // ASIC number within FEB // Asic number is counted downward from numAsicsPerMod - 1 for p side asicInModule = (moduleSide == 1 ? asicInFeb : numAsicsPerMod - 1 - asicInFeb); + + // Init channel mask + const int32_t febId = feb + comp * numCrobPerComp * numFebsPerCrob; + auto mapIt = maskedchans.find(febId); + if (mapIt != maskedchans.end()) { + std::unordered_set<uint16_t>& mask = mapIt->second; + + for (uint32_t chan = 0; chan < numChanPerAsic; chan++) { + const uint32_t chanInFeb = chan + numChanPerAsic * asicInFeb; + if (mask.count(chanInFeb)) { + std::vector<bool>& chanMask = fMaskMap[equipment][elink]; + if (chanMask.empty()) { chanMask.resize(numChanPerAsic, false); } + chanMask[chan] = true; + } + } + } } } fReadoutMap[equipment][elink] = std::make_pair(moduleAddress, asicInModule); @@ -197,7 +216,7 @@ namespace cbm::algo // ------------------------------------------------------------------------------------ - // --- Mapping (equimentId, elink) -> (address, ASIC) -------------------------------- + // --- Mapping (equimentId, elink) -> vector of walk coefficients ------------------- std::vector<double> StsReadoutConfigLegacy::WalkMap(int32_t modAddress, uint16_t asic) { std::vector<double> result; @@ -210,6 +229,21 @@ namespace cbm::algo // ------------------------------------------------------------------------------------ + // --- Mapping (equimentId, elink) -> (vector of mask flags) ------------------------ + std::vector<bool> StsReadoutConfigLegacy::MaskMap(uint16_t equipmentId, uint16_t elinkId) + { + std::vector<bool> result; + auto equipIter = fMaskMap.find(equipmentId); + if (equipIter != fMaskMap.end()) { + auto elinkMap = equipIter->second; + auto elinkIter = elinkMap.find(elinkId); + if (elinkIter != elinkMap.end()) { result = elinkIter->second; } + } + return result; + } + // ------------------------------------------------------------------------------------ + + // ----- Print readout map ------------------------------------------------ std::string StsReadoutConfigLegacy::PrintReadoutMap() { @@ -237,6 +271,50 @@ namespace cbm::algo // ---------------------------------------------------------------------------- + // --- Init map of masked channels --------------------------------------------- + std::map<size_t, std::unordered_set<uint16_t>> StsReadoutConfigLegacy::BuildMaskSet() + { + // Taken from /macro/beamtime/mcbm2022/sts_mask_channels.par + std::map<size_t, std::unordered_set<uint16_t>> maskedchans; + + maskedchans[6] = {15, 17, 23, 27, 29, 35, 37, 39, 41, 45, 47, 51, 55, 57, 59, 63, 67, 69, + 73, 75, 81, 83, 85, 87, 89, 91, 101, 103, 125, 137, 141, 145, 147, 151, 157, 159, + 161, 167, 169, 173, 189, 191, 197, 199, 205, 227, 279, 313, 357, 359, 393, 395, 399, 401, + 403, 405, 415, 447, 471, 487, 527, 641, 643, 655, 657, 663, 665, 667, 669, 671, 679, 681, + 685, 687, 689, 695, 697, 699, 701, 702, 703, 705, 707, 715, 717, 718, 719, 721, 723, 727, + 733, 735, 737, 739, 741, 745, 747, 751, 753, 755, 759, 761, 768, 769, 835, 845, 851, 873, + 897, 899, 953, 967, 971, 978, 979, 982, 985, 991, 997, 999, 1005, 1009, 1011, 1013}; + + maskedchans[7] = {1022, 1020, 764, 642, 638, 636, 514, 510, 508, 386, 258, 256, 129, 128, 127, 16}; + + maskedchans[11] = {46, 66, 100, 102, 106, 108, 114, 118, 120, 122}; + + maskedchans[12] = {767, 762, 750, 746, 740, 712, 710, 708, 692, 674, 662, 658, + 652, 642, 380, 378, 376, 370, 356, 352, 312, 294, 292}; + + maskedchans[13] = {644, 668, 670, 688, 694, 696, 700, 704, 710, 716, 720, + 724, 732, 738, 740, 742, 744, 754, 762, 765, 767}; + + maskedchans[15] = {1023, 132, 124}; + + maskedchans[18] = {1, 131, 253, 385, 387, 451, 509, 641, 719, 763, 765, 1021, 1023}; + + maskedchans[19] = {1020, 1018, 1012, 1010, 1008, 1000, 996, 982, 980, 978, 967, 890, 838, 836, 772, 766, 765, 759, + 751, 747, 743, 739, 735, 727, 723, 719, 715, 711, 707, 683, 675, 671, 667, 663, 659, 655, + 651, 647, 643, 640, 636, 587, 514, 513, 512, 511, 509, 388, 378, 254, 146, 126, 124, 122, + 114, 110, 108, 106, 104, 102, 100, 98, 96, 94, 92, 90, 88, 86, 84, 82, 80, 78, + 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, + 59, 58, 57, 56, 54, 50, 48, 44, 42, 41, 40, 38, 36, 32, 28}; + + maskedchans[22] = {385, 402, 513, 517, 518, 520, 521, 522, 523, 524, 525, 527, 530, 538, + 545, 610, 614, 616, 618, 622, 623, 624, 625, 633, 641, 658, 896, 904}; + + maskedchans[24] = {993}; + + return maskedchans; + } + + // --- Initialise the walk map --------------------------------------------- void StsReadoutConfigLegacy::InitWalkCoeffs() { diff --git a/algo/detectors/sts/StsReadoutConfigLegacy.h b/algo/detectors/sts/StsReadoutConfigLegacy.h index 83dfd2432debf627922fbf16d70a2c94152c8732..932e25b55f17d3639d2f80265154368dc94ce1b7 100644 --- a/algo/detectors/sts/StsReadoutConfigLegacy.h +++ b/algo/detectors/sts/StsReadoutConfigLegacy.h @@ -7,6 +7,7 @@ #include <map> #include <sstream> +#include <unordered_set> #include <utility> #include <vector> @@ -58,12 +59,12 @@ namespace cbm::algo size_t GetNumElinks(); - /** @brief API: Mapping from component and elink to address and ASIC number + /** @brief API: Mapping from component and elink to channel mask flags ** @param equipId Equipment identifier (component) ** @param elink Elink number within component - ** @return (module address, ASIC number within module) + ** @return (vector of mask flags for channels per asic) */ - std::pair<int32_t, uint16_t> Map(uint16_t equipId, uint16_t elink); + std::vector<bool> MaskMap(uint16_t equipId, uint16_t elink); /** @brief API: Mapping from module address and ASIC number to walk coefficients. @@ -73,6 +74,13 @@ namespace cbm::algo */ std::vector<double> WalkMap(int32_t modAddress, uint16_t asic); + /** @brief API: Mapping from component and elink to address and ASIC number + ** @param equipId Equipment identifier (component) + ** @param elink Elink number within component + ** @return (module address, ASIC number within module) + */ + std::pair<int32_t, uint16_t> Map(uint16_t equipId, uint16_t elink); + /** @brief Debug output of readout map **/ std::string PrintReadoutMap(); @@ -87,11 +95,18 @@ namespace cbm::algo // --- Map index: (module address, ASIC number in module, ADC value), map value: (walk coefficient) std::map<int32_t, std::vector<std::vector<double>>> fWalkMap; + // --- STS channel mask map + // --- Map index: (equipment, elink), map value: (vector of mask flags for channels per asic) + std::map<uint16_t, std::map<size_t, std::vector<bool>>> fMaskMap = {}; //! + /** @brief Initialisation of readout map **/ void Init(); /** @brief Initialisation of walk map **/ void InitWalkCoeffs(); + + /** @brief Creates a list of masked channels from hardcoded values **/ + std::map<size_t, std::unordered_set<uint16_t>> BuildMaskSet(); }; } /* namespace cbm::algo */ diff --git a/algo/detectors/sts/UnpackSts.cxx b/algo/detectors/sts/UnpackSts.cxx index 77829fa0f7d6151fe716f84afa40823dd25a27bf..7ceb4cca1abbb7b9845ef888535061920685ed7d 100644 --- a/algo/detectors/sts/UnpackSts.cxx +++ b/algo/detectors/sts/UnpackSts.cxx @@ -108,6 +108,9 @@ namespace cbm::algo const UnpackStsElinkPar& elinkPar = fParams.fElinkParams.at(elink); uint32_t asicNr = elinkPar.fAsicNr; + // --- Check for masked channel + if (!elinkPar.fChanMask.empty() && elinkPar.fChanMask[message.GetHitChannel()] == true) { return; } + // --- Hardware-to-software address uint32_t channel = 0; if (asicNr < fParams.fNumAsicsPerModule / 2) { // front side (n side); channels counted upward diff --git a/algo/detectors/sts/UnpackSts.h b/algo/detectors/sts/UnpackSts.h index 31cad3bf1f4f6f269b20d3dbfe6c23eac6894489..d06db8877a899396eddcb1789a738b758a48d800 100644 --- a/algo/detectors/sts/UnpackSts.h +++ b/algo/detectors/sts/UnpackSts.h @@ -29,12 +29,13 @@ namespace cbm::algo ** @brief STS Unpacking parameters for one eLink / ASIC **/ struct UnpackStsElinkPar { - int32_t fAddress = 0; ///< CbmStsAddress for the connected module - uint32_t fAsicNr = 0; ///< Number of connected ASIC within the module - uint64_t fTimeOffset = 0.; ///< Time calibration parameter - double fAdcOffset = 0.; ///< Charge calibration parameter - double fAdcGain = 0.; ///< Charge calibration parameter - std::vector<double> fWalk; ///< Walk correction coefficients + int32_t fAddress = 0; ///< CbmStsAddress for the connected module + uint32_t fAsicNr = 0; ///< Number of connected ASIC within the module + uint64_t fTimeOffset = 0.; ///< Time calibration parameter + double fAdcOffset = 0.; ///< Charge calibration parameter + double fAdcGain = 0.; ///< Charge calibration parameter + std::vector<double> fWalk; ///< Walk correction coefficients + std::vector<bool> fChanMask; ///< Channel masking flags }; diff --git a/algo/unpack/Unpack.cxx b/algo/unpack/Unpack.cxx index 0142a298b784202b026d604d7f1fd7e2bd9dd489..e19af981ee4375a9a4be7bf63383889256dddf02 100644 --- a/algo/unpack/Unpack.cxx +++ b/algo/unpack/Unpack.cxx @@ -253,6 +253,7 @@ namespace cbm::algo elinkPar.fAdcOffset = 1.; elinkPar.fAdcGain = 1.; if (fApplyWalkCorrection) elinkPar.fWalk = fStsConfig.WalkMap(elinkPar.fAddress, elinkPar.fAsicNr); + elinkPar.fChanMask = fStsConfig.MaskMap(equip, elink); // TODO: Add parameters for time and ADC calibration par->fElinkParams.push_back(elinkPar); }