126 auto sortstart = std::chrono::high_resolution_clock::now();
129 mDigitsIndex.resize(mDigits.size());
130 std::iota(mDigitsIndex.begin(), mDigitsIndex.end(), 0);
132 for (
auto& trig : mTrackletTriggerRecords) {
133 if (trig.getNumberOfTracklets() > 0) {
135 LOG(
debug) <<
" sorting tracklets from : " << trig.getFirstTracklet() <<
" till " << trig.getFirstTracklet() + trig.getNumberOfTracklets();
141 std::stable_sort(std::begin(mTracklets) + trig.getFirstTracklet(), std::begin(mTracklets) + trig.getNumberOfTracklets() + trig.getFirstTracklet(),
142 [
this](
auto&&
t1,
auto&& t2) {
143 int link1 = (!mLinkMap) ? HelperMethods::getLinkIDfromHCID(t1.getHCID()) : mLinkMap->getLink(t1.getHCID());
144 int link2 = (!mLinkMap) ? HelperMethods::getLinkIDfromHCID(t2.getHCID()) : mLinkMap->getLink(t2.getHCID());
145 if (link1 != link2) {
146 return link1 < link2;
148 if (
t1.getPadRow() != t2.getPadRow()) {
149 return t1.getPadRow() < t2.getPadRow();
151 return t1.getMCM() < t2.getMCM();
154 if (trig.getNumberOfDigits() != 0) {
156 LOG(
debug) <<
" sorting digits from : " << trig.getFirstDigit() <<
" till " << trig.getFirstDigit() + trig.getNumberOfDigits();
158 std::stable_sort(mDigitsIndex.begin() + trig.getFirstDigit(), mDigitsIndex.begin() + trig.getNumberOfDigits() + trig.getFirstDigit(),
159 [
this](
const uint32_t
i,
const uint32_t
j) {
160 int link1=HelperMethods::getLinkIDfromHCID(mDigits[i].getHCId());
161 int link2=HelperMethods::getLinkIDfromHCID(mDigits[j].getHCId());
162 if(link1!=link2){return link1<link2;}
163 if(mDigits[
i].getROB() != mDigits[
j].getROB()){return (mDigits[i].getROB() < mDigits[j].getROB());}
164 if(mDigits[
i].getMCM() != mDigits[
j].getMCM()){return (mDigits[i].getMCM() < mDigits[j].getMCM());}
165 return (mDigits[
i].getChannel() < mDigits[
j].getChannel()); });
170 std::chrono::duration<double> duration = std::chrono::high_resolution_clock::now() - sortstart;
171 LOG(info) <<
"TRD Digit/Tracklet Sorting took " << duration.count() <<
" s";
172 int triggercount = 0;
173 for (
auto& trig : mTrackletTriggerRecords) {
175 LOG(info) <<
"Trigger: " << triggercount <<
" with T " << trig.getBCData().asString();
176 LOG(info) <<
"Tracklets from:" << trig.getFirstTracklet() <<
" with " << trig.getNumberOfTracklets();
177 LOG(info) <<
"Digits from:" << trig.getFirstDigit() <<
" with " << trig.getNumberOfDigits();
178 if (trig.getNumberOfTracklets() > 0) {
179 int firsttracklet = trig.getFirstTracklet();
180 int numtracklets = trig.getNumberOfTracklets();
181 for (
int trackletcount = firsttracklet; trackletcount < firsttracklet + numtracklets; ++trackletcount) {
182 LOG(info) <<
"Tracklet : " << trackletcount <<
" details : tracklethcid :" << std::dec
183 << mTracklets[trackletcount].getHCID() <<
" linkid:" << HelperMethods::getLinkIDfromHCID(mTracklets[trackletcount].getHCID())
184 <<
" linkid by map : " << ((!mLinkMap) ? -1 : (
int)mLinkMap->getLink(mTracklets[trackletcount].getHCID()))
185 <<
" tracklet:" << mTracklets[trackletcount] <<
std::endl;
188 LOG(info) <<
"No Tracklets for this trigger";
190 if (trig.getNumberOfDigits() != 0) {
191 int firstdigit = trig.getFirstDigit();
192 int numdigits = trig.getNumberOfDigits();
194 LOG(info) <<
"Digit indexed: " <<
digitcount <<
" digit index : " << mDigitsIndex[
digitcount] <<
" details : hcid=" << mDigits[mDigitsIndex[
digitcount]].getHCId()
195 <<
" calculated hcid=" << (mDigits[mDigitsIndex[
digitcount]].getDetector() * 2 + (mDigits[mDigitsIndex[
digitcount]].getROB() % 2))
196 <<
" det=" << mDigits[mDigitsIndex[
digitcount]].getDetector()
197 <<
" mcm=" << mDigits[mDigitsIndex[
digitcount]].getMCM()
198 <<
" rob=" << mDigits[mDigitsIndex[
digitcount]].getROB()
199 <<
" channel=" << mDigits[mDigitsIndex[
digitcount]].getChannel()
200 <<
" col=" << mDigits[mDigitsIndex[
digitcount]].getPadRow()
201 <<
" pad=" << mDigits[mDigitsIndex[
digitcount]].getPadCol()
202 <<
" adcsum=" << mDigits[mDigitsIndex[
digitcount]].getADCsum()
203 <<
" hcid=" << mDigits[mDigitsIndex[
digitcount]].getHCId();
207 LOG(error) <<
"No Digits for this trigger <----- this should NEVER EVER HAPPEN";
211 LOG(info) <<
"end of pre sort tracklets then digits";
215void Trap2CRU::readTrapData()
220 LOG(info) <<
"Trap2CRU::readTrapData";
228 LOG(info) <<
"Retrieving LinkToHCIDMapping for time stamp " << mTimeStamp;
230 mLinkMap = ccdbmgr.getForTimeStamp<
LinkToHCIDMapping>(
"TRD/Config/LinkToHCIDMapping", mTimeStamp);
234 std::string prefix = mOutputDir;
235 if (!prefix.empty() && prefix.back() !=
'/') {
239 for (
int link = 0; link < constants::NHALFCRU; link++) {
246 LOG(info) <<
"FEEID;" << std::hex << mFeeID;
250 std::string outFileLink;
251 std::string outPrefix =
"TRD_";
252 outPrefix +=
"alio2-cr1-flp";
253 std::string outSuffix =
".raw";
257 if (mFilePer ==
"all") {
260 }
else if (mFilePer ==
"sm") {
263 std::stringstream ss;
264 ss << std::setw(2) << std::setfill(
'0') << sm;
267 }
else if (mFilePer ==
"cru") {
270 }
else if (mFilePer ==
"cruendpoint") {
274 throw std::runtime_error(
"invalid option provided for file grouping");
276 LOG(info) <<
"registering links";
277 mWriter.registerLink(mFeeID, mCruID, mLinkID, mEndPointID, outFileLink);
282 if (mTrackletsTree->GetEntries() != mDigitsTree->GetEntries()) {
283 LOG(fatal) <<
"Entry counts in mTrackletsTree and Digits Tree dont match " << mTrackletsTree->GetEntries() <<
"!=" << mDigitsTree->GetEntries();
285 int nTrackletsTotal = 0;
286 int nDigitsTotal = 0;
287 int nTriggerRecordsTotal = 0;
288 int triggercount = 42;
290 mTrackletsTree->GetEntry(
entry);
291 mDigitsTree->GetEntry(
entry);
292 nTrackletsTotal += mTracklets.size();
293 nDigitsTotal += mDigits.size();
294 nTriggerRecordsTotal += mTrackletTriggerRecords.size();
297 for (
auto tracklettrigger : mTrackletTriggerRecords) {
298 convertTrapData(tracklettrigger, triggercount);
302 LOGF(info,
"In the input files there were %u tracklets and %u digits in %u trigger records", nTrackletsTotal, nDigitsTotal, nTriggerRecordsTotal);
303 LOGF(info,
"Wrote %lu tracklets and %lu digits into the raw data", mTotalTrackletsWritten, mTotalDigitsWritten);
381int Trap2CRU::buildTrackletRawData(
unsigned int trackletIndexStart)
383 int hcid = mTracklets[trackletIndexStart].getHCID();
385 std::array<TrackletMCMData, 3>
tracklets;
387 header.
col = mTracklets[trackletIndexStart].getColumn();
388 header.
padrow = mTracklets[trackletIndexStart].getPadRow();
394 int iCurrTracklet = 0;
396 while (hcid == mTracklets[trackletIndexStart + iCurrTracklet].getHCID() &&
397 header.
col == mTracklets[trackletIndexStart + iCurrTracklet].getColumn() &&
398 header.
padrow == mTracklets[trackletIndexStart + iCurrTracklet].getPadRow()) {
399 unsigned int trackletIndex = trackletIndexStart + iCurrTracklet;
400 auto& trackletData =
tracklets[iCurrTracklet];
401 trackletData.word = 0;
403 trackletData.slope = mTracklets[trackletIndex].getSlope() ^ 0x80;
404 trackletData.pos = mTracklets[trackletIndex].getPosition() ^ 0x80;
405 trackletData.checkbit = 0;
407 bool qDynamicRange = mTracklets[trackletIndex].getFormat() & 0x1;
411 LOG(warning) <<
"Trying to add PID information for dynamic charge range, which is not yet verified";
412 trackletData.pid = ((mTracklets[trackletIndex].getQ1() & 0x3f) << 6) | (mTracklets[trackletIndex].getQ0() & 0x3f);
413 pidHeader = mTracklets[trackletIndex].getQ2() & 0x3f;
416 trackletData.pid = ((mTracklets[trackletIndex].getQ1() & 0x1f) << 7) | (mTracklets[trackletIndex].getQ0() & 0x7f);
417 pidHeader = ((mTracklets[trackletIndex].getQ2() & 0x3f) << 2) | ((mTracklets[trackletIndex].getQ1() >> 5) & 0x3);
419 if (iCurrTracklet == 0) {
420 header.
pid0 = pidHeader;
421 }
else if (iCurrTracklet == 1) {
422 header.
pid1 = pidHeader;
423 if (header.
pid0 == 0xff) {
424 LOG(error) <<
"Adding PID info for second tracklet, but first is marked as not available";
426 }
else if (iCurrTracklet == 2) {
427 header.
pid2 = pidHeader;
428 if (header.
pid1 == 0xff || header.
pid0 == 0xff) {
429 LOG(error) <<
"Adding PID info for third tracklet, but first or second is marked as not available";
432 LOG(fatal) <<
"Cannot have more than 3 tracklets for single trigger and single MCM";
435 if (trackletIndexStart + iCurrTracklet >= mTracklets.size()) {
440 if (iCurrTracklet == 0) {
441 LOG(fatal) <<
"Not writing any tracklet. This cannot happen, there must be at least one or this function would not be called";
448 for (
int i = 0;
i < iCurrTracklet; ++
i) {
455 return iCurrTracklet;
534 int nLinksWithData = 0;
535 char* rawdataptratstart;
536 std::vector<char> rawdatavector(1024 * 1024 * 2);
547 ir += ctpOffsets.LM_L0;
548 if (ctpOffsets.LM_L0 < 0 &&
ir.
toLong() <= -ctpOffsets.LM_L0) {
550 LOG(info) <<
"Skip writing IR " << triggerrecord.
getBCData() <<
" as after applying LM_L0 shift of " << ctpOffsets.LM_L0 <<
" bunches the orbit would become negative";
551 mCurrentDigit = enddigitindex;
552 mCurrentTracklet = endtrackletindex;
556 LOG(info) <<
"Skip writing trigger " << triggercount <<
" as there are neither digits nor tracklets";
560 for (
int halfcru = 0; halfcru < constants::NHALFCRU; halfcru++) {
561 int halfcruwordswritten = 0;
563 mEndPointID = halfcru % 2;
565 int cru = halfcru / 2;
568 mCruID = halfcru / 2;
569 mEndPointID = halfcru % 2;
573 buildHalfCRUHeader(halfcruheader,
ir.
bc, halfcru, isCalibTrigger);
574 halfcruheader.
EndPoint = mEndPointID;
575 mRawDataPtr = rawdatavector.data();
577 mRawDataPtr +=
sizeof(halfcruheader);
578 halfcruwordswritten +=
sizeof(halfcruheader) / 4;
579 int totallinklengths = 0;
580 rawdataptratstart = mRawDataPtr;
581 for (
int halfcrulink = 0; halfcrulink < constants::NLINKSPERHALFCRU; halfcrulink++) {
583 int linkid = halfcrulink + halfcru * constants::NLINKSPERHALFCRU;
584 int hcid = (!mLinkMap) ? HelperMethods::getHCIDFromLinkID(linkid) : mLinkMap->getHCID(linkid);
585 int linkwordswritten = 0;
587 uint32_t crudatasize = 0;
589 int nTrackletsOnLink = 0;
590 int nDigitsOnLink = 0;
591 bool haveDigitOnLink =
false;
592 bool haveTrackletOnLink =
false;
593 if (mCurrentTracklet < mTracklets.size() && mTracklets[mCurrentTracklet].getHCID() == hcid) {
594 haveTrackletOnLink =
true;
596 if (mCurrentDigit < mDigits.size() && mDigits[mDigitsIndex[mCurrentDigit]].getHCId() == hcid) {
597 haveDigitOnLink =
true;
600 LOGF(info,
"Link ID(%i), HCID(%i). Tracklets? %i, Digits? %i. Tracklet HCID(%i), mCurrentTracklet(%i), mCurrentDigit(%i)",
601 linkid, hcid, haveTrackletOnLink, haveDigitOnLink, mTracklets[mCurrentTracklet].getHCID(), mCurrentTracklet, mCurrentDigit);
603 if (haveTrackletOnLink || haveDigitOnLink) {
606 if (mUseTrackletHCHeader > 0) {
607 if (haveTrackletOnLink || mUseTrackletHCHeader == 2) {
610 writeTrackletHCHeader(hcid, triggercount);
611 linkwordswritten += 1;
615 while (mCurrentTracklet < endtrackletindex && mTracklets[mCurrentTracklet].getHCID() == hcid) {
617 int tracklets = buildTrackletRawData(mCurrentTracklet);
624 writeTrackletEndMarkers();
625 linkwordswritten += 2;
627 if (isCalibTrigger) {
629 writeDigitHCHeaders(triggercount, hcid);
630 linkwordswritten += 2;
631 while (mCurrentDigit < enddigitindex && mDigits[mDigitsIndex[mCurrentDigit]].getHCId() == hcid) {
633 int digitcounter = 0;
634 int currentROB = mDigits[mDigitsIndex[mCurrentDigit]].getROB();
635 int currentMCM = mDigits[mDigitsIndex[mCurrentDigit]].getMCM();
636 int firstDigitMCM = mCurrentDigit;
637 while (mDigits[mDigitsIndex[mCurrentDigit]].getMCM() == currentMCM &&
638 mDigits[mDigitsIndex[mCurrentDigit]].getROB() == currentROB &&
639 mDigits[mDigitsIndex[mCurrentDigit]].getHCId() == hcid) {
642 if (mCurrentDigit == enddigitindex) {
647 linkwordswritten += buildDigitRawData(firstDigitMCM, mCurrentDigit, currentMCM, currentROB, triggercount);
648 nDigitsOnLink += (mCurrentDigit - firstDigitMCM);
652 writeDigitEndMarkers();
653 linkwordswritten += 2;
657 int paddingsize = (linkwordswritten % 8 == 0) ? 0 : 8 - (linkwordswritten % 8);
658 int padword = constants::PADDINGWORD;
659 for (
int i = 0;
i < paddingsize; ++
i) {
660 memcpy(mRawDataPtr, &padword, 4);
664 rawwords += linkwordswritten;
665 crudatasize = linkwordswritten / 8;
666 if ((linkwordswritten % 8) != 0) {
667 LOG(error) <<
"linkwordswritten is not 256 bit aligned: " << linkwordswritten <<
". Padding size of= " << paddingsize;
671 if (crudatasize > constants::MAXDATAPERLINK256) {
672 LOG(error) <<
" linksize is huge : " << crudatasize;
674 LOG(
debug) <<
" setting halfcrulink " << halfcrulink <<
" linksize to : " << crudatasize <<
" with a linkwordswrittern=" << linkwordswritten;
676 uint32_t bytescopied;
677 totallinklengths += crudatasize;
678 if ((mRawDataPtr - rawdataptratstart) != (totallinklengths * 32)) {
679 bytescopied = mRawDataPtr - rawdataptratstart;
680 LOGF(error,
"Data size missmatch. Written words (%i), bytesCopied(%i), crudatasize(%i)", linkwordswritten, bytescopied, crudatasize);
682 LOGF(
debug,
"Found %i tracklets and %i digits on link %i (HCID=%i)", nTrackletsOnLink, nDigitsOnLink, linkid, hcid);
687 LOG(info) <<
"linkwordswritten is zero : " << linkwordswritten;
690 halfcruwordswritten += linkwordswritten;
693 memcpy((
char*)halfcruheaderptr, (
char*)&halfcruheader,
sizeof(halfcruheader));
695 std::vector<char> feeidpayload(halfcruwordswritten * 4);
696 memcpy(feeidpayload.data(), &rawdatavector[0], halfcruwordswritten * 4);
697 assert(halfcruwordswritten % 8 == 0);
698 mWriter.addData(mFeeID, mCruID, mLinkID, mEndPointID,
ir, feeidpayload,
false, triggercount);
700 LOGF(info,
"Written file for trigger %i, FeeID(%x), CruID(%i), LindID(%i), end point (%i), orbit(%i), bc(%i), payload size (%i)",
701 triggercount, mFeeID, mCruID, mLinkID, mEndPointID,
ir.
orbit,
ir.
bc, halfcruwordswritten);
703 LOG(info) <<
"+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+ ====== end of writing";
707 LOG(info) <<
"Raw data written for all CRUs of this trigger: " << rawwords;
708 LOG(info) <<
"Number of links with data for this trigger: " << nLinksWithData;