15#include "TObjString.h"
27 , fbMonitorMode(kFALSE)
28 , fbDebugMonitorMode(kFALSE)
29 , fbWriteOutput(kTRUE)
30 , fbDebugWriteOutput(kFALSE)
31 , fbBaselineAvg(kFALSE)
32 , fTrdDigiVector(nullptr)
33 , fTrdRawMessageVector(nullptr)
34 , fSpadicInfoMsgVector(nullptr)
43 , fTsStopTimeCore(0.0)
49 , fNbSpadicErrorMsg(0)
51 , fNbSpadicEpochMsg(0)
52 , fParContList(nullptr)
53 , fRefGeoTag(
"trd_v20a_mcbm")
60 , fIsFirstChannelsElinkEven(false)
78 LOG(debug) <<
"Initializing CbmMcbm2018UnpackerAlgoTrdR";
95 LOG(info) <<
"Finish of CbmMcbm2018UnpackerAlgoTrdR. Unpacked \n " <<
fNbTimeslices <<
" Timeslices with \n "
104 LOG(debug) <<
"Initializing Containers of CbmMcbm2018UnpackerAlgoTrdR";
114 LOG(debug) <<
"(Re-)Initializing Containers of CbmMcbm2018UnpackerAlgoTrdR";
116 Bool_t initOk = kTRUE;
119 LOG(warning) <<
"CbmTrdParSetAsic not found";
123 LOG(warning) <<
"CbmTrdParSetDigi not found";
127 LOG(warning) <<
"CbmTrdParSetGas not found";
131 LOG(warning) <<
"CbmTrdParSetGain not found";
165 Bool_t initOk = kTRUE;
174 LOG(debug) <<
"CbmMcbm2018UnpackerAlgoTrdR - Successfully initialized "
175 "Spadic hardware address map";
186 fTsStartTime =
static_cast<Double_t
>(ts.descriptor(0, 0).idx);
194 LOG(info) <<
"CbmMcbm2018UnpackerAlgoTrdR::ProcessTs :";
196 <<
" Overlap MS, for a core duration of " <<
fdTsCoreSizeInNs <<
" ns and a full duration of "
202 LOG(info) <<
"In each TS " <<
fuNbMsLoop <<
" MS will be looped over";
206 for (UInt_t MsIndex = 0; MsIndex <
fuNbMsLoop; MsIndex++) {
211 if (kFALSE ==
ProcessMs(ts, uMsComp, MsIndex)) {
219 return a.GetTime() < b.GetTime();
223 LOG(error) <<
"Failed to process ts " <<
fCurrTsIdx <<
" MS " << MsIndex <<
" for component " << uMsComp;
239 fles::MicrosliceDescriptor msDesc = ts.descriptor(uMsCompIdx, uMsIdx);
241 uint32_t msSize = msDesc.size;
246 const uint8_t* msPointer =
reinterpret_cast<const uint8_t*
>(ts.content(uMsCompIdx, uMsIdx));
247 const uint64_t* msContent =
reinterpret_cast<const uint64_t*
>(msPointer);
250 for (uint32_t iWord = 0; iWord < msNbWords; iWord++) {
251 uint64_t curWord =
static_cast<uint64_t
>(msContent[iWord]);
261 uint8_t curSample = 3;
263 for (uint8_t iRda = 0; iRda < nRda; iRda++) {
265 curWord =
static_cast<uint64_t
>(msContent[(iWord)]);
267 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs] Incomplete Spadic "
268 "Message! RDA Word missing, Microslice corrupted.";
272 for (uint8_t j = 0; curSample < nSamples && curSample < 32 && j < 7; curSample++, j++) {
280 std::shared_ptr<CbmTrdDigi> digi =
MakeDigi(raw);
289 if (!
FillHistograms(*digi)) LOG(error) <<
"Failed to fill CbmTrdDigi histograms";
292 LOG(error) <<
"Failed to fill CbmTrdRawMessageSpadic histograms";
297 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs] Unexpected RDA "
298 "Word. Microslice corrupted.";
318 if (iWord != (msNbWords - 1))
320 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs] Null Word but "
321 "not at end of Microslice.";
325 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs] Unknown Word. "
326 "Microslice corrupted.";
332 uint64_t mask = 0x3FFFFFFF;
334 uint64_t uTS_MSB = (uint64_t)((curWord & mask) >> 32);
336 if (dt_epoch != 1) LOG(debug4) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs] dt_epoch = " << dt_epoch;
357 LOG(info) <<
"CbmMcbm2018UnpackerAlgoTrdR::AddMsComponentToList => Component " << component <<
" with detector ID 0x"
358 << std::hex << usDetectorId << std::dec <<
" added to list";
375 Bool_t createHistosOk = kTRUE;
382 return createHistosOk;
388 Bool_t createHistoOk = kFALSE;
389 TString histName =
"";
390 TH1* newHisto =
nullptr;
391 std::map<Int_t, CbmTrdParMod*> parDigiModuleMap = (std::map<Int_t, CbmTrdParMod*>)
fDigiPar->
GetModuleMap();
393 for (
auto mapIt : parDigiModuleMap) {
396 histName.Form(
"Module%d-", moduleId);
399 histName +=
"RawMessage_Signalshape_all";
400 newHisto =
new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
401 newHisto->SetXTitle(
"time [cc]");
402 newHisto->SetYTitle(
"Pulse height [ADC channels]");
405 histName +=
"RawMessage_Signalshape_St";
406 newHisto =
new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
407 newHisto->SetXTitle(
"time [cc]");
408 newHisto->SetYTitle(
"Pulse height [ADC channels]");
411 histName +=
"RawMessage_Signalshape_Nt";
412 newHisto =
new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
413 newHisto->SetXTitle(
"time [cc]");
414 newHisto->SetYTitle(
"Pulse height [ADC channels]");
417 histName +=
"RawMessage_Signalshape_filtered";
418 newHisto =
new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
421 histName +=
"RawDistributionMapModule5";
422 newHisto =
new TH2I(histName.Data(), histName.Data(), 42, -0.5, 41.5, 16, -0.5, 15.5);
425 histName +=
"RawHitTypes";
431 histName +=
"RawPulserDeltaT";
432 newHisto =
new TH1I(histName.Data(), histName.Data(), 40000, 0, 4000000);
433 newHisto->SetXTitle(
"#Delta t [cc]");
434 newHisto->SetYTitle(
"Counts");
437 histName +=
"Spadic_Info_Types";
438 newHisto =
new TH2I(histName.Data(), histName.Data(), 500000, 0, 5e9, 5, -0.5, 4.5);
439 ((TH2I*) newHisto)->SetXTitle(
"t /Clockcycles");
440 ((TH2I*) newHisto)->SetYTitle(
"messagetype");
441 ((TH2I*) newHisto)->GetYaxis()->SetBinLabel(1,
"BOM");
442 ((TH2I*) newHisto)->GetYaxis()->SetBinLabel(2,
"MSB");
443 ((TH2I*) newHisto)->GetYaxis()->SetBinLabel(3,
"BUF");
444 ((TH2I*) newHisto)->GetYaxis()->SetBinLabel(4,
"UNU");
445 ((TH2I*) newHisto)->GetYaxis()->SetBinLabel(5,
"MIS");
448 histName +=
"DigiPulserDeltaT";
449 newHisto =
new TH1I(histName.Data(), histName.Data(), 60000, 0, 6e8);
450 newHisto->SetXTitle(
"#Delta t [ns]");
451 newHisto->SetYTitle(
"Counts");
454 histName +=
"DigiDeltaT";
455 newHisto =
new TH1I(histName.Data(), histName.Data(), 6000, -10, ((6e7) - 10));
460 newHisto->SetXTitle(
"#Delta t [ns]");
461 newHisto->SetYTitle(
"Counts");
464 histName +=
"DigiMeanHitFrequency";
472 newHisto->SetXTitle(
"Pad-Channel");
473 newHisto->SetYTitle(
"Hit frequency [kHz]");
476 histName +=
"DigiDistributionMap";
477 newHisto =
new TH2I(histName.Data(), histName.Data(), parDigiModule->
GetNofColumns(), -0.5,
481 newHisto->SetXTitle(
"Pad column");
482 newHisto->SetYTitle(
"Pad row");
485 histName +=
"DigiDistributionMapSt";
486 newHisto =
new TH2I(histName.Data(), histName.Data(), parDigiModule->
GetNofColumns(), -0.5,
490 newHisto->SetXTitle(
"Pad column");
491 newHisto->SetYTitle(
"Pad row");
494 histName +=
"DigiDistributionMapNt";
495 newHisto =
new TH2I(histName.Data(), histName.Data(), parDigiModule->
GetNofColumns(), -0.5,
499 newHisto->SetXTitle(
"Pad column");
500 newHisto->SetYTitle(
"Pad row");
503 histName +=
"DigiChargeSpectrum";
504 newHisto =
new TH1I(histName.Data(), histName.Data(), 512, 0, 512);
505 newHisto->SetYTitle(
"Counts");
506 newHisto->SetXTitle(
"MaxAdc [ADC channels]");
509 histName +=
"DigiChargeSpectrumSt";
510 newHisto =
new TH1I(histName.Data(), histName.Data(), 512, 0, 512);
511 newHisto->SetYTitle(
"Counts");
512 newHisto->SetXTitle(
"MaxAdc [ADC channels]");
515 histName +=
"DigiChargeSpectrumNt";
516 newHisto =
new TH1I(histName.Data(), histName.Data(), 512, 0, 512);
517 newHisto->SetYTitle(
"Counts");
518 newHisto->SetXTitle(
"MaxAdc [ADC channels]");
521 histName +=
"DigiRelativeTimeMicroslice";
525 histName +=
"DigiTriggerType";
530 histName +=
"DigiHitFrequency";
531 newHisto =
new TProfile(histName.Data(), histName.Data(), 100000, 0, 100000);
532 newHisto->SetXTitle(
"Timeslice");
533 newHisto->SetYTitle(
"#langle hit frequency #rangle");
535 default:
return createHistoOk;
break;
537 LOG(debug4) << Form(
"UnpackerTrdAlgo - Histo[%d]-%s - initialize", iHisto, histName.Data());
539 TString moduleName(Form(
"%d", moduleId));
543 Int_t histoPosition = moduleId << bitShift;
544 histoPosition += iHisto;
548 if (newHisto->IsA() == TProfile::Class())
AddHistoToVector((TProfile*) newHisto, moduleName.Data());
550 if (newHisto->IsA() == TH2I::Class())
AddHistoToVector((TH2I*) newHisto, moduleName.Data());
552 if (newHisto->IsA() == TH1I::Class())
AddHistoToVector((TH1I*) newHisto, moduleName.Data());
554 if (newHisto->IsA() == TH1D::Class())
AddHistoToVector((TH1D*) newHisto, moduleName.Data());
556 createHistoOk = kTRUE;
559 return createHistoOk;
567 Bool_t isOkFill = kTRUE;
581 Int_t row = parModDigi->
GetPadRow(rotatedAddress);
582 Int_t column = parModDigi->
GetPadColumn(rotatedAddress);
599 size_t digiTime = digi.
GetTime();
633 Double_t hitFreq = (Double_t) dt;
635 hitFreq = 1.0 / hitFreq;
642 Int_t pulserChannelAddress(663);
643 Int_t pulserModule(5);
644 if (channelAddress == pulserChannelAddress && digi.
GetAddressModule() == pulserModule
653 Double_t hitFreq = (Double_t) dt;
655 hitFreq = 1.0 / hitFreq;
670 Bool_t isOkFill = kTRUE;
709 std::uint8_t pulserChannelId = 0;
710 std::uint8_t pulserElinkId = 29;
731 ((TH1*) *it)->Reset();
748 std::vector<std::pair<size_t, size_t>>*
const qVector)
767 Int_t digiAddress = -1;
776 if (rawTriggerType == 2)
780 Int_t digiErrClass = 0;
782 size_t spadicHwAddress(0);
785 Int_t asicAddress(0);
786 auto mapIt =
fSpadicMap.find(spadicHwAddress);
788 LOG(debug4) <<
"CbmMcbm2018UnpackerAlgoTrdR::MakeDigi - No asic address "
789 "found for Spadic hardware address %lu"
793 asicAddress = mapIt->second;
794 Int_t uniqueModuleId = asicAddress / 1000;
802 digiAddress = (
fAsicChannelMap.find(asicAddress))->second.at(asicChannelId);
804 ULong64_t digiTime = raw.
GetTime();
811 std::shared_ptr<CbmTrdDigi> digi = std::make_shared<CbmTrdDigi>(
812 CbmTrdDigi(digiAddress, uniqueModuleId, digiCharge, digiTime, digiTriggerType, digiErrClass));
819 if ((msg >> 61) == 1)
823 else if ((msg >> 63) == 1)
827 else if ((msg >> 62) == 1)
831 else if ((msg >> 60) == 1)
847 uint64_t mask = 0x000FFFFF;
849 if (((msg & mask) >> 18) == 3)
853 if (((msg & mask) >> 17) == 2)
857 if (((msg & mask) >> 17) == 3)
861 if (((msg & mask) >> 17) == 4)
865 if (((msg & mask) >> 17) == 5)
870 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::GetInfoType] unknown type!";
876 fles::MicrosliceDescriptor msDesc)
879 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::CreateRawMessage] Not a SOM word!";
883 uint8_t elinkId = 0, chId = 0, crobId = 0;
884 uint16_t criId = msDesc.eq_id;
886 uint8_t hitType = 0, nSamples = 0;
887 bool multihit =
false;
888 uint16_t timestamp = 0;
889 uint64_t mask = 0x3F;
891 elinkId = (char) ((word & mask) >> 55);
895 chId = (char) ((word & mask) >> 51);
899 timestamp = (uint16_t)((word & mask) >> 35);
903 hitType = (uint8_t)((word & mask) >> 33);
907 multihit = (bool) ((word & mask) >> 32);
911 nSamples = (uint8_t)((word & mask) >> 27);
920 std::vector<int16_t> samples;
921 for (
int i = 0; i < nSamples && i < 3; i++) {
926 CbmTrdRawMessageSpadic retval(chId, elinkId, crobId, criId, hitType, nSamples, multihit, fulltime, samples);
932 if (nsamples < 4)
return 0;
933 else if (nsamples < 11)
935 else if (nsamples < 18)
937 else if (nsamples < 25)
939 else if (nsamples < 32)
947 const std::array<uint16_t, 32> indices {
948 {4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0}};
949 uint64_t mask = 0x1FF;
952 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ExtractSample] Wrong Message Type!";
957 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ExtractSample] Wrong sample index!";
961 LOG(error) <<
"[CbmMcbm2018UnpackerAlgoTrdR::ExtractSample] Wrong sample index!";
964 uint16_t index = indices[sample];
966 mask = mask << (9 * (6 - index));
967 uint64_t temp = word & mask;
968 temp = temp >> (6 - index) * 9;
978 temp ^= (-0 ^ temp) & (1 << 7);
979 temp ^= (-1 ^ temp) & (1 << 8);
984 int16_t result = s.x = temp;
ClassImp(CbmConverterManager)
Helper class to convert unique channel ID back and forth.
static constexpr size_t size()
Timeslice unpacker algorithm for Spadic v.2.2 .
ULong64_t fNbSpadicErrorMsg
Number of Spadic error Messages.
ULong64_t fNbUnkownWord
Number of unknown data words in the Microslice stream.
std::map< Int_t, std::vector< Int_t > > fAsicChannelMap
Map to retrieve module channelId from asicAddress and asicChannel.
CbmTrdParSetDigi * fDigiPar
CbmTrdParameter container.
Bool_t ProcessTs(const fles::Timeslice &ts)
std::vector< size_t > fLastDigiTimeVec
std::vector< bool > fIsActiveHistoVec
Stores all Histograms.
Double_t fTsStartTime
Time in ns of current TS from the index of the first MS first componen.
bool fIsFirstChannelsElinkEven
define if the first 16 channels (00..15) are found on the even (set true) or odd (false) eLinkId,...
Int_t GetNumRda(Int_t nsamples)
std::map< size_t, Int_t > fSpadicMap
Map to retrieve asic address from CriId/CrobId/ElinkId (see CbmTrdHardwareSetupR)
Spadic::MsMessageType GetMessageType(const uint64_t msg)
Bool_t CreateHistograms()
Goes through fIsActiveHistoVec and creates the activated histograms.
ECbmTrdUnpackerHistograms
@ kRawMessage_Signalshape_filtered
@ kRawMessage_Signalshape_Nt
@ kRawMessage_Signalshape_all
@ kRawMessage_Signalshape_St
@ kRawDistributionMapModule5
@ kDigiRelativeTimeMicroslice
Bool_t fbBaselineAvg
Set to true if Baseline Averaging is activated in Spadic.
Bool_t ProcessMs(const fles::Timeslice &ts, size_t uMsCompIdx, size_t uMsIdx)
Unpacks one Microslice.
Bool_t fbMonitorMode
Switch ON the filling of a minimal set of histograms.
void AddMsComponentToList(size_t component, UShort_t usDetectorId)
CbmTrdParSetGain * fGainPar
CbmTrdParameter container.
ULong64_t fNbSpadicRawMsg
Counters.
int16_t ExtractSample(const uint64_t word, uint8_t sample, Bool_t multihit=kFALSE)
Extract a Sample from a given SOM or RDA word.
ULong64_t fNbWildRda
Number of RDA Words outside of a Message.
CbmTrdRawMessageSpadic CreateRawMessage(const uint64_t word, fles::MicrosliceDescriptor msDesc)
Bool_t SetDigiOutputPointer(std::vector< CbmTrdDigi > *const pVector)
Set fTrdDigiVector to the address of pVector.
std::vector< CbmTrdRawMessageSpadic > * fTrdRawMessageVector
Output Spadic raw messages for debugging.
Bool_t fbDebugWriteOutput
If ON the raw messages output vector is filled and written to disk.
Bool_t ReInitContainers()
ULong64_t fNbTimeslices
Instance of RawToDigi class.
CbmMcbm2018UnpackerAlgoTrdR()
ULong64_t fNbSpadicEpochMsg
Number of Spadic Epoch Messages.
Spadic::MsInfoType GetInfoType(const uint64_t msg)
Bool_t fbDebugSortOutput
If ON the raw messages output vector is sorted within time.
std::map< size_t, std::vector< Int_t > > fmapTimeshifts
Map containing the timeshift parameters for the correction of the µSlice timeshifts....
Double_t fdTimeOffsetNs
User settings: Data correction parameters.
ULong64_t fCurrTsIdx
Index of current Timeslice.
CbmTrdParSetAsic * fAsicPar
CbmTrdParameter container.
std::vector< std::pair< size_t, size_t > > * fSpadicInfoMsgVector
vector< pair< fulltime, word > >
std::shared_ptr< CbmTrdDigi > MakeDigi(CbmTrdRawMessageSpadic raw)
std::vector< CbmTrdDigi > * fTrdDigiVector
Output Digi vector.
void SetNbMsInTs(size_t uCoreMsNb, size_t uOverlapMsNb)
CbmTrdParSetGas * fGasPar
CbmTrdParameter container.
Bool_t SetRawOutputPointer(std::vector< CbmTrdRawMessageSpadic > *const pVector, std::vector< std::pair< size_t, size_t > > *const qVector=nullptr)
Set fTrdRawMessageVector to the address of pVector.
ULong64_t fSpadicEpoch
Epoch counter (30 bits). Counts overflow of Spadic timestamp (11 bits).
Bool_t fbDebugMonitorMode
Switch ON the filling of a additional set of histograms.
std::vector< Int_t > * fvecTimeshiftsPar
Vector containing the timeshift parameters for the correction of the µSlice timeshifts for a given ts...
static const UInt_t kBytesPerWord
Constants.
Bool_t CreateHistogram(ECbmTrdUnpackerHistograms iHisto)
create the histogram correlated to iHisto
~CbmMcbm2018UnpackerAlgoTrdR()
TList * fParContList
Parameters and Address mapping.
Double_t fdTsCoreSizeInNs
void AddHistoToVector(TNamed *pointer, std::string sFolder="")
std::vector< size_t > fvMsComponentsList
Double_t fdTsFullSizeInNs
int32_t GetAddressModule() const
Getter module address in the experiment.
int32_t GetTriggerType() const
Channel trigger type. SPADIC specific see CbmTrdTriggerType.
int32_t GetAddressChannel() const
Getter read-out id.
double GetTime() const
Getter for physical time [ns]. Accounts for clock representation of each ASIC. In SPADIC case physica...
double GetCharge() const
Common purpose charge getter.
std::map< size_t, Int_t > CreateHwToSwAsicAddressTranslatorMap(bool isLoadedParameters)
Create a hardware to software asic addreess translator map, with hidden parameter loading.
std::map< Int_t, std::vector< Int_t > > CreateAsicChannelMap(bool isLoadedParameters)
Create a Asic Channel Map, with hidden parameter loading.
Definition of chamber gain conversion for one TRD module.
Int_t GetPadRow(const Int_t channelNumber) const
Int_t GetOrientation() const
Int_t GetPadColumn(const Int_t channelNumber) const
Int_t GetNofColumns() const
virtual int GetModuleId() const
Describe TRD module ASIC settings (electronic gain, delays, etc)
virtual void clear()
Reset all parameters.
Describe TRD module working settings (HV, etc)
virtual const CbmTrdParMod * GetModulePar(Int_t detId) const
std::map< Int_t, CbmTrdParMod * > GetModuleMap()
Base class for storing raw information which comes from the Spadic v2.2 trough flib or from a tsa fil...
std::uint64_t GetFullTime() const
void SetTime(double setvalue)
const std::vector< std::int16_t > * GetSamples() const
std::uint8_t GetChannelId() const
void SetSample(std::int16_t value, std::uint8_t pos)
std::uint8_t GetNrSamples() const
std::uint8_t GetCrobId() const
std::uint8_t GetHitType() const
std::uint8_t GetElinkId() const
std::uint16_t GetCriId() const
@ kUNU
Unused request. 100. .... .... .... cccc.
@ kBOM
Buffer overflow count. 11nn nnnn nnnn nnnn cccc.
@ kMIS
Missing request. 101. .... .... .... ....
@ kBUF
Buffer full. 011b b... .... .... cccc.
@ kMSB
Message build error. 010. .... .... .... cccc.
@ kNeigh
Neighbor trigger.
@ kSandN
Self and neighbor trigger at the same time.
@ kEPO
Epoch Marker or TS_MSB depending on the hitmessage version.