Select Git revision
Felix Weiglhofer authored
Unpack.h 5.28 KiB
/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Pascal Raisig, Alexandru Bercuci, Dominik Smith [committer] */
#ifndef CBM_ALGO_TRD2D_UNPACK_H
#define CBM_ALGO_TRD2D_UNPACK_H 1
#include "CbmTrdDigi.h"
#include "CbmTrdRawMessageSpadic.h"
#include "MicrosliceDescriptor.hpp"
#include "Timeslice.hpp"
#include <array>
#include <cmath>
#include <memory>
#include <sstream>
#define NFASPMOD 180
#define NCROBMOD 5
#define NFASPCROB NFASPMOD / NCROBMOD
#define NFASPCH 16
#define FASP_EPOCH_LENGTH 128
namespace cbm::algo::trd2d
{
enum FaspMessageType
{
kEpoch = 0,
kData
};
/** @brief Data structure for unpacking the FASP word */
struct FaspMessage {
FaspMessage(uint8_t c, uint8_t typ, uint8_t t, uint16_t d, uint8_t rob, uint8_t asic);
uint8_t ch = 0; ///< ch id in the FASP
uint8_t type = 0; ///< message type 0 = epoch, 1 = data (not used for the moment)
uint8_t tlab = 0; ///< time of the digi inside the epoch
uint16_t data = 0; ///< ADC value
uint32_t epoch = 0; ///< epoch id (not used for the moment)
uint32_t mod = 0; ///< full module address according to CbmTrdAddress
uint8_t crob = 0; ///< CROB id in the module
uint8_t fasp = 0; ///< FASP id in the module
};
/** @struct UnpackChannelPar
** @author Dominik Smith <d.smith@gsi.de>
** @since 31 January 2023
** @brief TRD Unpacking parameters for one Asic channel
**/
struct UnpackChannelPar {
int32_t fPadAddress; ///< Pad address for channel
bool fMask; ///< Flag for channel masking
uint64_t fDaqOffset = 0; ///< Time calibration parameter
};
/** @struct UnpackAsicPar
** @author Dominik Smith <d.smith@gsi.de>
** @since 31 January 2023
** @brief TRD Unpacking parameters for one Asic
**/
struct UnpackAsicPar {
std::vector<UnpackChannelPar> fChanParams; ///< Parameters for different channels
};
/** @struct UnpackPar
** @author Dominik Smith <d.smith@gsi.de>
** @since 31 January 2023 ** @brief Parameters required for the TRD unpacking (specific to one component)
**/
struct UnpackPar {
int32_t fSystemTimeOffset = 0; ///< Time calibration parameter
uint16_t fModId = 0; ///< Module ID of component
uint8_t fCrobId = 0; ///< CROB ID of component
std::vector<UnpackAsicPar> fAsicParams = {}; ///< Parameters for each ASIC
};
/** @struct UnpackMoni
** @author Dominik Smith <d.smith@gsi.de>
** @since 31 January 2023
** @brief Monitoring data for TRD unpacking
**/
struct UnpackMonitorData {
uint32_t fNumSelfTriggeredData = 0; ///< word fulfills data & 0x2000
uint32_t fNumIncompleteDigis = 0; ///< incomplete digis left in pads after finalization
uint32_t fNumErrEndBitSet = 0; ///< Corrupted data with end bit set
bool HasErrors()
{
uint32_t numErrors = fNumErrEndBitSet;
return (numErrors > 0 ? true : false);
}
std::string print()
{
std::stringstream ss;
ss << "stats " << fNumSelfTriggeredData << " | " << fNumIncompleteDigis << " | errors " << fNumErrEndBitSet
<< " | ";
return ss.str();
}
};
/** @class Unpack
** @author Dominik Smith <d.smith@gsi.de>
** @since 31 January 2023
** @brief Unpack algorithm for TRD
**/
class Unpack {
public:
typedef std::pair<std::vector<CbmTrdDigi>, UnpackMonitorData> resultType;
/** @brief Default constructor **/
Unpack(){};
/** @brief Destructor **/
~Unpack(){};
/** @brief Algorithm execution
** @param msContent Microslice payload
** @param msDescr Microslice descriptor
** @param tTimeslice Unix start time of timeslice [ns]
** @return TRD digi data
**/
resultType operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
const uint64_t tTimeslice) const;
/** @brief Set the parameter container
** @param params Pointer to parameter container
**/
void SetParams(std::unique_ptr<UnpackPar> params) { fParams = *(std::move(params)); }
private: // Types
struct MsContext {
UnpackMonitorData fMonitor; ///< Container for monitoring data
std::array<std::vector<CbmTrdDigi>, NFASPMOD* NFASPCH> fDigiBuffer = {
{}}; ///> Buffered digi for each pad in CROB component
};
private: // members
UnpackPar fParams = {}; ///< Parameter container
bool pushDigis(std::vector<FaspMessage> messages, const uint64_t time, MsContext& ctx) const;
/** @brief Finalize component (e.g. copy from temp buffers) */
std::vector<CbmTrdDigi> FinalizeComponent(MsContext& ctx) const;
// Constants
/** @brief Bytes per FASP frame stored in the microslices (32 bits words)
* - DATA WORD -
* ffff.ffdd dddd.dddd dddd.tttt ttta.cccc
* f - FASP id
* d - ADC signal
* t - time label inside epoch
* a - word type (1)
* c - channel id
* - EPOCH WORD -
* ffff.fftt tttt.tttt tttt.tttt ttta.cccc
* f - FASP id
* t - epoch index
* a - word type (0)
* c - channel id
*/
static const std::uint8_t fBytesPerWord = 4;
};
} // namespace cbm::algo::trd2d
#endif /* CBM_ALGO_TRD2D_UNPACK_H */