14#include <fairlogger/Logger.h>
30 mRawWriter->setCarryOverCallBack(
this);
33 if (!mMappingHandler) {
34 mMappingHandler = std::make_unique<o2::emcal::MappingHandler>();
37 for (
auto iddl = 0; iddl < 40; iddl++) {
47 mSRUdata.push_back(srucont);
51 if (iddl == 21 || iddl == 22 || iddl == 36 || iddl == 39) {
56 auto flpID = (iddl <= 23) ? 146 : 147;
57 std::string rawfilename = mOutputLocation;
60 rawfilename +=
"/emcal.raw";
63 rawfilename += fmt::format(
"/EMC_alio2-cr1-flp{:d}.raw", flpID);
66 rawfilename += fmt::format(
"/EMC_alio2-cr1-flp{:d}_crorc{:d}.raw", flpID, crorc);
70 rawfilename += fmt::format(
"/EMC_alio2-cr1-flp{:d}_crorc{:d}_{:d}.raw", flpID, crorc, link);
73 mRawWriter->registerLink(iddl, crorc, link, 0, rawfilename.data());
77void RawWriter::digitsToRaw(gsl::span<o2::emcal::Digit> digitsbranch, gsl::span<o2::emcal::TriggerRecord> triggerbranch)
80 for (
auto trg : triggerbranch) {
87 for (
auto& srucont : mSRUdata) {
88 srucont.mChannels.clear();
90 std::vector<o2::emcal::Digit*>* bunchDigits;
93 auto tower = dig.getTower();
94 if (tower != lasttower) {
97 std::cout <<
"Wrong cell ID " << tower << std::endl;
100 int sruID = std::get<0>(onlineindices);
101 auto towerdata = mSRUdata[sruID].mChannels.find(tower);
102 if (towerdata == mSRUdata[sruID].mChannels.end()) {
103 mSRUdata[sruID].mChannels[tower] = {std::get<1>(onlineindices), std::get<2>(onlineindices), std::vector<o2::emcal::Digit*>(mNADCSamples)};
104 bunchDigits = &(mSRUdata[sruID].mChannels[tower].mDigits);
107 bunchDigits = &(towerdata->second.mDigits);
114 auto timesample =
int(dig.getTimeStamp() / emcal::constants::EMCAL_TIMESAMPLE);
115 if (timesample >= mNADCSamples) {
116 LOG(error) <<
"Digit time sample " << timesample <<
" outside range [0," << mNADCSamples <<
"]";
119 (*bunchDigits)[timesample] = &dig;
124 for (
auto srucont : mSRUdata) {
126 std::vector<char> payload;
128 if (srucont.mSRUid == 21 || srucont.mSRUid == 22 || srucont.mSRUid == 36 || srucont.mSRUid == 39) {
135 std::map<int, std::map<int, int>> fecSortedTowersWithSignal;
136 auto& mappingDDL = mMappingHandler->getMappingForDDL(srucont.mSRUid);
137 for (
const auto& [tower, channel] : srucont.mChannels) {
142 auto fecFound = fecSortedTowersWithSignal.find(fecInDLL);
143 if (fecFound != fecSortedTowersWithSignal.end()) {
146 std::map<int, int> channelsInFec;
148 fecSortedTowersWithSignal[fecInDLL] = channelsInFec;
153 for (
const auto& [fec, channelsInFec] : fecSortedTowersWithSignal) {
154 for (
auto [
channelID, tower] : channelsInFec) {
155 auto towerChannel = srucont.mChannels.find(tower);
156 if (towerChannel != srucont.mChannels.end()) {
157 bool saturatedBunchHG =
false;
159 if (saturatedBunchHG) {
163 LOG(error) <<
"No data found for FEC " << fec <<
", channel " <<
channelID <<
"(tower " << tower <<
")";
168 if (!payload.size()) {
171 LOG(
debug) <<
"Payload buffer has size 0 - only write empty trailer" << std::endl;
173 LOG(
debug) <<
"Payload buffer has size " << payload.size();
177 for (
auto word : trailerwords) {
178 payload.emplace_back(word);
182 auto ddlid = srucont.mSRUid;
184 LOG(debug1) <<
"Adding payload with size " << payload.size() <<
" (" << payload.size() / 4 <<
" ALTRO words)";
194 auto hwaddress = mMappingHandler->getMappingForDDL(ddlID).getHardwareAddress(channel.
mRow, channel.
mCol, chanType);
196 std::vector<int> rawbunches;
201 if (!bunch.mADCs.size()) {
202 LOG(error) <<
"Found bunch with without ADC entries - skipping ...";
205 rawbunches.push_back(bunch.mADCs.size() + 2);
206 rawbunches.push_back(bunch.mStarttime);
207 for (
auto adc : bunch.mADCs) {
208 rawbunches.push_back(
adc);
209 if (
adc > o2::emcal::constants::LG_SUPPRESSION_CUT) {
210 saturatedBunch =
true;
216 if (!rawbunches.size()) {
220 LOG(
debug) <<
"Selected " << nbunches <<
" bunches";
224 char* chanheadwords =
reinterpret_cast<char*
>(&chanhead);
225 uint32_t* testheader =
reinterpret_cast<uint32_t*
>(chanheadwords);
226 if ((*testheader >> 30) & 1) {
228 uint32_t payloadsizeRead = ((*testheader >> 16) & 0x3FF);
229 uint32_t nwordsRead = (payloadsizeRead + 2) / 3;
230 if (encodedbunches.size() != nwordsRead) {
231 LOG(error) <<
"Mismatch in number of 32-bit words, encoded " << encodedbunches.size() <<
", recalculated " << nwordsRead << std::endl;
232 LOG(error) <<
"Payload size: " << payloadsizeRead <<
", number of words: " << rawbunches.size() <<
", encodeed words " << encodedbunches.size() <<
", calculated words " << nwordsRead << std::endl;
234 LOG(
debug) <<
"Matching number of payload 32-bit words, encoded " << encodedbunches.size() <<
", decoded " << nwordsRead;
237 LOG(error) <<
"Header without header bit detected ..." << std::endl;
239 for (
int iword = 0; iword <
sizeof(
ChannelHeader) /
sizeof(
char); iword++) {
240 payload.emplace_back(chanheadwords[iword]);
242 char* channelwords =
reinterpret_cast<char*
>(encodedbunches.data());
243 for (
auto iword = 0; iword < encodedbunches.size() *
sizeof(
int) /
sizeof(
char); iword++) {
244 payload.emplace_back(channelwords[iword]);
250 std::vector<AltroBunch>
result;
252 bool bunchStarted =
false;
255 for (itime = channelDigits.size() - 1; itime >= 0; itime--) {
256 auto dig = channelDigits[itime];
261 if (currentBunch.
mADCs.size() >= mMinADCBunch) {
263 result.push_back(currentBunch);
265 bunchStarted =
false;
270 int adc = dig->getAmplitudeADC(channelType);
271 if (
adc < mPedestal) {
277 if (currentBunch.
mADCs.size() >= mMinADCBunch) {
279 result.push_back(currentBunch);
281 bunchStarted =
false;
290 currentBunch.
mADCs.emplace_back(
adc);
294 if (currentBunch.
mADCs.size() >= mMinADCBunch) {
295 result.push_back(currentBunch);
303 std::vector<int> encoded;
309 LOG(error) <<
"Exceeding max ADC count for 10 bit ALTRO word: " <<
adc <<
" (max: 1023)" << std::endl;
311 switch (wordnumber) {
323 if (wordnumber == 3) {
325 encoded.push_back(currentword.
mDataWord);
331 encoded.push_back(currentword.
mDataWord);
373 auto trailerwords = trailer.
encode();
374 std::vector<char> encoded(trailerwords.size() *
sizeof(uint32_t));
375 memcpy(encoded.data(), trailerwords.data(), trailerwords.size() *
sizeof(uint32_t));
380 const char*
ptr,
int maxSize,
int splitID,
381 std::vector<char>& trailer, std::vector<char>& header)
const
383 constexpr int TrailerSize = 9 *
sizeof(uint32_t);
385 int leftAfterSplit = bytesLeft - maxSize;
387 if (leftAfterSplit < TrailerSize) {
388 return std::max(0, bytesLeft - TrailerSize);
static const TriggerOffsetsParam & Instance()
EMCAL digit implementation.
std::tuple< int, int, int > getOnlineID(int towerID)
Get link ID, row and column from cell ID, have a look here: https://alice.its.cern....
std::tuple< int, int > getLinkAssignment(int ddlID) const
Temporary link assignment (till final link assignment is known -.
Information stored in the RCU trailer.
void setNumberOfNonZeroSuppressedPostsamples(uint16_t npostsamples)
Set the number of postsamples before zero suppression.
void setPayloadSize(uint32_t size)
set the payload size in number of DDL (32-bit) words
void setTimeSamplePhaseNS(uint64_t triggertime, uint64_t timesample)
Set the time sample length and L1 phase based on the trigger time.
void setNumberOfNonZeroSuppressedPresamples(uint16_t npresamples)
Set the number of presamples after zero suppression.
void setSparseReadout(bool isSparse)
Set sparse readout mode.
@ NBUFFERS4
4 ALTRO buffers
void setNumberOfAltroBuffers(BufferMode_t bufmode)
Set the number of ALTRO buffers.
void setNumberOfPretriggerSamples(uint16_t nsamples)
Set the number of pretrigger samples.
void setBaselineCorrection(uint16_t baselineCorrection)
Set baseline correction method.
void setSecondBaselineCorrection(bool doHave)
Specify whether second basedline correction has been applied.
void setGlitchFilter(uint16_t glitchfilter)
Set the glitch filter.
void setActiveFECsA(uint16_t value)
void setActiveFECsB(uint16_t value)
void setZeroSuppression(bool doHave)
Specify whether zero suppression has been applied.
void setFirmwareVersion(uint8_t version)
Set the firmware version.
std::vector< uint32_t > encode() const
Encode RCU trailer as array of DDL (32-bit) words.
void setNumberOfSamplesPerChannel(uint16_t nsamples)
Set the number of samples per channel.
void setRCUID(int rcuid)
Set the ID of the RCU.
void setPolarity(bool doSet)
Set the polarity.
void setNumberOfPostsamples(uint16_t npostsamples)
Set the number of postsamples (after zero suppression)
void setNumberOfPresamples(uint16_t npresamples)
Set the number of presamples (after zero suppression)
std::vector< char > createRCUTrailer(int payloadsize, double timesample, uint64_t triggertime, int feeID)
Creating RCU trailer.
ChannelHeader createChannelHeader(int hardwareAddress, int payloadSize, bool isBadChannel)
Create channel header.
bool processTrigger(const o2::emcal::TriggerRecord &trg)
Processing digits to raw conversion for the digits from the current event.
@ kSubDet
Subdetector (EMCAL/DCAL separate)
@ kFullDet
Full detector (EMCAL + DCAL)
int getChannelIndexFromHwAddress(int hwaddress)
Extracting Channel index in FEC from the hardware address.
int getFecIndexFromHwAddress(int hwaddress)
Extracting FEC index in branch from the hardware address.
int getBranchIndexFromHwAddress(int hwaddress)
Extracting branch index from the hardware address.
std::vector< AltroBunch > findBunches(const std::vector< o2::emcal::Digit * > &channelDigits, ChannelType_t channelType)
Parse digits vector in channel and create ALTRO bunches.
void createPayload(o2::emcal::ChannelData channel, o2::emcal::ChannelType_t chanType, int ddlID, std::vector< char > &payload, bool &saturatedBunch)
int carryOverMethod(const header::RDHAny *rdh, const gsl::span< char > data, const char *ptr, int maxSize, int splitID, std::vector< char > &trailer, std::vector< char > &header) const
void setDigits(gsl::span< o2::emcal::Digit > digits)
void digitsToRaw(gsl::span< o2::emcal::Digit > digits, gsl::span< o2::emcal::TriggerRecord > triggers)
Converting digits from a full timeframe to raw pages.
std::vector< int > encodeBunchData(const std::vector< int > &data)
Encoding words of the ALTRO bunch into 32-bit words.
Header for data corresponding to the same hardware trigger.
int getFirstEntry() const
int getNumberOfObjects() const
uint32_t getTriggerBits() const
const BCData & getBCData() const
constexpr o2::header::DataOrigin gDataOriginEMC
ChannelType_t
Type of a raw data channel.
@ HIGH_GAIN
High gain channel.
@ LOW_GAIN
Low gain channel.
ALTRO bunch information obtained from digits.
std::vector< int > mADCs
ADCs belonging to the bunch.
int mStarttime
Start time of the bunch.
Structure for mapping digits to Channels within a SRU.
std::vector< o2::emcal::Digit * > mDigits
Digits for the channel within the current event.
int mRow
Row of the channel.
int mCol
Column of the channel.
Structure for organizing digits within the SRU.
int mSRUid
DDL of the SRU.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
Encoding of ALTRO words (32 bit consisting of 3 10-bit words)
uint32_t mWord2
Bits 0 - 9 : Word 2.
uint32_t mWord0
Bits 20 - 29 : Word 0.
uint32_t mDataWord
Full data word representation.
uint32_t mWord1
Bits 10 - 19 : Word 1.