Skip to content
Snippets Groups Projects
Commit 18348085 authored by Alexandru Bercuci's avatar Alexandru Bercuci Committed by Pierre-Alain Loizeau
Browse files

add digi buffering to fix asynchronous ADC read-out. Restore PRF for

TRD2D clusters (hint by C.Schiaua)
parent 7ea221c8
No related branches found
No related tags found
1 merge request!873Changes from mCBM 2022 prod to TRD unpacking and reco
...@@ -35,9 +35,9 @@ using namespace std; ...@@ -35,9 +35,9 @@ using namespace std;
CbmTrdUnpackFaspAlgo::CbmTrdUnpackFaspAlgo() CbmTrdUnpackFaspAlgo::CbmTrdUnpackFaspAlgo()
: CbmRecoUnpackAlgo("CbmTrdUnpackFaspAlgo") : CbmRecoUnpackAlgo("CbmTrdUnpackFaspAlgo")
, fTime(0)
, fModuleId() , fModuleId()
, fAsicPar() , fAsicPar()
, fTime(0)
{ {
} }
...@@ -218,12 +218,11 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas ...@@ -218,12 +218,11 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas
UChar_t lFasp(0xff); UChar_t lFasp(0xff);
UShort_t lchR, lchT; UShort_t lchR, lchT;
Double_t r, t; Double_t r, t;
Int_t dt, dtime, ch, pad, row; Int_t dt, dtime, ch, pad;
ULong64_t tlab, tdaqOffset(0); ULong64_t lTime, tdaqOffset(0);
CbmTrdParFasp* faspPar(nullptr); CbmTrdParFasp* faspPar(nullptr);
const CbmTrdParFaspChannel* chCalib(nullptr); const CbmTrdParFaspChannel* chCalib(nullptr);
CbmTrdParModDigi* digiPar(nullptr); CbmTrdParModDigi* digiPar(nullptr);
vector<CbmTrdDigi*> digis;
for (auto imess : messes) { for (auto imess : messes) {
if (lFasp == 0xff) { if (lFasp == 0xff) {
lFasp = messes[0]->fasp; lFasp = messes[0]->fasp;
...@@ -237,67 +236,99 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas ...@@ -237,67 +236,99 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas
LOG(error) << GetName() << "::pushDigis - DIGI par for module " << imess->mod << " missing. Skip."; LOG(error) << GetName() << "::pushDigis - DIGI par for module " << imess->mod << " missing. Skip.";
return false; return false;
} }
// TODO temporary add DAQ time calibration for FASPRO.
// Should be absorbed in the ASIC parameter definition
if (digiPar->GetPadRow(faspPar->GetChannelAddress(imess->ch)) % 2) tdaqOffset = 3;
if (VERBOSE) faspPar->Print(); if (VERBOSE) faspPar->Print();
pad = faspPar->GetChannelAddress(imess->ch);
chCalib = faspPar->GetChannel(imess->ch);
ch = 2 * pad + chCalib->HasPairingR();
row = digiPar->GetPadRow(pad);
if (row % 2) tdaqOffset = 3;
if (VERBOSE)
printf("fasp[%2d] ch[%4d / %2d] pad[%4d] row[%2d] col[%2d] tilt[%d]\n", lFasp, ch, imess->ch, pad, row,
digiPar->GetPadColumn(pad), chCalib->HasPairingT());
} }
if (VERBOSE) mess_prt(imess); if (VERBOSE) mess_prt(imess);
pad = faspPar->GetChannelAddress(imess->ch);
chCalib = faspPar->GetChannel(imess->ch);
ch = 2 * pad + chCalib->HasPairingR();
lTime = fTime + tdaqOffset + imess->tlab;
lchR = 0; lchR = 0;
lchT = 0; lchT = 0;
chCalib = faspPar->GetChannel(imess->ch);
if (chCalib->HasPairingR()) lchR = imess->data; if (chCalib->HasPairingR()) lchR = imess->data;
else else
lchT = imess->data; lchT = imess->data;
pad = faspPar->GetChannelAddress(imess->ch); if (VERBOSE)
printf("fasp[%2d] ch[%4d / %2d] pad[%4d] row[%2d] col[%2d] %c[%4d]\n", lFasp, ch, imess->ch, pad,
bool use(false); digiPar->GetPadRow(pad), digiPar->GetPadColumn(pad), (chCalib->HasPairingT() ? 'T' : 'R'),
for (auto id : digis) { lchT > 0 ? lchT : lchR);
if (id->GetAddressChannel() != pad) continue;
dtime = id->GetTimeDAQ() - imess->tlab; if (fDigiBuffer.find(pad) != fDigiBuffer.end()) {
if (TMath::Abs(dtime) < 5) { // check if last digi has both R/T message components. Update if not and is within time window
r = id->GetCharge(t, dt); auto id = fDigiBuffer[pad].rbegin();
if (lchR && !int(r)) { dtime = (*id)->GetTimeDAQ() - lTime;
id->SetCharge(t, lchR, -dtime); bool use(false);
if (TMath::Abs(dtime) < 5) { // test message part of (last) digi
r = (*id)->GetCharge(t, dt);
if (lchR && r < 0.1) { // set R charge on an empty slot
(*id)->SetCharge(t, lchR, -dtime);
use = true; use = true;
break;
} }
else if (lchT && !int(t)) { else if (lchT && t < 0.1) { // set T charge on an empty slot
tlab = id->GetTimeDAQ(); (*id)->SetCharge(lchT, r, +dtime);
id->SetCharge(lchT, r, +dtime); (*id)->SetTimeDAQ(ULong64_t((*id)->GetTimeDAQ() - dtime));
id->SetTimeDAQ(ULong64_t(tlab - dtime));
use = true; use = true;
break;
} }
} }
}
if (!use) { // build digi for message when update failed
CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, imess->tlab); if (!use) {
CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, lTime);
digi->SetAddressModule(imess->mod);
fDigiBuffer[pad].push_back(digi);
id = fDigiBuffer[pad].rbegin();
}
if (id != fDigiBuffer[pad].rend()) id++;
// update charge for previously allocated digis to account for FASPRO ADC buffering and read-out problem
use = false;
for (; id != fDigiBuffer[pad].rend(); ++id) {
r = (*id)->GetCharge(t, dt);
if (lchR && int(r)) { // update R charge and mark on digi
(*id)->SetCharge(t, lchR, dt);
(*id)->SetFlag(1);
use = true;
}
else if (lchT && int(t)) { // update T charge and mark on digi
(*id)->SetCharge(lchT, r, dt);
(*id)->SetFlag(0);
use = true;
}
if (use) break;
}
}
else { // init pad position in map and build digi for message
CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, lTime);
digi->SetAddressModule(imess->mod); digi->SetAddressModule(imess->mod);
digis.push_back(digi); fDigiBuffer[pad].push_back(digi);
} }
delete imess; delete imess;
} }
// push finalized digits to the next level // push finalized digits to the next level
for (vector<CbmTrdDigi*>::iterator id = digis.begin(); id != digis.end(); id++) { for (int jd(0); jd < NFASPCH; jd += 2) {
// TODO temporary add DAQ time calibration for FASPRO. int ipad(faspPar->GetChannelAddress(jd));
// Should be absorbed in the ASIC parameter definition if (fDigiBuffer.find(ipad) == fDigiBuffer.end()) continue;
(*id)->SetTimeDAQ(fTime + (*id)->GetTimeDAQ() + tdaqOffset);
fOutputVec.emplace_back(*std::move(*id)); for (auto id = fDigiBuffer[ipad].begin(); id != fDigiBuffer[ipad].end(); id++) {
if (fMonitor) fMonitor->FillHistos((*id)); r = (*id)->GetCharge(t, dt);
if (VERBOSE) cout << (*id)->ToString(); // check if digi has all signals CORRECTED
if (((t > 0) != (*id)->IsFlagged(0)) || ((r > 0) != (*id)->IsFlagged(1))) continue;
if (fMonitor) fMonitor->FillHistos(((*id)));
// reset flags as they were used only to mark the correctly setting of the charge/digi
(*id)->SetFlag(0, false);
(*id)->SetFlag(1, false);
fOutputVec.emplace_back(*std::move((*id)));
// clear digi buffer wrt the digi which was forwarded to higher structures
id = fDigiBuffer[ipad].erase(id);
}
} }
digis.clear();
messes.clear(); messes.clear();
return true; return true;
...@@ -366,14 +397,15 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp ...@@ -366,14 +397,15 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp
// std::cout<<"fasp_id="<<static_cast<unsigned int>(fasp_id)<<" ch_id="<<static_cast<unsigned int>(ch_id)<<" isaux="<<static_cast<unsigned int>(isaux)<<std::endl; // std::cout<<"fasp_id="<<static_cast<unsigned int>(fasp_id)<<" ch_id="<<static_cast<unsigned int>(ch_id)<<" isaux="<<static_cast<unsigned int>(isaux)<<std::endl;
if (isaux) { if (isaux) {
if (!ch_id) { if (!ch_id) {
// clear buffer
if (vDigi.size()) { pushDigis(vDigi); }
vDigi.clear();
if (VERBOSE) if (VERBOSE)
cout << boost::format(" EE : fasp_id=%02d ch_id=%02d epoch=%03d\n") % static_cast<unsigned int>(fasp_id) cout << boost::format(" EE : fasp_id=%02d ch_id=%02d epoch=%03d\n") % static_cast<unsigned int>(fasp_id)
% static_cast<unsigned int>(ch_id) % static_cast<unsigned int>(epoch); % static_cast<unsigned int>(ch_id) % static_cast<unsigned int>(epoch);
if (vDigi.size()) { pushDigis(vDigi); }
vDigi.clear();
lFaspOld = 0xff; lFaspOld = 0xff;
fTime += FASP_EPOCH_LENGTH; fTime += FASP_EPOCH_LENGTH;
} }
else if (ch_id == 1) { else if (ch_id == 1) {
...@@ -403,7 +435,7 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp ...@@ -403,7 +435,7 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp
} }
mess = new CbmTrdFaspContent; mess = new CbmTrdFaspContent;
mess->ch = ch_id; mess->ch = ch_id;
mess->type = 1; mess->type = kData;
mess->tlab = slice; mess->tlab = slice;
mess->data = data >> 1; mess->data = data >> 1;
mess->fasp = lFaspOld; mess->fasp = lFaspOld;
......
...@@ -196,6 +196,7 @@ private: ...@@ -196,6 +196,7 @@ private:
void prt_wd(uint32_t w); void prt_wd(uint32_t w);
std::map<uint32_t, uint8_t[NFASPMOD]>* fFaspMap = nullptr; ///> FASP mapping update wrt the default setting std::map<uint32_t, uint8_t[NFASPMOD]>* fFaspMap = nullptr; ///> FASP mapping update wrt the default setting
std::map<uint32_t, uint16_t[NCROBMOD]>* fCrobMap = nullptr; ///> CRI mapping setting std::map<uint32_t, uint16_t[NCROBMOD]>* fCrobMap = nullptr; ///> CRI mapping setting
std::map<uint32_t, std::vector<CbmTrdDigi*>> fDigiBuffer; ///> Map of buffered digi per pad
/** @brief Potential (online) monitor for the unpacking process */ /** @brief Potential (online) monitor for the unpacking process */
std::shared_ptr<CbmTrdUnpackFaspMonitor> fMonitor = nullptr; std::shared_ptr<CbmTrdUnpackFaspMonitor> fMonitor = nullptr;
std::vector<Int_t> fModuleId; std::vector<Int_t> fModuleId;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment