From e2764f16289f4a90ef6dfdb84652a293b70975d8 Mon Sep 17 00:00:00 2001 From: Dominik Smith <d.smith@gsi.de> Date: Wed, 21 Jun 2023 12:41:11 +0000 Subject: [PATCH] Rich unpacker in cbm::algo --- algo/CMakeLists.txt | 2 + algo/detectors/rich/RichReadoutConfig.cxx | 355 ++++++++++++++++++++++ algo/detectors/rich/RichReadoutConfig.h | 89 ++++++ algo/detectors/rich/UnpackRich.cxx | 322 ++++++++++++++++++++ algo/detectors/rich/UnpackRich.h | 250 +++++++++++++++ algo/unpack/Unpack.cxx | 22 ++ algo/unpack/Unpack.h | 9 + 7 files changed, 1049 insertions(+) create mode 100644 algo/detectors/rich/RichReadoutConfig.cxx create mode 100644 algo/detectors/rich/RichReadoutConfig.h create mode 100644 algo/detectors/rich/UnpackRich.cxx create mode 100644 algo/detectors/rich/UnpackRich.h diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index 78fa9029f8..9d8de75311 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -35,6 +35,8 @@ set(SRCS detectors/trd/UnpackTrd.cxx detectors/trd2d/Trd2dReadoutConfig.cxx detectors/trd2d/UnpackTrd2d.cxx + detectors/rich/RichReadoutConfig.cxx + detectors/rich/UnpackRich.cxx global/Reco.cxx ) diff --git a/algo/detectors/rich/RichReadoutConfig.cxx b/algo/detectors/rich/RichReadoutConfig.cxx new file mode 100644 index 0000000000..dd188e6b02 --- /dev/null +++ b/algo/detectors/rich/RichReadoutConfig.cxx @@ -0,0 +1,355 @@ +/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Dominik Smith [committer] */ + +#include "RichReadoutConfig.h" + +#include <cassert> +#include <iomanip> + +using std::setw; + +namespace cbm::algo +{ + + + // --- Constructor ------------------------------------------------------------------ + RichReadoutConfig::RichReadoutConfig() { Init(); } + // ------------------------------------------------------------------------------------ + + + // --- Destructor ----------------------------------------------------------------- + RichReadoutConfig::~RichReadoutConfig() {} + // ------------------------------------------------------------------------------------ + + + // --- Equipment IDs -------------------------------------------------------------- + std::vector<uint16_t> RichReadoutConfig::GetEquipmentIds() + { + std::vector<uint16_t> result; + for (auto& entry : fReadoutMap) + result.push_back(entry.first); + return result; + } + // ------------------------------------------------------------------------------------ + + + // --- Number of elinks for a component / equipment ------------------------------- + size_t RichReadoutConfig::GetNumElinks(uint16_t equipmentId) + { + size_t result = 0; + auto it = fReadoutMap.find(equipmentId); + if (it != fReadoutMap.end()) result = fReadoutMap[equipmentId].size(); + return result; + } + // ------------------------------------------------------------------------------------ + + + // --- Total number of elinks for STS --------------------------------------------- + size_t RichReadoutConfig::GetNumElinks() + { + size_t result = 0; + for (auto& entry : fReadoutMap) { + result += entry.second.size(); + } + return result; + } + // ------------------------------------------------------------------------------------ + + + // --- Initialise the mapping structure -------------------------------------------- + void RichReadoutConfig::Init() + { + // This here refers to the mCBM 2021 setup. + // Taken from CbmMcbm2018RichPar in combination with macro/beamtime/mcbm2021/mRich.par + + // Constants + const uint16_t numComp = 1; // Number of components + const uint16_t numElinksPerComp = 74; // Number of elinks per component + const uint16_t numChanPerElink = 33; // Number of channels per Elink + + // Equipment IDs for each component + // This number is written to the data stream (MicrosliceDescriptor). + uint16_t eqId[numComp] = {12289}; + + uint32_t TRBaddresses[numElinksPerComp] = { + 0xc000, 0xc001, 0x7000, 0x7001, 0x7010, 0x7011, 0x7020, 0x7021, 0x7030, 0x7031, 0x7040, 0x7041, 0x7050, + 0x7051, 0x7060, 0x7061, 0x7070, 0x7071, 0x7080, 0x7081, 0x7100, 0x7101, 0x7110, 0x7111, 0x7120, 0x7121, + 0x7130, 0x7131, 0x7140, 0x7141, 0x7150, 0x7151, 0x7160, 0x7161, 0x7170, 0x7171, 0x7180, 0x7181, 0x7200, + 0x7201, 0x7210, 0x7211, 0x7220, 0x7221, 0x7230, 0x7231, 0x7240, 0x7241, 0x7250, 0x7251, 0x7260, 0x7261, + 0x7270, 0x7271, 0x7280, 0x7281, 0x7300, 0x7301, 0x7310, 0x7311, 0x7320, 0x7321, 0x7330, 0x7331, 0x7340, + 0x7341, 0x7350, 0x7351, 0x7360, 0x7361, 0x7370, 0x7371, 0x7380, 0x7381}; + + double ToTshifts[numElinksPerComp][numChanPerElink] = { + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 15.05, 13.85, 14.15, 12.05, 15.05, 12.35, 11.35, 13.75, 13.85, 11.95, + 14.75, 16.15, 16.35, 15.35, 8.15, 9.55, 6.05, 3.85, 5.65, 7.85, 8.65, + 6.85, 7.15, 7.35, 8.05, 9.15, 7.25, 5.85, 7.15, 5.35, 6.95, 8.75}, + {0.00, 13.85, 13.05, 13.25, 11.35, 14.75, 11.75, 10.85, 13.35, 13.25, 11.55, + 13.85, 15.75, 15.75, 14.55, 7.65, 8.65, 5.65, 0.00, 5.65, 7.35, 0.00, + 6.45, 6.85, 6.75, 7.35, 8.55, 6.35, 5.35, 6.35, 4.65, 5.85, 8.15}, + {0.00, 14.15, 13.15, 13.65, 11.75, 14.65, 11.85, 10.35, 13.35, 13.15, 11.55, + 14.15, 15.65, 15.65, 14.65, 7.45, 8.85, 5.75, 3.75, 0.00, 7.55, 8.45, + 6.85, 6.75, 7.15, 7.75, 8.85, 6.85, 5.25, 6.55, 4.85, 6.55, 8.25}, + {0.00, 15.95, 14.75, 15.05, 12.85, 16.45, 12.95, 11.85, 14.75, 14.55, 12.85, + 15.45, 16.95, 16.85, 15.65, 9.15, 9.05, 0.00, 4.55, 6.65, 8.65, 9.55, + 7.45, 7.75, 8.25, 8.85, 10.05, 8.05, 6.45, 7.85, 6.25, 7.75, 9.85}, + {0.00, 17.35, 16.25, 16.35, 14.05, 18.15, 14.55, 13.55, 16.25, 16.05, 14.05, + 17.05, 18.85, 19.25, 17.55, 10.15, 11.45, 7.75, 5.55, 7.45, 9.65, 10.75, + 8.55, 9.15, 9.65, 9.65, 11.25, 9.15, 7.35, 8.55, 7.15, 8.55, 10.65}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 17.65, 16.15, 16.35, 14.15, 17.65, 14.45, 13.15, 16.05, 16.15, 13.85, + 16.35, 18.05, 18.65, 17.05, 9.65, 10.75, 7.85, 5.65, 7.85, 9.55, 10.75, + 8.65, 8.85, 9.35, 9.85, 10.65, 8.85, 7.15, 7.85, 6.15, 8.65, 10.65}, + {0.00, 16.35, 15.25, 15.75, 13.25, 17.25, 13.55, 12.55, 15.25, 15.35, 13.55, + 16.45, 17.65, 18.25, 16.85, 9.25, 10.55, 7.25, 4.35, 6.85, 8.75, 9.75, + 8.35, 8.25, 8.65, 9.35, 10.05, 8.25, 6.85, 7.85, 6.35, 7.85, 9.65}, + {0.00, 16.05, 14.85, 15.35, 13.05, 16.55, 13.45, 12.05, 14.75, 15.05, 13.15, + 15.65, 17.35, 17.65, 16.35, 9.15, 10.45, 7.05, 4.65, 6.55, 8.55, 9.55, + 7.75, 8.15, 8.05, 9.05, 10.25, 8.25, 6.55, 7.85, 6.15, 7.85, 9.65}, + {0.00, 15.55, 14.55, 14.75, 12.65, 16.15, 12.85, 11.65, 14.35, 14.15, 12.65, + 15.35, 16.95, 17.15, 15.85, 8.85, 9.75, 6.75, 4.35, 6.55, 8.55, 9.35, + 7.65, 7.75, 8.15, 9.05, 10.05, 7.85, 6.35, 7.55, 5.35, 7.05, 9.05}, + {0.00, 17.15, 16.15, 16.15, 14.05, 17.65, 14.25, 13.35, 16.15, 16.15, 14.35, + 16.85, 18.05, 18.85, 17.15, 10.05, 11.15, 7.85, 5.55, 7.55, 9.85, 10.55, + 8.75, 9.15, 9.65, 10.05, 11.05, 8.85, 7.35, 8.55, 7.35, 8.85, 10.75}, + {0.00, 16.95, 15.85, 16.15, 14.15, 17.55, 14.05, 13.05, 15.85, 15.85, 13.85, + 16.75, 18.35, 18.75, 17.55, 9.85, 11.35, 7.45, 5.05, 7.45, 9.45, 10.75, + 8.45, 8.85, 9.35, 9.55, 10.75, 8.85, 6.95, 8.55, 6.65, 8.25, 10.05}, + {0.00, 16.85, 15.95, 16.15, 14.05, 17.55, 14.35, 12.85, 15.65, 16.05, 14.05, + 16.65, 18.25, 18.65, 17.35, 9.85, 11.05, 7.65, 5.25, 7.75, 9.55, 10.85, + 8.85, 8.85, 9.45, 10.05, 11.05, 9.05, 7.15, 8.65, 7.05, 8.35, 10.35}, + {0.00, 15.75, 14.25, 14.45, 12.65, 16.15, 13.05, 12.05, 14.55, 14.55, 12.85, + 15.35, 16.85, 17.45, 15.85, 8.85, 9.85, 6.45, 4.15, 6.35, 8.35, 8.05, + 7.55, 7.85, 8.35, 8.65, 9.85, 7.85, 6.35, 7.15, 5.55, 7.75, 9.15}, + {0.00, 15.05, 13.85, 14.15, 12.05, 15.05, 12.55, 11.35, 13.75, 13.85, 11.85, + 14.85, 16.35, 16.45, 15.35, 8.35, 9.55, 6.05, 4.05, 6.25, 8.15, 8.95, + 7.15, 6.85, 7.65, 8.55, 9.35, 7.55, 6.05, 6.95, 5.35, 7.25, 8.95}, + {0.00, 14.35, 13.35, 13.65, 11.35, 15.05, 12.15, 10.75, 13.55, 12.75, 11.65, + 14.45, 15.75, 15.65, 15.25, 7.75, 8.85, 5.75, 3.55, 5.85, 7.35, 8.65, + 6.95, 7.15, 7.35, 8.05, 8.75, 6.95, 5.55, 6.55, 5.35, 6.85, 8.05}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 14.75, 13.45, 14.25, 11.85, 15.15, 12.35, 11.05, 13.85, 13.65, 12.05, + 14.55, 16.25, 16.35, 15.55, 7.85, 9.55, 5.85, 3.75, 5.85, 7.95, 8.65, + 0.00, 7.25, 7.85, 8.25, 9.05, 7.45, 5.85, 6.95, 5.65, 7.05, 9.05}, + {0.00, 16.55, 15.05, 15.75, 13.55, 16.65, 13.35, 12.65, 15.05, 15.35, 13.25, + 16.05, 17.55, 17.35, 16.65, 9.15, 10.65, 7.15, 4.55, 7.15, 8.75, 9.65, + 8.25, 8.65, 8.85, 9.35, 10.35, 8.55, 6.85, 8.05, 6.65, 8.25, 10.05}, + {0.00, 14.15, 13.05, 13.85, 11.55, 14.75, 11.85, 10.85, 13.25, 13.45, 11.35, + 14.05, 15.85, 16.05, 14.85, 7.85, 8.85, 5.85, 3.55, 5.75, 7.55, 8.55, + 7.05, 0.00, 7.35, 7.85, 9.05, 7.15, 5.35, 6.55, 5.35, 6.65, 8.65}, + {0.00, 14.55, 13.65, 14.15, 12.35, 15.65, 12.75, 11.55, 14.05, 14.15, 12.05, + 14.35, 16.05, 16.35, 15.35, 8.35, 9.15, 6.15, 4.05, 5.85, 7.55, 8.85, + 0.00, 7.35, 7.75, 8.25, 9.15, 7.05, 5.75, 7.15, 5.75, 7.35, 8.65}, + {0.00, 15.85, 14.85, 15.05, 13.05, 16.55, 13.25, 12.35, 15.05, 15.05, 13.15, + 16.05, 17.35, 17.75, 16.55, 9.25, 10.35, 6.75, 4.65, 6.65, 8.85, 9.45, + 7.85, 8.05, 8.55, 8.95, 10.05, 8.25, 6.35, 7.75, 6.25, 7.85, 9.55}, + {0.00, 16.55, 15.25, 15.85, 13.55, 16.95, 14.05, 12.85, 15.35, 15.65, 13.65, + 16.35, 17.95, 18.45, 17.05, 9.65, 10.85, 7.45, 5.15, 7.15, 9.35, 10.35, + 8.55, 8.55, 9.15, 9.45, 10.65, 8.85, 6.85, 8.15, 6.55, 8.05, 10.15}, + {0.00, 16.55, 15.45, 15.55, 13.65, 16.75, 14.05, 12.75, 15.55, 15.55, 13.75, + 16.55, 17.95, 18.35, 17.15, 9.75, 10.55, 8.35, 5.05, 7.75, 9.15, 10.45, + 8.65, 8.95, 9.15, 9.75, 10.85, 8.85, 7.05, 8.45, 6.55, 8.35, 10.35}, + {0.00, 15.05, 13.35, 14.15, 12.25, 15.55, 12.35, 11.25, 14.15, 14.05, 12.35, + 14.85, 16.15, 16.65, 15.65, 8.25, 9.35, 5.95, 3.55, 6.05, 8.05, 8.65, + 7.15, 7.35, 8.05, 8.05, 9.35, 7.15, 5.45, 6.85, 5.25, 6.55, 8.55}, + {0.00, 16.75, 15.55, 15.85, 13.65, 17.55, 14.05, 12.85, 15.65, 15.55, 13.65, + 16.55, 17.85, 18.45, 17.45, 9.65, 10.65, 7.65, 5.15, 7.55, 9.45, 10.35, + 8.65, 8.65, 9.35, 10.05, 10.85, 9.05, 7.15, 8.55, 6.95, 8.55, 10.55}, + {0.00, 15.65, 14.55, 15.05, 12.75, 16.15, 12.85, 11.75, 14.65, 14.65, 12.85, + 15.55, 17.15, 17.45, 15.95, 8.75, 9.85, 6.75, 4.35, 6.65, 8.35, 9.55, + 7.95, 7.75, 8.35, 8.95, 9.85, 8.05, 6.55, 7.35, 6.05, 7.35, 9.05}, + {0.00, 16.85, 15.65, 16.05, 14.05, 17.05, 14.25, 12.15, 15.55, 15.65, 13.85, + 16.15, 17.55, 18.05, 16.95, 9.55, 10.55, 7.55, 4.75, 7.25, 9.15, 10.35, + 8.35, 8.45, 9.15, 9.55, 10.85, 8.75, 7.05, 8.35, 7.05, 8.55, 10.35}, + {0.00, 15.85, 14.75, 15.05, 13.15, 15.85, 12.65, 12.05, 14.75, 15.05, 12.45, + 0.00, 16.55, 17.35, 16.05, 8.95, 9.65, 6.85, 4.65, 6.35, 8.15, 9.25, + 7.35, 8.15, 8.55, 9.05, 9.65, 8.15, 6.55, 7.35, 5.55, 7.75, 9.65}, + {0.00, 16.85, 16.15, 16.05, 14.15, 17.05, 14.25, 12.75, 16.05, 15.85, 13.95, + 16.65, 18.35, 18.15, 16.85, 9.65, 10.55, 7.65, 5.65, 7.55, 9.55, 10.55, + 8.85, 8.65, 9.15, 10.05, 10.75, 9.05, 6.85, 8.15, 6.15, 8.65, 10.75}, + {0.00, 14.35, 13.25, 13.85, 11.55, 15.05, 11.85, 10.85, 13.35, 13.35, 11.15, + 14.15, 15.65, 15.85, 14.25, 7.65, 8.85, 5.75, 4.05, 5.65, 7.85, 8.65, + 6.65, 7.15, 7.55, 7.85, 8.65, 7.05, 5.35, 6.65, 5.05, 6.75, 8.35}, + {0.00, 14.35, 13.15, 13.55, 11.75, 14.75, 11.95, 10.75, 13.05, 13.15, 11.65, + 14.25, 15.75, 15.85, 14.55, 7.85, 8.85, 5.75, 3.75, 5.35, 7.15, 8.35, + 6.85, 6.85, 7.25, 7.65, 8.65, 6.45, 5.15, 6.55, 4.85, 6.05, 8.35}, + {0.00, 17.15, 15.95, 16.15, 13.85, 17.25, 14.35, 12.85, 15.55, 15.85, 13.55, + 16.75, 18.45, 18.85, 16.65, 10.25, 11.15, 7.65, 5.35, 7.35, 9.25, 10.35, + 8.25, 8.35, 9.05, 9.65, 10.65, 8.85, 7.15, 8.45, 5.95, 8.65, 10.05}, + {0.00, 14.85, 13.85, 14.25, 11.65, 15.05, 12.05, 11.25, 13.85, 13.85, 11.55, + 14.65, 16.05, 16.45, 15.25, 8.45, 9.05, 6.05, 4.15, 5.75, 7.95, 8.75, + 6.85, 7.05, 7.45, 8.15, 9.15, 7.05, 5.65, 6.75, 5.35, 7.05, 8.95}, + {0.00, 17.05, 15.85, 16.05, 14.15, 17.55, 14.35, 13.05, 15.55, 15.65, 13.95, + 16.65, 18.35, 18.55, 17.05, 9.55, 10.55, 7.35, 5.35, 7.25, 9.35, 10.35, + 8.65, 8.75, 9.15, 9.55, 10.75, 8.65, 7.25, 8.75, 6.85, 8.35, 10.55}, + {0.00, 14.15, 13.15, 13.75, 11.55, 14.55, 11.55, 10.55, 13.35, 12.95, 11.45, + 14.05, 15.65, 15.65, 14.85, 7.95, 8.75, 5.65, 3.45, 5.65, 7.25, 8.05, + 6.45, 0.00, 7.25, 7.65, 8.55, 6.85, 5.15, 6.65, 5.05, 6.55, 0.00}, + {0.00, 16.15, 15.05, 15.55, 13.25, 16.85, 13.55, 12.35, 15.35, 15.15, 13.05, + 15.85, 17.95, 17.65, 16.65, 9.35, 10.55, 7.25, 4.85, 7.35, 9.15, 10.05, + 7.95, 8.35, 8.85, 9.05, 10.35, 8.25, 6.65, 8.15, 6.55, 0.00, 9.85}, + {0.00, 15.65, 14.55, 14.75, 13.05, 15.95, 12.45, 11.95, 14.25, 13.65, 12.05, + 14.65, 16.35, 16.35, 15.25, 8.55, 9.85, 6.85, 4.15, 5.65, 7.55, 8.65, + 7.55, 7.15, 7.35, 8.35, 9.15, 6.85, 6.25, 7.05, 6.15, 7.85, 8.35}, + {0.00, 14.75, 13.55, 14.05, 12.05, 15.35, 12.05, 11.15, 13.95, 13.55, 11.65, + 14.15, 15.85, 16.15, 15.25, 8.15, 9.45, 0.00, 3.95, 5.85, 7.85, 8.65, + 7.05, 7.25, 7.55, 8.35, 9.25, 7.55, 5.75, 7.05, 5.65, 6.95, 8.75}, + {0.00, 15.05, 13.55, 14.35, 11.95, 15.55, 12.05, 11.25, 13.85, 13.75, 12.15, + 14.65, 16.35, 16.35, 15.35, 0.00, 9.55, 5.85, 3.55, 5.95, 7.75, 8.85, + 7.05, 7.65, 7.65, 8.05, 9.05, 7.55, 5.85, 7.15, 5.65, 7.15, 9.05}, + {0.00, 16.05, 14.65, 15.35, 13.05, 16.75, 13.55, 12.35, 14.85, 15.05, 12.95, + 16.05, 17.55, 17.65, 16.45, 9.05, 10.15, 6.85, 4.85, 6.95, 9.15, 9.85, + 7.95, 8.15, 8.85, 8.85, 10.05, 8.25, 6.55, 8.05, 6.15, 7.75, 9.65}, + {0.00, 16.65, 15.55, 15.75, 13.75, 16.75, 13.65, 12.65, 15.05, 15.35, 13.35, + 16.55, 17.85, 18.35, 16.85, 9.65, 10.75, 7.35, 5.05, 7.25, 9.45, 10.25, + 8.65, 8.55, 9.25, 9.85, 10.75, 8.65, 7.15, 8.15, 6.15, 8.05, 10.25}, + {0.00, 15.15, 13.65, 14.15, 12.25, 15.95, 12.65, 11.65, 14.05, 14.45, 12.25, + 14.75, 16.15, 16.55, 15.25, 8.45, 9.35, 6.35, 4.25, 6.35, 8.25, 9.45, + 8.05, 8.35, 7.95, 8.25, 10.05, 7.45, 6.65, 7.05, 5.05, 6.65, 8.45}, + {0.00, 16.35, 14.15, 15.55, 12.65, 16.45, 13.65, 11.85, 15.05, 14.15, 12.85, + 15.35, 17.15, 17.35, 15.85, 8.55, 9.65, 6.55, 4.35, 6.15, 8.65, 9.55, + 7.65, 7.55, 8.25, 9.25, 9.75, 7.75, 6.05, 7.05, 5.35, 6.95, 8.85}, + {0.00, 16.65, 15.45, 15.85, 13.65, 17.15, 14.05, 12.85, 15.55, 15.45, 13.85, + 16.55, 17.85, 18.35, 17.05, 9.35, 10.55, 7.15, 5.05, 7.05, 9.05, 10.25, + 8.15, 8.65, 9.05, 9.55, 0.00, 8.55, 7.05, 8.05, 6.55, 7.85, 10.15}, + {0.00, 15.55, 14.55, 14.85, 12.75, 16.05, 12.95, 11.85, 14.55, 14.75, 12.75, + 15.35, 16.85, 17.25, 15.75, 8.85, 9.85, 6.35, 4.25, 6.05, 8.25, 9.35, + 7.55, 7.65, 8.05, 8.35, 9.55, 7.65, 5.75, 7.15, 5.55, 7.05, 8.85}, + {0.00, 17.85, 16.75, 17.05, 14.65, 18.05, 14.85, 13.75, 16.65, 16.55, 14.75, + 17.05, 18.55, 19.05, 17.55, 10.05, 11.05, 8.35, 6.05, 8.05, 10.35, 11.15, + 9.05, 9.65, 9.85, 10.65, 11.35, 9.55, 7.85, 8.55, 7.55, 9.15, 10.05}, + {0.00, 16.05, 15.05, 15.25, 13.55, 16.75, 13.75, 12.35, 15.15, 15.05, 13.35, + 15.85, 17.55, 17.85, 16.55, 9.05, 10.15, 7.25, 4.55, 6.85, 8.85, 9.75, + 8.05, 8.65, 8.75, 9.25, 10.15, 8.25, 6.35, 7.85, 6.25, 7.55, 9.35}, + {0.00, 15.65, 14.15, 14.45, 12.45, 15.95, 12.85, 11.55, 14.15, 14.15, 12.75, + 15.05, 16.65, 16.85, 15.65, 8.85, 9.85, 6.55, 4.35, 6.45, 8.35, 9.35, + 7.65, 7.55, 8.05, 8.55, 9.55, 7.75, 6.15, 7.35, 5.65, 7.55, 9.05}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 14.85, 13.05, 13.95, 11.65, 15.05, 12.15, 11.15, 13.85, 13.65, 12.15, + 14.65, 15.95, 16.35, 15.15, 8.05, 9.35, 5.95, 3.55, 3.35, 7.55, 8.15, + 6.65, 7.25, 7.65, 7.85, 8.75, 7.15, 5.45, 6.85, 5.45, 6.85, 8.75}, + {0.00, 15.25, 14.25, 14.85, 12.55, 15.95, 12.65, 12.05, 14.35, 14.35, 12.55, + 15.15, 16.65, 16.85, 16.05, 8.55, 9.75, 6.35, -0.15, 6.15, 8.15, 9.15, + 6.95, 7.65, 8.15, 8.65, 9.65, 7.25, 5.85, 7.05, 5.65, 6.75, 9.05}, + {0.00, 14.35, 13.15, 13.55, 11.75, 14.65, 11.75, 10.95, 13.05, 13.25, 11.65, + 13.85, 15.75, 16.05, 14.65, 7.65, 8.85, 5.75, 3.35, 0.00, 7.15, 8.15, + 6.75, 6.55, 7.05, 7.85, 8.85, 6.75, 5.25, 6.55, 5.05, 6.55, 8.25}, + {0.00, 13.45, 15.05, 15.35, 12.95, 16.25, 13.15, 12.05, 14.85, 14.85, 13.05, + 15.65, 17.05, 17.35, 16.05, 9.05, 10.15, 7.05, 4.55, 6.85, 8.55, 9.75, + 7.75, 0.00, 8.35, 9.05, 10.05, 8.05, 6.35, 7.85, 6.25, 7.65, 9.75}, + {0.00, 15.55, 14.35, 14.35, 12.85, 15.75, 12.65, 11.55, 14.85, 14.15, 12.55, + 15.35, 16.55, 16.75, 15.65, 8.95, 10.05, 6.05, 3.75, 5.95, 7.65, 9.05, + 7.05, 7.25, 7.55, 8.05, 9.15, 7.55, 5.55, 6.95, 5.45, 6.55, 8.35}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 16.05, 15.05, 15.55, 13.65, 16.75, 13.45, 12.55, 15.55, 15.45, 13.35, + 16.15, 17.55, 18.05, 16.65, 9.15, 10.55, 7.15, 4.45, 7.15, 8.65, 9.75, + 8.15, 8.25, 8.65, 9.05, 10.35, 8.35, 6.45, 7.95, 6.25, 7.65, 9.65}, + {0.00, 16.65, 14.35, 15.05, 12.65, 16.15, 13.15, 12.35, 15.05, 14.65, 12.85, + 15.75, 17.35, 17.35, 16.05, 8.85, 10.05, 6.45, 4.65, 6.55, 8.65, 9.35, + 7.95, 8.75, 8.35, 8.85, 10.05, 8.05, 6.05, 7.35, 5.75, 7.35, 8.95}, + {0.00, 16.65, 15.35, 15.85, 13.85, 16.85, 13.15, 12.85, 14.65, 14.85, 13.05, + 15.65, 17.25, 17.05, 16.05, 9.05, 10.05, 6.95, 4.65, 6.55, 8.55, 9.85, + 7.65, 8.65, 8.25, 9.05, 10.05, 7.75, 6.35, 7.35, 5.65, 7.35, 9.55}, + {0.00, 16.75, 15.35, 15.85, 13.85, 17.35, 14.25, 12.85, 15.85, 15.75, 13.75, + 16.65, 18.25, 18.55, 17.15, 10.05, 11.05, 7.05, 4.85, 6.95, 9.05, 10.25, + 8.15, 8.55, 8.85, 9.65, 10.55, 8.65, 6.65, 8.05, 6.25, 8.15, 10.05}, + {0.00, 16.85, 15.75, 16.25, 13.85, 17.45, 13.95, 12.85, 15.65, 15.85, 13.65, + 16.45, 17.75, 18.35, 16.55, 9.65, 10.85, 7.65, 5.25, 7.35, 9.15, 10.05, + 7.95, 8.75, 9.05, 9.55, 10.55, 8.55, 6.75, 8.05, 5.85, 8.45, 10.35}, + {0.00, 16.95, 15.95, 16.05, 14.05, 17.45, 14.35, 13.05, 15.65, 15.85, 14.15, + 16.85, 18.35, 18.55, 17.45, 10.05, 11.35, 7.75, 5.15, 7.45, 9.65, 10.55, + 8.65, 8.65, 9.15, 9.55, 10.85, 9.25, 7.25, 8.55, 7.15, 8.85, 10.65}, + {0.00, 16.85, 15.55, 15.85, 13.95, 17.15, 14.35, 13.15, 15.75, 15.65, 13.85, + 16.65, 18.35, 18.75, 17.55, 9.75, 10.85, 7.35, 5.15, 7.45, 9.35, 10.35, + 8.35, 8.65, 9.15, 9.55, 11.05, 8.85, 7.05, 8.35, 6.85, 8.35, 10.05}, + {0.00, 14.75, 13.65, 13.95, 12.15, 15.35, 12.45, 11.35, 13.85, 13.85, 12.05, + 14.55, 15.85, 16.35, 15.25, 8.05, 9.55, 6.05, 3.95, 6.05, 8.25, 9.05, + 7.35, 7.85, 8.05, 8.45, 9.45, 7.35, 5.85, 7.15, 5.45, 7.25, 8.65}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, + {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, + 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}}; + + // Constructing the map (equipmentId, asic address, channel) -> (tot shift) + for (uint16_t comp = 0; comp < numComp; comp++) { + uint16_t equipment = eqId[comp]; + for (uint16_t elink = 0; elink < numElinksPerComp; elink++) { + uint32_t address = TRBaddresses[elink]; + fReadoutMap[equipment][address].resize(numChanPerElink); + for (uint16_t chan = 0; chan < numChanPerElink; chan++) { + fReadoutMap[equipment][address][chan] = ToTshifts[elink][chan]; + } //# channel + } //# elink + } //# component + } + // ------------------------------------------------------------------------------------ + + + // --- Mapping (equimentId, trb address, channel) -> (tot shift) -------------------- + double RichReadoutConfig::Map(uint16_t equipmentId, uint32_t address, uint16_t chan) + { + double result = -1.; + auto equipIter = fReadoutMap.find(equipmentId); + if (equipIter != fReadoutMap.end()) { + auto elinkMap = equipIter->second; + auto elinkIter = elinkMap.find(address); + if (elinkIter != elinkMap.end()) { + if (chan < elinkIter->second.size()) { result = elinkIter->second.at(chan); } + } + } + return result; + } + // ------------------------------------------------------------------------------------ + + // --- Returns map (trb address, channel) -> (tot shift) ---------------------------- + std::map<uint32_t, std::vector<double>> RichReadoutConfig::Map(uint16_t equipmentId) + { + std::map<uint32_t, std::vector<double>> result; + auto equipIter = fReadoutMap.find(equipmentId); + if (equipIter != fReadoutMap.end()) { result = equipIter->second; } + return result; + } + // ------------------------------------------------------------------------------------ + + + // ----- Print readout map ------------------------------------------------ + std::string RichReadoutConfig::PrintReadoutMap() + { + std::stringstream ss; + for (auto& equipment : fReadoutMap) { + uint16_t eqId = equipment.first; + for (auto& trb : equipment.second) { + uint32_t address = trb.first; + std::vector<double>& shifts = trb.second; + for (size_t channel = 0; channel < shifts.size(); channel++) { + ss << "\n Equipment " << eqId << " trb address " << setw(2) << address; + ss << " channel " << setw(2) << channel << " tot shift " << shifts.at(channel); + } + } + } + return ss.str(); + } + // ---------------------------------------------------------------------------- + + +} /* namespace cbm::algo */ diff --git a/algo/detectors/rich/RichReadoutConfig.h b/algo/detectors/rich/RichReadoutConfig.h new file mode 100644 index 0000000000..ea811d82a7 --- /dev/null +++ b/algo/detectors/rich/RichReadoutConfig.h @@ -0,0 +1,89 @@ +/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese, Dominik Smith [committer] */ + +#ifndef ALGO_DETECTORS_RICH_RICHREADOUTCONFIG_H +#define ALGO_DETECTORS_RICH_RICHREADOUTCONFIG_H + +#include <map> +#include <sstream> +#include <utility> +#include <vector> + +namespace cbm::algo +{ + + + /** @class RichReadoutConfig + ** @author Dominik Smith <d.smith@gsi.de> + ** @since 3 March 2022 + ** @brief Provides the hardware-to-software address mapping for the CBM-RICH + ** + ** The hardware address as provided in the raw data stream is specified in terms of the + ** equipment identifier (specific to one FLES component) and the trb address within + ** component. This is to be translated to a tot shift value. + ** The mapping of the address spaces is hard-coded in this class. + **/ + + class RichReadoutConfig { + + public: + /** @brief Constructor **/ + RichReadoutConfig(); + + + /** @brief Destructor **/ + virtual ~RichReadoutConfig(); + + + /** @brief Equipment in the configuration + ** @return Vector of equipment IDs + **/ + std::vector<uint16_t> GetEquipmentIds(); + + + /** @brief Number of elinks of a component + ** @param Equipment ID + ** @return Number of elinks + **/ + size_t GetNumElinks(uint16_t equipmentId); + + + /** @brief Total number of elinks for RICH + ** @return Number of elinks + **/ + size_t GetNumElinks(); + + + /** @brief API: Mapping from component, address and channel to tot shift + ** @param equipId Equipment identifier (component) + ** @param address trb address within component + ** @param chan channel within trb address + ** @return tot shift + */ + double Map(uint16_t equipmentId, uint32_t address, uint16_t chan); + + /** @brief API: Returns map from address and channel to tot shift for component + ** @param equipId Equipment identifier (component) + ** @return map: (address, channel) - > tot shift + */ + std::map<uint32_t, std::vector<double>> Map(uint16_t equipmentId); + + + /** @brief Debug output of readout map **/ + std::string PrintReadoutMap(); + + + private: + // --- RICH readout map + // --- Map index: (equipment, trb address, channel), map value: (tot shift) + std::map<uint16_t, std::map<uint32_t, std::vector<double>>> fReadoutMap = {}; //! + + + /** @brief Initialisation of readout map **/ + void Init(); + }; + +} /* namespace cbm::algo */ + +#endif /* ALGO_DETECTORS_RICH_RICHREADOUTCONFIG_H_ */ diff --git a/algo/detectors/rich/UnpackRich.cxx b/algo/detectors/rich/UnpackRich.cxx new file mode 100644 index 0000000000..471504f5f9 --- /dev/null +++ b/algo/detectors/rich/UnpackRich.cxx @@ -0,0 +1,322 @@ +/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig, Dominik Smith [committer] */ + +#include "UnpackRich.h" + +#include <cstdint> + +#include "AlgoFairloggerCompat.h" + +namespace cbm::algo +{ + // ---- Algorithm execution --------------------------------------------- + UnpackRich::resultType UnpackRich::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr, + const uint64_t tTimeslice) + { + // --- Output data + resultType result = {}; + + fMonitor = UnpackRichMonitorData(); + fOutputVec.clear(); + + // Clear CbmTime of MS. Used to get time offset of subtriggers to MS start + fCbmTimeMS = 0; + + RichMicrosliceReader reader; + reader.SetData(msContent, msDescr.size); + + const auto mstime = msDescr.idx; + fMsRefTime = mstime - tTimeslice; + + // There are a lot of MS with 8 bytes size + // Does one need these MS? + if (reader.GetSize() <= 8) return result; + + while (true) { + ProcessTrbPacket(reader); + ProcessHubBlock(reader); + + // -4*2 for 2 last words which contain microslice index + if (reader.GetOffset() >= reader.GetSize() - 8) break; + // -4*3 for 0xffffffff padding and 2 last words which contain microslice index + if (reader.IsNextPadding() && reader.GetOffset() >= reader.GetSize() - 12) break; + } + uint32_t msIndexWord1 = reader.NextWord(); + uint32_t msIndexWord2 = reader.NextWord(); + + result.first = fOutputVec; + result.second = fMonitor; + return result; + } + + + void UnpackRich::ProcessTrbPacket(RichMicrosliceReader& reader) + { + //process CBM time + const uint32_t word_MSB = reader.NextWord(); // CBM 63:32 + const uint32_t word_LSB = reader.NextWord(); // CBM 31: 0 + fCbmTimePacket = (uint64_t) word_MSB << 32 | word_LSB; + if (fCbmTimeMS == 0) fCbmTimeMS = fCbmTimePacket; + + //discard unused words + for (auto l = 0; l < 10; ++l) { + reader.NextWord(); + } + + //process remaining words + for (auto l = 0; l < 14; ++l) { + const uint32_t wordEpoch = reader.NextWord(); + const uint32_t epoch = ProcessEpoch(wordEpoch); + const uint32_t wordTime = reader.NextWord(); + const RichTdcTimeData td = ProcessTimeData(wordTime); + const double fullTime = CalculateTime(epoch, td.fCoarse, td.fFine); + + if (l == 0) fPrevLastCh0ReTime[12] = fullTime; + if (l == 1) fMbsCorr = fullTime - fPrevLastCh0ReTime[12]; // = MbsPrevTimeCh1 - MbsPrevTimeCh0 + if (l > 1) fPrevLastCh0ReTime[l - 2] = fullTime; + } + + const uint32_t trbNum = reader.NextWord(); // TRB trigger number + //if (isLog()) L_(debug4) << getLogHeader(reader) << "TRB Num:" << reader.GetWordAsHexString(trbNum); + } + + + void UnpackRich::ProcessHubBlock(RichMicrosliceReader& reader) + { + uint32_t word = reader.NextWord(); + const uint32_t hubId = word & 0xffff; // 16 bits + const uint32_t hubSize = (word >> 16) & 0xffff; // 16 bits + + bool isLast = false; // if true then it is CTS sub-sub-event + size_t totalSize = 0; + fCurrentSubSubEvent = 0; + + uint32_t subSubEventId, subSubEventSize; + + //loop over events in hub block + while (totalSize < hubSize) { + word = reader.NextWord(); + subSubEventId = word & 0xffff; // 16 bits + subSubEventSize = (word >> 16) & 0xffff; // 16 bits + isLast = reader.IsLastSubSubEvent(subSubEventSize); // if true then it is CTS sub-sub-event + totalSize += (1 + subSubEventSize); + + if (!isLast) { // all except last are DiRICH events + if (((subSubEventId >> 12) & 0xF) != 0x7) { // catch invalid ids + fMonitor.fNumErrInvalidHubId++; + } + if (totalSize == hubSize) { fMonitor.fNumErrInvalidHubSize++; } + ProcessSubSubEvent(reader, subSubEventSize, subSubEventId); + fCurrentSubSubEvent++; + } + } + + //last event ist expected to be CTS + if (totalSize != hubSize || !isLast) { fMonitor.fNumErrInvalidHubSize++; } + subSubEventSize = ProcessCtsHeader(reader, subSubEventSize, subSubEventId); + ProcessSubSubEvent(reader, subSubEventSize, subSubEventId); + + // read last words + int lastWordsCounter = 0; + while (true) { + lastWordsCounter++; + word = reader.NextWord(); + if (word == 0x600dda7a) { + if (reader.IsNextPadding()) word = reader.NextWord(); + break; + } + if (lastWordsCounter >= 7) { fMonitor.fNumErrExcessLastWords++; } + } + } + + int UnpackRich::ProcessCtsHeader(RichMicrosliceReader& reader, uint32_t subSubEventSize, uint32_t subSubEventId) + { + const uint32_t word = reader.NextWord(); + const uint32_t ctsState = word & 0xffff; // 16 bits + const uint32_t nofInputs = (word >> 16) & 0xf; // 4 bits + const uint32_t nofTrigCh = (word >> 20) & 0x1f; // 5 bits + const uint32_t inclLastIdle = (word >> 25) & 0x1; // 1 bit + const uint32_t inclTrigInfo = (word >> 26) & 0x1; // 1 bit + const uint32_t inclTime = (word >> 27) & 0x1; // 1 bit + const uint32_t ETM = (word >> 28) & 0x3; // 2 bits + uint32_t ctsInfoSize = 2 * nofInputs + 2 * nofTrigCh + 2 * inclLastIdle + 3 * inclTrigInfo + inclTime; // in words + switch (ETM) { + case 0: break; + case 1: ctsInfoSize += 1; break; + case 2: ctsInfoSize += 4; break; + case 3: break; + } + for (uint32_t i = 0; i < ctsInfoSize; i++) { + reader.NextWord(); // do nothing? + } + const int nofTimeWords = subSubEventSize - ctsInfoSize - 1; + return nofTimeWords; + } + + void UnpackRich::ProcessSubSubEvent(RichMicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId) + { + uint32_t epoch = 0; // store last epoch obtained in sub-sub-event + + // Store last raising edge time for each channel or -1. if no time + // this array is used to match raising and falling edges + std::vector<double> raisingTime(33, -1.); + + // check if DiRICH (SubSubEvId) is masked and skip to end if so + if (CheckMaskedDiRICH(subSubEventId)) { + for (int i = 0; i < nofTimeWords; i++) { + reader.NextWord(); + } + return; + } + + // First word is expected to be of type "header" + if (GetTdcWordType(reader.NextWord()) != RichTdcWordType::Header) { fMonitor.fNumErrInvalidFirstMessage++; } + + // Second word is expected to be of type "epoch" + uint32_t word = reader.NextWord(); + if (GetTdcWordType(word) != RichTdcWordType::Epoch) { fMonitor.fNumErrInvalidSecondMessage++; } + else { + epoch = ProcessEpoch(word); + } + + // Loop over words + for (int i = 2; i < nofTimeWords - 1; i++) { + word = reader.NextWord(); + switch (GetTdcWordType(word)) { + case RichTdcWordType::TimeData: { + ProcessTimeDataWord(epoch, word, subSubEventId, raisingTime); + break; + } + case RichTdcWordType::Epoch: { + epoch = ProcessEpoch(word); + break; + } + case RichTdcWordType::Header: { + fMonitor.fNumErrWildHeaderMessage++; + break; + } + case RichTdcWordType::Trailer: { + fMonitor.fNumErrWildTrailerMessage++; + break; + } + case RichTdcWordType::Debug: { + break; + // for the moment do nothing + fMonitor.fNumDebugMessage++; + break; + } + case RichTdcWordType::Error: { + fMonitor.fNumErrTdcErrorWord++; + break; + } + } + } + + // Last word is expected to be of type "trailer" + if (GetTdcWordType(reader.NextWord()) != RichTdcWordType::Trailer) { fMonitor.fNumErrInvalidLastMessage++; } + } + + // ---- ProcessTimeDataWord ---- + void UnpackRich::ProcessTimeDataWord(uint32_t epoch, uint32_t tdcWord, uint32_t subSubEventId, + std::vector<double>& raisingTime) + { + const RichTdcTimeData td = ProcessTimeData(tdcWord); + const double fullTime = CalculateTime(epoch, td.fCoarse, td.fFine); + + if (td.fChannel != 0) { + const double dT = fullTime - fPrevLastCh0ReTime[fCurrentSubSubEvent]; + const double subtrigOffset = (fCbmTimePacket - fCbmTimeMS) * 25.0; // offset of SubTrigger to MS start in ns + const double fullTimeCorr = dT - fMbsCorr + subtrigOffset; + + if (td.fChannel < 1 || td.fChannel >= raisingTime.size()) { fMonitor.fNumErrChannelOutOfBounds++; } + if (td.fIsRisingEdge) { + // always store the latest raising edge. It means that in case RRFF situation only middle RF will be matched. + raisingTime[td.fChannel] = fullTimeCorr; + } + else { + if (raisingTime[td.fChannel] != -1.) { + // Matching was found, calculate ToT, if tot is in a good range -> create digi + const double ToT = fullTimeCorr - raisingTime[td.fChannel]; + if (ToT >= fToTMin && ToT <= fToTMax) { + if (fullTimeCorr >= 0.0) { WriteOutputDigi(subSubEventId, td.fChannel, raisingTime[td.fChannel], ToT); } + } + // pair was created, set raising edge to -1. + raisingTime[td.fChannel] = -1.; + } + } + } + } + + double UnpackRich::CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine) + { + return ((double) epoch) * 2048. * 5. + ((double) coarse) * 5. - ((double) fine) * 0.005; + } + + void UnpackRich::WriteOutputDigi(int32_t fpgaID, int32_t channel, double time, double tot) + { + double ToTcorr = fbDoToTCorr ? fParams.fElinkParams[fpgaID].fToTshift[channel] : 0.; + int32_t pixelUID = GetPixelUID(fpgaID, channel); + //check ordering + double finalTime = time + (double) fMsRefTime - fSystemTimeOffset; + + // Do not accept digis, where the MS und TS differs by more than 6 sec (mainly TS0) + if (6e9 < finalTime) return; + + fOutputVec.emplace_back(pixelUID, finalTime, tot - ToTcorr); + } + + bool UnpackRich::CheckMaskedDiRICH(int32_t subSubEventId) + { + for (unsigned int i = 0; i < fMaskedDiRICHes.size(); ++i) { + if (fMaskedDiRICHes.at(i) == subSubEventId) return true; + } + return false; + } + + RichTdcWordType UnpackRich::GetTdcWordType(uint32_t tdcWord) + { + uint32_t tdcTimeDataMarker = (tdcWord >> 31) & 0x1; // 1 bit + uint32_t tdcMarker = (tdcWord >> 29) & 0x7; // 3 bits + + if (tdcTimeDataMarker == 0x1) { + // TODO: I also include tdcMarker == 0x5, some tdc time data words have this marker. Is it correct? + if (tdcMarker == 0x4 || tdcMarker == 0x5) { return RichTdcWordType::TimeData; } + else { + return RichTdcWordType::Error; + } + } + if (tdcMarker == 0x0) return RichTdcWordType::Trailer; + if (tdcMarker == 0x1) return RichTdcWordType::Header; + if (tdcMarker == 0x2) return RichTdcWordType::Debug; + if (tdcMarker == 0x3) return RichTdcWordType::Epoch; + return RichTdcWordType::Error; + } + + int32_t UnpackRich::GetPixelUID(int32_t fpgaID, int32_t ch) + { + // First 16 bits are used for the FPGA ID, then + // 8 bits unused and then 8 bits are used for the channel + return ((fpgaID << 16) | (ch & 0x00FF)); + } + + RichTdcTimeData UnpackRich::ProcessTimeData(uint32_t tdcWord) + { + RichTdcTimeData out; + out.fCoarse = static_cast<uint32_t>(tdcWord & 0x7ff); // 11 bits + out.fIsRisingEdge = static_cast<uint32_t>((tdcWord >> 11) & 0x1); // 1 bit + out.fFine = static_cast<uint32_t>((tdcWord >> 12) & 0x3ff); // 10 bits + out.fChannel = static_cast<uint32_t>((tdcWord >> 22) & 0x7f); // 7 bits + return out; + } + + uint32_t UnpackRich::ProcessEpoch(uint32_t tdcWord) { return static_cast<uint32_t>(tdcWord & 0xfffffff); } + + uint16_t UnpackRich::ProcessHeader(uint32_t tdcWord) + { + return static_cast<uint16_t>(tdcWord & 0xff); //8 bits + } + + uint16_t UnpackRich::ProcessTrailer(uint32_t tdcWord) { return static_cast<uint16_t>(tdcWord & 0xffff); } + +} /* namespace cbm::algo */ diff --git a/algo/detectors/rich/UnpackRich.h b/algo/detectors/rich/UnpackRich.h new file mode 100644 index 0000000000..8987e926f3 --- /dev/null +++ b/algo/detectors/rich/UnpackRich.h @@ -0,0 +1,250 @@ +/* Copyright (C) 2021 Goethe-University Frankfurt, Frankfurt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pascal Raisig, Dominik Smith [committer] */ + +#ifndef UnpackRich_H +#define UnpackRich_H + +#include "CbmRichDigi.h" + +#include "Timeslice.hpp" + +#include <cstddef> +#include <cstdint> +#include <iomanip> +#include <memory> +#include <sstream> +#include <utility> + +namespace cbm::algo +{ + class RichMicrosliceReader; + + enum class RichTdcWordType + { + TimeData, + Header, + Epoch, + Trailer, + Debug, + Error + }; + + + struct RichTdcTimeData { + uint32_t fCoarse = 0; // 11 bits + uint32_t fIsRisingEdge = 0; // 1 bit + uint32_t fFine = 0; // 10 bits + uint32_t fChannel = 0; // 7 bits + }; + + + /** @struct UnpackRichElinkPar + ** @author Dominik Smith <d.smith@gsi.de> + ** @since 26 May 2023 + ** @brief RICH Unpacking parameters for one eLink / ASIC + **/ + struct UnpackRichElinkPar { + std::vector<double> fToTshift; ///< TOT shift for different channels + }; + + + /** @struct UnpackRichPar + ** @author Dominik Smith <d.smith@gsi.de> + ** @since 26 May 2023 + ** @brief Parameters required for the RICH unpacking (specific to one component) + **/ + struct UnpackRichPar { + std::map<uint32_t, UnpackRichElinkPar> fElinkParams = {}; ///< Map TRB address to elink params + }; + + + /** @struct UnpackRichMoni + ** @author Dominik Smith <d.smith@gsi.de> + ** @since 26 May 2023 + ** @brief Monitoring data for RICH unpacking + **/ + struct UnpackRichMonitorData { + uint32_t fNumDebugMessage = 0; ///< Received debug messages + uint32_t fNumErrInvalidFirstMessage = 0; ///< First message is not HEADER + uint32_t fNumErrInvalidSecondMessage = 0; ///< Second message is not EPOCH + uint32_t fNumErrInvalidLastMessage = 0; ///< Last message is not TRAILER + uint32_t fNumErrWildHeaderMessage = 0; ///< TDC header in invalid position + uint32_t fNumErrWildTrailerMessage = 0; ///< TDC trailer in invalid position + uint32_t fNumErrTdcErrorWord = 0; ///< TDC word of error type + uint32_t fNumErrChannelOutOfBounds = 0; ///< TDC channel out of bounds + uint32_t fNumErrInvalidHubId = 0; ///< "SubSubEvent" has invalid ID + uint32_t fNumErrInvalidHubSize = 0; ///< Premature end of hub block + uint32_t fNumErrExcessLastWords = 0; ///< More than exprected trailing words + + bool HasErrors() + { + uint32_t numErrors = fNumDebugMessage + fNumErrInvalidFirstMessage + fNumErrInvalidSecondMessage + + fNumErrInvalidLastMessage + fNumErrWildHeaderMessage + fNumErrWildTrailerMessage + + fNumErrTdcErrorWord + fNumErrChannelOutOfBounds + fNumErrInvalidHubId + + fNumErrInvalidHubSize + fNumErrExcessLastWords; + return (numErrors > 0 ? true : false); + } + std::string print() + { + std::stringstream ss; + ss << "errors " << fNumDebugMessage << " | " << fNumErrInvalidFirstMessage << " | " << fNumErrInvalidSecondMessage + << " | " << fNumErrInvalidLastMessage << " | " << fNumErrWildHeaderMessage << " | " + << fNumErrWildTrailerMessage << " | " << fNumErrTdcErrorWord << " | " << fNumErrChannelOutOfBounds << " | " + << fNumErrInvalidHubId << " | " << fNumErrInvalidHubSize << " | " << fNumErrExcessLastWords << " | "; + return ss.str(); + } + }; + + + class UnpackRich { + public: + typedef std::pair<std::vector<CbmRichDigi>, UnpackRichMonitorData> resultType; + + + /** @brief Default constructor **/ + UnpackRich() {}; + + + /** @brief Destructor **/ + ~UnpackRich() {}; + + + /** @brief Algorithm execution + ** @param msContent Microslice payload + ** @param msDescr Microslice descriptor + ** @param tTimeslice Unix start time of timeslice [ns] + ** @return RICH digi data + **/ + resultType operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr, + const uint64_t tTimeslice); + + /** @brief Set the parameter container + ** @param params Pointer to parameter container + **/ + void SetParams(std::unique_ptr<UnpackRichPar> params) { fParams = *(std::move(params)); } + + private: + void ProcessTrbPacket(RichMicrosliceReader& reader); + + void ProcessHubBlock(RichMicrosliceReader& reader); + + int ProcessCtsHeader(RichMicrosliceReader& reader, uint32_t subSubEventSize, uint32_t subSubEventId); + + void ProcessSubSubEvent(RichMicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId); + + void ProcessTimeDataWord(uint32_t epoch, uint32_t tdcWord, uint32_t subSubEventId, + std::vector<double>& raisingTime); + + RichTdcWordType GetTdcWordType(uint32_t tdcWord); + + RichTdcTimeData ProcessTimeData(uint32_t tdcWord); + + uint32_t ProcessEpoch(uint32_t tdcWord); + + uint16_t ProcessHeader(uint32_t tdcWord); + + uint16_t ProcessTrailer(uint32_t tdcWord); + + void WriteOutputDigi(int32_t fpgaID, int32_t channel, double time, double tot); + + double CalculateTime(uint32_t epoch, uint32_t coarse, uint32_t fine); + + int32_t GetPixelUID(int32_t fpgaID, int32_t ch); + + bool CheckMaskedDiRICH(int32_t subSubEventId); + + private: + UnpackRichPar fParams = {}; ///< Parameter container + + std::vector<int32_t> fMaskedDiRICHes; + + bool fbDoToTCorr = true; //activates ToT correction from parameter file + + uint64_t fCbmTimeMS; + uint64_t fCbmTimePacket; + + double fMbsCorr = 0.; + double fPrevLastCh0ReTime[13]; // 12 DiRICHes chnl0 + 1 CTS chnl0 + uint16_t fCurrentSubSubEvent = 0; + + uint64_t fMsRefTime = 0; + + double fToTMin = -20.; + double fToTMax = 100.; + + /** @brief Default return vector for Unpack function. */ + std::vector<CbmRichDigi> fOutputVec = {}; + + /** @brief Storage of monitoring data. */ + UnpackRichMonitorData fMonitor; + + /** + * @brief Time offset for the system + * @todo This should be module and channel dependent and included into the asic parameters + */ + std::int32_t fSystemTimeOffset = 0; + }; + + + class RichMicrosliceReader { + private: + const uint8_t* fData = nullptr; + size_t fSize = 0; + size_t fOffset = 0; // offset in bytes + size_t fWordCounter = 0; + uint32_t fCurWord = 0; + + public: + void SetData(const uint8_t* data, size_t size) + { + fData = data; + fSize = size; + fOffset = 0; + fWordCounter = 0; + fCurWord = 0; + } + + const uint8_t* GetData() { return fData; } + size_t GetSize() { return fSize; } + size_t GetOffset() { return fOffset; } + size_t GetWordCounter() { return fWordCounter; } + uint32_t GetCurWord() { return fCurWord; } + + std::string GetWordAsHexString(uint32_t word) + { + std::stringstream stream; + stream << "0x" << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex << word; + return stream.str(); + } + + uint32_t NextWord() + { + uint32_t i = ((uint32_t*) (fData + fOffset))[0]; + //swap bytes + i = (i >> 24) | ((i << 8) & 0x00FF0000) | ((i >> 8) & 0x0000FF00) | (i << 24); + fOffset += 4; + fWordCounter++; + fCurWord = i; + return i; + } + + bool IsNextPadding() + { + uint32_t nextWord = ((uint32_t*) (fData + fOffset))[0]; + if (nextWord == 0xffffffff) return true; + return false; + } + + bool IsLastSubSubEvent(uint32_t subSubEventSize) + { + uint32_t i = ((uint32_t*) (fData + fOffset + 4 * subSubEventSize))[0]; + i = (i >> 24) | ((i << 8) & 0x00ff0000) | ((i >> 8) & 0x0000ff00) | (i << 24); + if (i == 0x00015555) return true; + return false; + } + }; + +} /* namespace cbm::algo */ + +#endif // UnpackRich_H diff --git a/algo/unpack/Unpack.cxx b/algo/unpack/Unpack.cxx index db3a356ac7..bab391dcf8 100644 --- a/algo/unpack/Unpack.cxx +++ b/algo/unpack/Unpack.cxx @@ -57,6 +57,9 @@ namespace cbm::algo if (systemId == fles::SubsystemIdentifier::TRD2D) { MsLoop(timeslice, fAlgoTrd2d, comp, equipmentId, &digiTs.fData.fTrd2d.fDigis, monitor, &monitor.fTrd2d, 0x02); } + if (systemId == fles::SubsystemIdentifier::RICH) { + MsLoop(timeslice, fAlgoRich, comp, equipmentId, &digiTs.fData.fRich.fDigis, monitor, &monitor.fRich, 0x03); + } } //# component // --- Sorting of output digis. Is required by both digi trigger and event builder. @@ -73,6 +76,8 @@ namespace cbm::algo [](CbmTrdDigi digi1, CbmTrdDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); std::sort(std::execution::par_unseq, digiTs.fData.fTrd2d.fDigis.begin(), digiTs.fData.fTrd2d.fDigis.end(), [](CbmTrdDigi digi1, CbmTrdDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); + std::sort(std::execution::par_unseq, digiTs.fData.fRich.fDigis.begin(), digiTs.fData.fRich.fDigis.end(), + [](CbmRichDigi digi1, CbmRichDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); #else std::sort(digiTs.fData.fSts.fDigis.begin(), digiTs.fData.fSts.fDigis.end(), [](CbmStsDigi digi1, CbmStsDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); @@ -86,6 +91,8 @@ namespace cbm::algo [](CbmTrdDigi digi1, CbmTrdDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); std::sort(digiTs.fData.fTrd2d.fDigis.begin(), digiTs.fData.fTrd2d.fDigis.end(), [](CbmTrdDigi digi1, CbmTrdDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); + std::sort(digiTs.fData.fRich.fDigis.begin(), digiTs.fData.fRich.fDigis.end(), + [](CbmRichDigi digi1, CbmRichDigi digi2) { return digi1.GetTime() < digi2.GetTime(); }); #endif return result; } @@ -213,6 +220,19 @@ namespace cbm::algo L_(info) << "--- Configured equipment " << equip << " with " << numElinks << " elinks"; } + // Create one algorithm per component and configure it with parameters + auto equipIdsRich = fRichConfig.GetEquipmentIds(); + for (auto& equip : equipIdsRich) { + std::unique_ptr<UnpackRichPar> par(new UnpackRichPar()); + std::map<uint32_t, std::vector<double>> compMap = fRichConfig.Map(equip); + for (auto const& val : compMap) { + uint32_t address = val.first; + par->fElinkParams[address].fToTshift = val.second; + } + fAlgoRich[equip].SetParams(std::move(par)); + L_(info) << "--- Configured equipment " << equip << " with " << fRichConfig.GetNumElinks(equip) << " elinks"; + } + // Create one algorithm per component for TRD and configure it with parameters auto equipIdsTrd = fTrdConfig.GetEquipmentIds(); for (auto& equip : equipIdsTrd) { @@ -268,6 +288,8 @@ namespace cbm::algo L_(info) << "--- Configured " << fAlgoSts.size() << " unpacker algorithms for STS."; L_(debug) << "Readout map:" << fStsConfig.PrintReadoutMap(); L_(info) << "--- Configured " << fAlgoMuch.size() << " unpacker algorithms for MUCH."; + L_(info) << "--- Configured " << fAlgoRich.size() << " unpacker algorithms for RICH."; + L_(debug) << "Readout map:" << fRichConfig.PrintReadoutMap(); L_(info) << "--- Configured " << fAlgoTof.size() << " unpacker algorithms for TOF."; L_(info) << "--- Configured " << fAlgoTrd.size() << " unpacker algorithms for TRD."; L_(info) << "--- Configured " << fAlgoTrd2d.size() << " unpacker algorithms for TRD2D."; diff --git a/algo/unpack/Unpack.h b/algo/unpack/Unpack.h index 5a0d6dbed4..57d72cb8d2 100644 --- a/algo/unpack/Unpack.h +++ b/algo/unpack/Unpack.h @@ -22,6 +22,8 @@ #include "bmon/UnpackBmon.h" #include "much/MuchReadoutConfig.h" #include "much/UnpackMuch.h" +#include "rich/RichReadoutConfig.h" +#include "rich/UnpackRich.h" #include "sts/StsReadoutConfigLegacy.h" #include "sts/UnpackSts.h" @@ -40,6 +42,7 @@ namespace cbm::algo std::vector<UnpackBmonMonitorData> fBmon; ///< Monitoring data for T0 std::vector<UnpackTrdMonitorData> fTrd; ///< Monitoring data for TRD std::vector<UnpackTrd2dMonitorData> fTrd2d; ///< Monitoring data for TRD2D + std::vector<UnpackRichMonitorData> fRich; ///< Monitoring data for RICH size_t fNumMs = 0; size_t fNumBytes = 0; size_t fNumDigis = 0; @@ -94,6 +97,9 @@ namespace cbm::algo /** @brief Parameters for TRD2D unpackers **/ Trd2dReadoutConfig fTrd2dConfig {}; + /** @brief Parameters for RICH unpackers **/ + RichReadoutConfig fRichConfig {}; + /** @brief Initialize unpackers and fill parameters from config objects **/ bool Init(); @@ -123,6 +129,9 @@ namespace cbm::algo /** @brief TRD2D unpackers **/ std::map<uint16_t, UnpackTrd2d> fAlgoTrd2d = {}; + + /** @brief RICH unpackers **/ + std::map<uint16_t, UnpackRich> fAlgoRich = {}; }; } // namespace cbm::algo -- GitLab