24 LOG(info) <<
"Initialization of ZDC reconstruction";
27 mIsContinuous = sopt.continuous;
28 mNBCAHead = mIsContinuous ? sopt.nBCAheadCont : sopt.nBCAheadTrig;
31 LOG(fatal) <<
"Missing ModuleConfig configuration object";
41 LOG(info) <<
"ZDC DigiReco: opening debug output";
42 mDbg = std::make_unique<TFile>(
"ZDCRecoDbg.root",
"recreate");
43 mTDbg = std::make_unique<TTree>(
"zdcr",
"ZDCReco");
44 mTDbg->Branch(
"zdcr",
"RecEventAux", &mRec);
56 if (ropt.
tmod[itdc] < 0 || ropt.
tch[itdc] < 0) {
58 for (
int im = 0; im <
NModules; im++) {
60 if (mModuleConfig->
modules[im].channelID[ic] == isig && mModuleConfig->
modules[im].readChannel[ic]) {
66 mTDCMask[itdc] = (0x1 << (4 * im + ic));
73 mTDCMask[itdc] = (0x1 << (4 * ropt.
tmod[itdc] + ropt.
tch[itdc]));
78 <<
" mod " << ropt.
tmod[itdc] <<
" ch " << ropt.
tch[itdc];
84 if (mLowPassFilterSet ==
false) {
86 if (!mRecoConfigZDC) {
87 LOG(fatal) <<
"Configuration of low pass filtering: missing configuration object and no manual override";
94 LOG(info) <<
"Low pass filtering is " << (mLowPassFilter ?
"enabled" :
"disabled");
97 if (mFullInterpolationSet ==
false) {
99 if (!mRecoConfigZDC) {
100 LOG(fatal) <<
"Configuration of interpolation: missing configuration object and no manual override";
112 LOG(info) <<
"Full waveform interpolation is " << (mFullInterpolation ?
"enabled" :
"disabled") <<
" min length is " << mFullInterpolationMinLength;
116 if (!mRecoConfigZDC) {
117 LOG(fatal) <<
"Trigger condition: missing configuration object and no manual override";
125 if (mTriggerCondition == 0x1) {
126 LOG(info) <<
"SINGLE trigger condition enforced in reconstruction";
127 }
else if (mTriggerCondition == 0x3) {
128 LOG(info) <<
"DOUBLE trigger condition enforced in reconstruction";
129 }
else if (mTriggerCondition == 0x7) {
130 LOG(info) <<
"TRIPLE trigger condition enforced in reconstruction";
132 LOG(fatal) <<
"Unsupported trigger condition in ZDC reconstruction: " << mTriggerCondition;
135 if (mCorrSignalSet ==
false) {
137 if (!mRecoConfigZDC) {
138 LOG(fatal) <<
"Configuration of TDC signal correction: missing configuration object and no manual override";
146 LOG(info) <<
"TDC signal correction is " << (mCorrSignal ?
"enabled" :
"disabled");
149 if (mCorrBackgroundSet ==
false) {
151 if (!mRecoConfigZDC) {
152 LOG(fatal) <<
"Configuration of TDC pile-up correction: missing configuration object and no manual override";
160 LOG(info) <<
"TDC pile-up correction is " << (mCorrBackground ?
"enabled" :
"disabled");
166 if (ropt.
tth[itdc] <= 0) {
167 if (!mRecoConfigZDC) {
168 LOG(fatal) <<
"Trigger threshold for TDC " << itdc <<
" missing configuration object and no manual override";
170 ropt.
tth[itdc] = mRecoConfigZDC->
tth[itdc];
173 if (ropt.
tsh[itdc] <= 0) {
174 if (!mRecoConfigZDC) {
175 LOG(fatal) <<
"Trigger shift for TDC " << itdc <<
" missing configuration object and no manual override";
177 ropt.
tsh[itdc] = mRecoConfigZDC->
tsh[itdc];
187 if (mRecoConfigZDC ==
nullptr) {
188 LOG(fatal) <<
"Extended search configuration: missing configuration object and no manual override";
197 if (mRecoConfigZDC ==
nullptr) {
198 LOG(fatal) <<
"Storage of hits with in-event pile-up: missing configuration object and no manual override";
213 LOG(fatal) <<
"TDC " << itdc <<
" missing configuration object and no manual override";
219 auto val = std::nearbyint(fval);
220 if (
val < kMinShort) {
221 LOG(fatal) <<
"Shift for TDC " << itdc <<
" " <<
val <<
" is out of range";
223 if (
val > kMaxShort) {
224 LOG(fatal) <<
"Shift for TDC " << itdc <<
" " <<
val <<
" is out of range";
226 tdc_shift[itdc] =
val;
239 LOG(fatal) <<
"TDC amplitude calibration " << itdc <<
" missing configuration object and no manual override";
245 LOG(fatal) <<
"Correction factor for TDC amplitude " << itdc <<
" " << fval <<
" is out of range";
247 tdc_calib[itdc] = fval;
253 LOG(fatal) <<
"TDC offset correction " << itdc <<
" missing configuration object and no manual override";
258 if (fval <= -ADCRange || fval >=
ADCRange) {
259 LOG(fatal) <<
"TDC offset correction " << itdc <<
" " << fval <<
" is out of range";
261 tdc_offset[itdc] = fval;
263 LOG(info) << itdc <<
" " <<
ChannelNames[
TDCSignal[itdc]] <<
" factor= " << tdc_calib[itdc] <<
" offset= " << tdc_offset[itdc];
271 if (!mRecoConfigZDC) {
272 LOG(fatal) <<
"Search zone for TDC " << itdc <<
" missing configuration object and no manual override";
348 for (
int ich = 0; ich <
NChannels; ich++) {
350 if (ropt.
amod[ich] < 0 || ropt.
ach[ich] < 0) {
351 for (
int im = 0; im <
NModules; im++) {
353 if (mModuleConfig->
modules[im].channelID[ic] == ich && mModuleConfig->
modules[im].readChannel[ic]) {
357 mChMask[ich] = (0x1 << (4 * im + ic));
364 mChMask[ich] = (0x1 << (4 * ropt.
amod[ich] + ropt.
ach[ich]));
368 LOG(info) <<
"ADC " << ich <<
"(" <<
ChannelNames[ich] <<
") mod " << ropt.
amod[ich] <<
" ch " << ropt.
ach[ich];
373 for (
int ich = 0; ich <
NChannels; ich++) {
376 if (!mRecoConfigZDC) {
377 LOG(fatal) <<
"Integration for signal " << ich <<
" missing configuration object and no manual override";
384 if (!mRecoConfigZDC) {
385 LOG(fatal) <<
"Integration for pedestal " << ich <<
" missing configuration object and no manual override";
394 if (!mRecoConfigZDC) {
395 LOG(fatal) <<
"Pedestal threshold high for signal " << ich <<
" missing configuration object and no manual override";
401 if (!mRecoConfigZDC) {
402 LOG(fatal) <<
"Pedestal threshold low for signal " << ich <<
" missing configuration object and no manual override";
412 if (mVerbosity >
DbgZero && mTDCCorr !=
nullptr) {
416 if (mLowPassFilter ==
false) {
417 LOG(warning) <<
"Low pass filtering of signal is disabled";
419 if (mCorrSignal ==
false) {
420 LOG(warning) <<
"TDC signal correction is disabled";
422 if (mCorrBackground ==
false) {
423 LOG(warning) <<
"TDC pile-up correction is disabled";
425 if (mPedParam ==
nullptr) {
426 LOG(warning) <<
"Missing average pedestals";
431 mPedParam->
print(
false);
439 LOG(info) <<
"o2::zdc::DigiReco: closing debug output";
449 LOG(warn) <<
"Detected " << mNLonely <<
" lonely bunches";
450 for (
int ib = 0; ib < o2::constants::lhc::LHCMaxBunches; ib++) {
452 LOGF(warn,
"lonely bunch %4d #times=%u #trig=%u", ib, mLonely[ib], mLonelyTrig[ib]);
456 for (
int ich = 0; ich <
NChannels; ich++) {
457 if (mMissingPed[ich] > 0) {
458 LOGF(
error,
"Missing pedestal for ch %2d %s: %u", ich,
ChannelNames[ich], mMissingPed[ich]);
474 for (
int tsi = 0; tsi <=
n; tsi++) {
478 fs = TMath::Sin(arg1) / arg1;
486 mTS[
n + tsi] = fs * fg;
487 mTS[
n - tsi] = mTS[
n + tsi];
490 LOG(info) <<
"Interpolation alpha = " << mAlpha;
493int DigiReco::process(
const gsl::span<const o2::zdc::OrbitData>& orbitdata,
const gsl::span<const o2::zdc::BCData>& bcdata,
const gsl::span<const o2::zdc::ChannelData>& chdata)
495#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
496 LOG(info) <<
"________________________________________________________________________________";
497 LOG(info) << __func__;
500 mOrbitData = orbitdata;
507 int norb = mOrbitData.size();
509 LOG(info) <<
"Dump of pedestal data lookup table";
513 for (
int iorb = 0; iorb < norb; iorb++) {
514 mOrbit[mOrbitData[iorb].ir.orbit] = iorb;
516 LOG(info) <<
"mOrbitData[" << mOrbitData[iorb].ir.orbit <<
"] = " << iorb;
519 for (
int ich = 0; ich <
NChannels; ich++) {
520 if (mOrbitData[iorb].scaler[ich] <= o2::constants::lhc::LHCMaxBunches) {
521 scaler[ich] += mOrbitData[iorb].scaler[ich];
526 for (
int ich = 0; ich <
NChannels; ich++) {
531 mNBC = mBCData.size();
535 for (
int ibc = 0; ibc < mNBC; ibc++) {
536 auto& bcr = mReco[ibc];
537#ifdef O2_ZDC_TDC_C_ARRAY
540 bcr.tdcVal[itdc][
i] = kMinShort;
541 bcr.tdcAmp[itdc][
i] = kMinShort;
545 auto& bcd = mBCData[ibc];
547 int chEnt = bcd.ref.getFirstEntry();
548 for (
int ic = 0; ic < bcd.ref.getEntries(); ic++) {
549 auto& chd = mChData[chEnt];
551 bcr.ref[chd.id] = chEnt;
569 for (
int ibc = 0; ibc < mNBC; ibc++) {
570 mReco[ibc].ir = mBCData[ibc].ir;
571 mReco[ibc].channels = mBCData[ibc].channels;
572 mReco[ibc].triggers = mBCData[ibc].triggers;
573 for (
int isig = 0; isig <
NChannels; isig++) {
574 auto ref = mReco[ibc].ref[isig];
581 mReco[ibc].data[isig][is] = mChData[
ref].data[is];
588 if (mLowPassFilter) {
596 for (
int ibc = 0; ibc < mNBC; ibc++) {
597 auto ref_c = mReco[ibc].ref[isig];
600 mReco[ibc].data[isig][is] = mChData[ref_c].data[is];
607 if (mFullInterpolation) {
609 for (
int isig = 0; isig <
NChannels; isig++) {
611 if (isig == isig_tdc) {
615 for (
int ibc = 0; ibc < mNBC; ibc++) {
616 auto ref_c = mReco[ibc].ref[isig];
619 mReco[ibc].data[isig][is] = mChData[ref_c].data[is];
634 LOG(info) <<
"Processing ZDC reconstruction for " << mNBC <<
" bunch crossings";
638 for (
int ibc = 0; ibc < mNBC; ibc++) {
639 auto&
ir = mBCData[seq_end].ir;
640 auto bcd = mBCData[ibc].ir.differenceInBC(
ir);
642 LOG(
error) <<
"Bunch order error in TDC reconstruction";
643 for (
int ibcdump = 0; ibcdump < mNBC; ibcdump++) {
644 LOG(
error) <<
"mBCData[" << ibcdump <<
"] @ " << mBCData[ibcdump].ir.orbit <<
"." << mBCData[ibcdump].ir.bc;
646 LOG(
error) <<
"Orbit number is not increasing " << mBCData[seq_end].ir.orbit <<
"." << mBCData[seq_end].ir.bc <<
" followed by " << mBCData[ibc].ir.orbit <<
"." << mBCData[ibc].ir.bc;
648 }
else if (bcd > 1) {
650 int rval = reconstructTDC(seq_beg, seq_end);
657 }
else if (ibc == (mNBC - 1)) {
660 int rval = reconstructTDC(seq_beg, seq_end);
671#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
673 mBCData[ibc].print(mTriggerMask);
683 for (
int ibc = 0; ibc < mNBC; ibc++) {
684 auto&
ir = mBCData[seq_end].ir;
685 auto bcd = mBCData[ibc].ir.differenceInBC(
ir);
687 LOG(
error) <<
"Bunch order error in ADC reconstruction";
688 for (
int ibcdump = 0; ibcdump < mNBC; ibcdump++) {
689 LOG(
error) <<
"mBCData[" << ibcdump <<
"] @ " << mBCData[ibcdump].ir.orbit <<
"." << mBCData[ibcdump].ir.bc;
691 LOG(
error) <<
"Orbit number is not increasing " << mBCData[seq_end].ir.orbit <<
"." << mBCData[seq_end].ir.bc <<
" followed by " << mBCData[ibc].ir.orbit <<
"." << mBCData[ibc].ir.bc;
693 }
else if (bcd > 1) {
695 int rval = reconstruct(seq_beg, seq_end);
701 }
else if (ibc == (mNBC - 1)) {
704 int rval = reconstruct(seq_beg, seq_end);
718void DigiReco::lowPassFilter()
723#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
724 LOG(info) <<
"________________________________________________________________________________";
725 LOG(info) << __func__;
730 for (
int ibc = 0; ibc < mNBC; ibc++) {
732 auto ref_c = mReco[ibc].ref[isig];
738 ref_p = mReco[ibc - 1].ref[isig];
739 bcd_p = mReco[ibc].ir.differenceInBC(mReco[ibc - 1].
ir);
741 if (ibc < (mNBC - 1)) {
742 ref_n = mReco[ibc + 1].ref[isig];
743 bcd_n = mReco[ibc + 1].ir.differenceInBC(mReco[ibc].
ir);
749 sum += mChData[ref_c].data[1];
752 sum += mChData[ref_p].data[MaxTimeBin];
755 sum += mChData[ref_c].data[0];
757 }
else if (is == MaxTimeBin) {
758 sum += mChData[ref_c].data[MaxTimeBin - 1];
761 sum += mChData[ref_n].data[0];
764 sum += mChData[ref_c].data[MaxTimeBin];
768 sum += mChData[ref_c].data[is - 1];
769 sum += mChData[ref_c].data[is + 1];
772 bool isNegative =
sum < 0;
785 mReco[ibc].data[isig][is] =
sum;
792int DigiReco::reconstructTDC(
int ibeg,
int iend)
794#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
795 LOG(info) <<
"________________________________________________________________________________";
796 LOG(info) << __func__ <<
"(" << ibeg <<
", " << iend <<
") length=" << iend - ibeg + 1;
798 mAssignedTDC[itdc] = 0;
806 int istart = -1, istop = -1;
808 for (
int ibun = ibeg; ibun <= iend; ibun++) {
809 if (mBCData[ibun].
channels & mTDCMask[itdc]) {
816 if (istart >= 0 && (istop - istart) > 0) {
820 rval = processTriggerExtended(itdc, istart, istop);
822 rval = processTrigger(itdc, istart, istop);
833 if (istart >= 0 && (istop - istart) > 0) {
836 rval = processTriggerExtended(itdc, istart, istop);
838 rval = processTrigger(itdc, istart, istop);
851 if (mFullInterpolation) {
852 for (
int isig = 0; isig <
NChannels; isig++) {
854 if (isig == isig_tdc) {
861 int istart = -1, istop = -1;
863 for (
int ibun = ibeg; ibun <= iend; ibun++) {
864 if (mBCData[ibun].
channels & mChMask[isig]) {
871 if (istart >= 0 && (istop - istart + 1) >= mFullInterpolationMinLength) {
873 int rval = fullInterpolation(isig, istart, istop);
883 if (istart >= 0 && (istop - istart + 1) >= mFullInterpolationMinLength) {
884 int rval = fullInterpolation(isig, istart, istop);
891#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
892 printf(
"Assiged TDCs:");
893 bool hasMult =
false;
895 if (mAssignedTDC[itdc] > 0) {
897 if (mAssignedTDC[itdc] > 1) {
903 printf(
" MULTIPLE_ASSIGNMENTS\n");
911int DigiReco::reconstruct(
int ibeg,
int iend)
913#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
914 LOG(info) <<
"________________________________________________________________________________";
915 LOG(info) << __func__ <<
"(" << ibeg <<
", " << iend <<
"): " << mReco[ibeg].ir.orbit <<
"." << mReco[ibeg].ir.bc <<
" - " << mReco[iend].ir.orbit <<
"." << mReco[iend].ir.bc;
920 mLonely[mReco[ibeg].ir.bc]++;
921 if (mBCData[ibeg].triggers != 0x0) {
922 mLonelyTrig[mReco[ibeg].ir.bc]++;
928#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
929 for (
int ibun = ibeg; ibun <= iend; ibun++) {
930 printf(
"%d CH Mask: 0x%08x TDC data for:", ibun, mBCData[ibun].
channels);
932 if (mBCData[ibun].
channels & mTDCMask[itdc]) {
943 findSignals(ibeg, iend);
947 for (
int ich = 0; ich <
NChannels; ich++) {
957 for (
int ibp = 1; ibp < 4; ibp++) {
958 int ibun = ibeg - ibp;
963 auto bcd = mBCData[ibeg].ir.differenceInBC(mBCData[ibun].
ir);
965 LOG(
error) <<
"Bunches are not in ascending order: " << mBCData[ibeg].ir.orbit <<
"." << mBCData[ibeg].ir.bc <<
" followed by " << mBCData[ibun].ir.orbit <<
"." << mBCData[ibun].ir.bc;
972 ref[bcd] = mReco[ibun].ref[ich];
981 hasFired[bcd] = mReco[ibun].chfired[ich];
985 hasHit[bcd] = mBCData[ibun].triggers & mChMask[ich];
988 ModuleTriggerMapData
mt;
989 mt.w = mBCData[ibun].moduleTriggers[mRopt->
amod[ich]];
990 hasAuto0[bcd] =
mt.f.Auto_0;
991 hasAutoM[bcd] =
mt.f.Auto_m;
992#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
993 printf(
"%2d %s bcd = %d ibun = %d ibeg = %d ref = %3u %s %s %s\n",
995 hasHit[bcd] ?
"H" :
"-", hasAuto0[bcd] ?
"A0" :
"--", hasAutoM[bcd] ?
"AM" :
"--");
999 for (
int ibun = ibeg; ibun <= iend; ibun++) {
1000 updateOffsets(ibun);
1001 auto&
rec = mReco[ibun];
1003 ref[0] = mReco[ibun].ref[ich];
1004 hasHit[0] = mBCData[ibun].triggers & mChMask[ich];
1005 ModuleTriggerMapData
mt;
1006 mt.w = mBCData[ibun].moduleTriggers[mRopt->
amod[ich]];
1007 hasAuto0[0] =
mt.f.Auto_0;
1008 hasAutoM[0] =
mt.f.Auto_m;
1009 if (
rec.chfired[ich]) {
1014 bool hasEvPed =
false;
1017 auto ref_m =
ref[1];
1039 if (hasEvPed && (mSource[ich] ==
PedOr || mSource[ich] ==
PedQC)) {
1040 auto pedref = mOffset[ich];
1041 if (evPed > pedref && (evPed - pedref) > mRopt->
ped_thr_hi[ich]) {
1043 rec.offPed[ich] =
true;
1044 }
else if (evPed < pedref && (pedref - evPed) > mRopt->
ped_thr_lo[ich]) {
1046 rec.pilePed[ich] =
true;
1049 float myPed = std::numeric_limits<float>::infinity();
1051 if (hasEvPed &&
rec.pilePed[ich] ==
false) {
1053 rec.adcPedEv[ich] =
true;
1054 }
else if (mSource[ich] ==
PedOr) {
1055 myPed = mOffset[ich];
1056 rec.adcPedOr[ich] =
true;
1057 }
else if (mSource[ich] ==
PedQC) {
1058 myPed = mOffset[ich];
1059 rec.adcPedQC[ich] =
true;
1061 rec.adcPedMissing[ich] =
true;
1063 if (myPed < std::numeric_limits<float>::infinity()) {
1065 for (
int is = mRopt->
beg_int[ich]; is <= mRopt->
end_int[ich]; is++) {
1072 LOGF(warn,
"%d.%-4d CH %2d %s missing pedestal",
rec.ir.orbit,
rec.ir.bc, ich,
ChannelNames[ich].data());
1084 rec.adcPedMissing[ich] =
true;
1086 LOGF(warn,
"%d.%-4d CH %2d %s ADC missing, TDC present",
rec.ir.orbit,
rec.ir.bc, ich,
ChannelNames[ich].data());
1094 for (
int ibcr =
NBCReadOut - 1; ibcr > 0; ibcr--) {
1095 ref[ibcr] =
ref[ibcr - 1];
1096 hasHit[ibcr] = hasHit[ibcr - 1];
1097 hasAuto0[ibcr] = hasAuto0[ibcr - 1];
1098 hasAutoM[ibcr] = hasAutoM[ibcr - 1];
1099 hasFired[ibcr] = hasFired[ibcr - 1];
1105 for (
int ibun = ibeg; ibun <= iend; ibun++) {
1106 auto&
rec = mReco[ibun];
1114void DigiReco::updateOffsets(
int ibun)
1116 auto orbit = mBCData[ibun].ir.orbit;
1117 if (
orbit == mOffsetOrbit) {
1120 mOffsetOrbit =
orbit;
1123 for (
int ich = 0; ich <
NChannels; ich++) {
1124 mSource[ich] =
PedND;
1125 mOffset[ich] = std::numeric_limits<float>::infinity();
1130 std::map<uint32_t, int>::iterator it = mOrbit.find(
orbit);
1131 if (it != mOrbit.end()) {
1132 auto& orbitdata = mOrbitData[it->second];
1133 for (
int ich = 0; ich <
NChannels; ich++) {
1137 mOffset[ich] = myped;
1138 mSource[ich] =
PedOr;
1144 if (mPedParam !=
nullptr) {
1145 for (
int ich = 0; ich <
NChannels; ich++) {
1146 if (mSource[ich] ==
PedND) {
1147 auto myped = mPedParam->
getCalib(ich);
1149 mOffset[ich] = myped;
1150 mSource[ich] =
PedQC;
1156 for (
int ich = 0; ich <
NChannels; ich++) {
1157 if (mSource[ich] ==
PedND) {
1160 LOGF(
error,
"Missing pedestal for ch %2d %s orbit %u ", ich,
ChannelNames[ich], mOffsetOrbit);
1163#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1164 LOGF(info,
"Pedestal for ch %2d %s orbit %u %s: %f", ich,
ChannelNames[ich], mOffsetOrbit, mSource[ich] ==
PedOr ?
"OR" : (mSource[ich] ==
PedQC ?
"QC" :
"??"), mOffset[ich]);
1169int DigiReco::processTrigger(
int itdc,
int ibeg,
int iend)
1171#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1172 LOG(info) << __func__ <<
"(itdc=" << itdc <<
"[" <<
ChannelNames[
TDCSignal[itdc]] <<
"], " << ibeg <<
", " << iend <<
"): " << mReco[ibeg].ir.orbit <<
"." << mReco[ibeg].ir.bc <<
" - " << mReco[iend].ir.orbit <<
"." << mReco[iend].ir.bc;
1175 int nbun = iend - ibeg + 1;
1177 int shift = mRopt->
tsh[itdc];
1178 int thr = mRopt->
tth[itdc];
1180 int is1 = 0, is2 = 1;
1182#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1186 int it1 = 0, it2 = 0, ib1 = -1, ib2 = -1;
1189 isfired = isfired << 1;
1190#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1191 for (
int i = 2;
i > 0;
i--) {
1201 auto ref_m = mReco[b1].ref[
TDCSignal[itdc]];
1202 auto ref_s = mReco[b2].ref[
TDCSignal[itdc]];
1206 LOG(
error) << __func__ <<
" @ " << __LINE__ <<
" Missing information for bunch crossing " << mReco[b1].ir.orbit <<
"." << mReco[b1].ir.bc <<
" tdc = " << itdc <<
" sig = " <<
TDCSignal[itdc];
1209 LOG(
error) << __func__ <<
" @ " << __LINE__ <<
" Missing information for bunch crossing " << mReco[b2].ir.orbit <<
"." << mReco[b2].ir.bc <<
" tdc = " << itdc <<
" sig = " <<
TDCSignal[itdc];
1214 auto bcd = mReco[b2].ir.differenceInBC(mReco[b1].
ir);
1215 if (bcd != 0 && bcd != 1) {
1216 LOG(
error) << __func__ <<
" @ " << __LINE__ <<
" Large bunch crossing difference " << mReco[b1].ir.orbit <<
"." << mReco[b1].ir.bc <<
" followed by " << mReco[b2].ir.orbit <<
"." << mReco[b2].ir.bc;
1219 int diff = mChData[ref_m].data[
s1] - mChData[ref_s].data[s2];
1221#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1222 m[0] = mChData[ref_m].data[
s1];
1223 s[0] = mChData[ref_s].data[s2];
1226 isfired = isfired | 0x1;
1227 if ((isfired & mTriggerCondition) == mTriggerCondition) {
1230 mReco[b2].fired[itdc] |= mMask[s2];
1231#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1232 if (mTriggerCondition == 0x7) {
1233 printf(
"0x7 TDC %d[%s] Fired @ %u.%u.s%02u (%5d-%5d)=%5d>%2d && (%5d-%5d)=%5d>%2d && (s%02d:%-5d-s%02d:%-5d)=%5d>%2d\n",
1235 m[2],
s[2], (
m[2] -
s[2]), thr,
1236 m[1],
s[1], (
m[1] -
s[1]), thr,
1237 s1,
m[0], s2,
s[0], diff, thr);
1238 }
else if (mTriggerCondition == 0x3) {
1239 printf(
"0x3 TDC %d[%s] Fired @ %u.%u.s%02u (%5d-%5d)=%5d>%2d && (s%02d:%-5d-s%02d:(%-5d))=%5d>%2d\n",
1241 m[1],
s[1], (
m[1] -
s[1]), thr,
1242 s1,
m[0], s2,
s[0], diff, thr);
1243 }
else if (mTriggerCondition == 0x1) {
1244 printf(
"0x1 TDC %d[%s] Fired @ %u.%u.s%02u (%d-(%d))=%d>%d && (%d-(%d))=%d>%d && (s%d:%d-s%d:(%d))=%d>%d\n",
1246 s1,
m[0], s2,
s[0], diff, thr);
1261 return interpolate(itdc, ibeg, iend);
1264int DigiReco::processTriggerExtended(
int itdc,
int ibeg,
int iend)
1267#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1268 LOG(info) << __func__ <<
"(itdc=" << itdc <<
"[" <<
ChannelNames[isig] <<
"], " << ibeg <<
", " << iend <<
"): " << mReco[ibeg].ir.orbit <<
"." << mReco[ibeg].ir.bc <<
" - " << mReco[iend].ir.orbit <<
"." << mReco[iend].ir.bc;
1272 updateOffsets(ibeg);
1273 if (mSource[isig] ==
PedND) {
1278 return processTrigger(itdc, ibeg, iend);
1281 int nbun = iend - ibeg + 1;
1283 int shift = mRopt->
tsh[itdc];
1284 int thr = mRopt->
tth[itdc];
1286 int is1 = -shift, is2 = 0;
1288#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1293 int it1 = 0, it2 = 0, ib1 = -1, ib2 = -1;
1296 isfired = isfired << 1;
1297#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1298 for (
int i = 2;
i > 0;
i--) {
1307 auto ref_s = mReco[b2].ref[isig];
1311 LOG(
error) << __func__ <<
" @ " << __LINE__ <<
" Missing information for bunch crossing " << mReco[b2].ir.orbit <<
"." << mReco[b2].ir.bc <<
" sig = " << isig;
1314 diff = mOffset[isig] - mChData[ref_s].data[s2];
1315#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1316 m[0] = mOffset[isig];
1317 s[0] = mChData[ref_s].data[s2];
1321 auto ref_m = mReco[b1].ref[
TDCSignal[itdc]];
1324 LOG(
error) << __func__ <<
" @ " << __LINE__ <<
" Missing information for bunch crossing " << mReco[b1].ir.orbit <<
"." << mReco[b1].ir.bc <<
" tdc = " << itdc <<
" sig = " <<
TDCSignal[itdc];
1328 auto bcd = mReco[b2].ir.differenceInBC(mReco[b1].
ir);
1329 if (bcd != 0 && bcd != 1) {
1330 LOG(
error) << __func__ <<
": large bunch crossing difference " << mReco[b1].ir.orbit <<
"." << mReco[b1].ir.bc <<
" followed by " << mReco[b2].ir.orbit <<
"." << mReco[b2].ir.bc;
1333 diff = mChData[ref_m].data[
s1] - mChData[ref_s].data[s2];
1334#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1335 m[0] = mChData[ref_m].data[
s1];
1336 s[0] = mChData[ref_s].data[s2];
1340 isfired = isfired | 0x1;
1342 if ((isfired & mTriggerCondition) == mTriggerCondition) {
1345 mReco[b2].fired[itdc] |= mMask[s2];
1346#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1347 if (mTriggerCondition == 0x7) {
1348 printf(
"0x7E TDC %d[%s] Fired @ %u.%u.s%02u (%5d-%5d)=%5d>%2d && (%5d-%5d)=%5d>%5d && (s%02d:%-5d-s%02d:%-5d)=%-5d>%2d\n",
1350 m[2],
s[2], (
m[2] -
s[2]), thr,
1351 m[1],
s[1], (
m[1] -
s[1]), thr,
1352 s1,
m[0], s2,
s[0], diff, thr);
1353 }
else if (mTriggerCondition == 0x3) {
1354 printf(
"0x3E TDC %d[%s] Fired @ %u.%u.s%02u (%5d-%5d)=%5d>%2d && (s%02d:%-5d-s%02d:(%-5d))=%-5d>%2d\n",
1356 m[1],
s[1], (
m[1] -
s[1]), thr,
1357 s1,
m[0], s2,
s[0], diff, thr);
1358 }
else if (mTriggerCondition == 0x1) {
1359 printf(
"0x1E TDC %d[%s] Fired @ %u.%u.s%02u (%5d-(%5d))=%5d>%2d && (%5d-(%5d))=%5d>%2d && (s%d:%5d-s%d:(%5d))=%5d>%2d\n",
1361 s1,
m[0], s2,
s[0], diff, thr);
1374 return interpolate(itdc, ibeg, iend);
1381 if (
i >= mNtot ||
i < 0) {
1382 LOG(
error) <<
"Error addressing isig=" << isig <<
" i=" <<
i <<
" mNtot=" << mNtot;
1384 return std::numeric_limits<float>::infinity();
1389 return mFirstSample;
1390 }
else if (
i >= mIlast) {
1395 int ibun = ibeg +
i / nsbun;
1404 LOG(
error) <<
"ib=" << ib <<
" ibun=" << ibun;
1406 return std::numeric_limits<float>::infinity();
1408 return mReco[ibun].data[isig][ip];
1415 for (
int is =
TSN - im, ii = ip -
TSL + 1; is <
NTS; is +=
TSN, ii++) {
1422 yy = mReco[ib].data[isig][ip];
1438void DigiReco::setPoint(
int isig,
int ibeg,
int iend,
int i)
1442 if (!mFullInterpolation) {
1443 LOG(fatal) << __func__ <<
" call with mFullInterpolation = " << mFullInterpolation;
1447 if (
i >= mNtot ||
i < 0) {
1448 LOG(
error) <<
"Error addressing signal isig=" << isig <<
" i=" <<
i <<
" mNtot=" << mNtot;
1455 mReco[ibeg].inter[isig][
i] = mFirstSample;
1456 }
else if (
i >= mIlast) {
1458 int isam =
i % nsbun;
1459 mReco[iend].inter[isig][isam] = mLastSample;
1462 int ibun = ibeg +
i / nsbun;
1463 int isam =
i % nsbun;
1464 mReco[ibun].inter[isig][isam] = getPoint(isig, ibeg, iend,
i);
1468int DigiReco::fullInterpolation(
int isig,
int ibeg,
int iend)
1473#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1474 LOG(info) << __func__ <<
"(isig=" << isig <<
"[" <<
ChannelNames[isig] <<
"], " << ibeg <<
", " << iend <<
"): " << mReco[ibeg].ir.orbit <<
"." << mReco[ibeg].ir.bc <<
" - " << mReco[iend].ir.orbit <<
"." << mReco[iend].ir.bc;
1483 mNbun = iend - ibeg + 1;
1485 mNtot = mNsam *
TSN;
1487 mIlast = mNtot -
TSNH;
1491 for (
int ibun = ibeg; ibun <= iend; ibun++) {
1492 auto ref = mReco[ibun].ref[isig];
1494 LOG(
error) << __func__ <<
" @ " << __LINE__ <<
" Missing information for bunch crossing " << mReco[ibun].ir.orbit <<
"." << mReco[ibun].ir.bc <<
" sig = " << isig;
1499 mFirstSample = mReco[ibeg].data[isig][0];
1500 mLastSample = mReco[iend].data[isig][MaxTimeBin];
1503 for (
int ibun = ibeg; ibun <= iend; ibun++) {
1504 mReco[ibun].allocate(isig);
1506 for (
int i = 0;
i < mNtot;
i++) {
1507 setPoint(isig, ibeg, iend,
i);
1515int DigiReco::interpolate(
int itdc,
int ibeg,
int iend)
1520#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1521 LOG(info) << __func__ <<
"(itdc=" << itdc <<
"[" <<
ChannelNames[isig] <<
"], " << ibeg <<
", " << iend <<
"): " << mReco[ibeg].ir.orbit <<
"." << mReco[ibeg].ir.bc <<
" - " << mReco[iend].ir.orbit <<
"." << mReco[iend].ir.bc;
1531 mNbun = iend - ibeg + 1;
1533 mNtot = mNsam *
TSN;
1535 mIlast = mNtot -
TSNH;
1537 constexpr int nsp = 5;
1541 for (
int ibun = ibeg; ibun <= iend; ibun++) {
1542 auto ref = mReco[ibun].ref[isig];
1544 LOG(
error) << __func__ <<
" @ " << __LINE__ <<
" Missing information for bunch crossing " << mReco[ibun].ir.orbit <<
"." << mReco[ibun].ir.bc <<
" sig = " << isig;
1554 mFirstSample = mReco[ibeg].data[isig][0];
1555 mLastSample = mReco[iend].data[isig][MaxTimeBin];
1559 if (mFullInterpolation) {
1560 for (
int ibun = ibeg; ibun <= iend; ibun++) {
1561 mReco[ibun].allocate(isig);
1563 for (
int i = 0;
i < mNtot;
i++) {
1564 setPoint(isig, ibeg, iend,
i);
1573 int ip_old = -1, ip_cur = -1, ib_cur = -1;
1574 bool is_searchable =
false;
1575 bool was_searchable =
false;
1576 int ib[nsp] = {-1, -1, -1, -1, -1};
1577 int ip[nsp] = {-1, -1, -1, -1, -1};
1580 for (
int i = 0;
i < mNint;
i += mInterpolationStep) {
1581 int isam =
i +
TSNH;
1585 ip_cur = isam /
TSN;
1587 if (ip_cur != ip_old) {
1589 for (
int j = 0;
j < 5;
j++) {
1600 }
else if (ip[2] == 0) {
1609 }
else if (ip[1] == 0) {
1615 if (ip[2] < MaxTimeBin) {
1618 }
else if (ip[2] == MaxTimeBin) {
1624 if (ip[3] < MaxTimeBin) {
1627 }
else if (ip[3] == MaxTimeBin) {
1634 was_searchable = is_searchable;
1638 for (
int j = 0;
j < 5;
j++) {
1639 if (ib[
j] >= 0 && (mReco[ib[
j]].fired[itdc] & mMask[ip[
j]]) > 0) {
1640 triggered |= (0x1 <<
j);
1667 if (triggered != 0) {
1668 for (
int j = 0;
j < 14;
j++) {
1669 if (triggered == accept[
j]) {
1685 if (was_searchable && !is_searchable) {
1687 if (mInterpolationStep > 1) {
1689 int sbeg = (isam_amp -
TSNH);
1690 int send = (isam_amp +
TSNH);
1695 if (send > (mNint +
TSNH)) {
1696 send = mNint +
TSNH;
1702 for (
int spos = sbeg; spos < send; spos++) {
1713 int ibun = ibeg + isam_amp / nsbun;
1714 updateOffsets(ibun);
1719 if (mSource[isig] !=
PedND) {
1720 amp = mOffset[isig] - amp;
1723 amp = std::numeric_limits<float>::infinity();
1725 int tdc = isam_amp % nsbun;
1726 assignTDC(ibun, ibeg, iend, itdc, tdc, amp);
1728 amp = std::numeric_limits<float>::infinity();
1732 if (is_searchable) {
1733 int mysam = isam % nsbun;
1735 if (mFullInterpolation) {
1737 myval = mReco[ib_cur].inter[isig][mysam];
1740 myval = getPoint(isig, ibeg, iend, isam);
1754 if (is_searchable) {
1757 if (mInterpolationStep > 1) {
1759 int sbeg = (isam_amp -
TSNH);
1760 int send = (isam_amp +
TSNH);
1765 if (send > (mNint +
TSNH)) {
1766 send = mNint +
TSNH;
1772 for (
int spos = sbeg; spos < send; spos++) {
1783 int ibun = ibeg + isam_amp / nsbun;
1784 updateOffsets(ibun);
1785 if (mSource[isig] !=
PedND) {
1786 amp = mOffset[isig] - amp;
1789 amp = std::numeric_limits<float>::infinity();
1791 int tdc = isam_amp % nsbun;
1792 assignTDC(ibun, ibeg, iend, itdc, tdc, amp);
1802void DigiReco::assignTDC(
int ibun,
int ibeg,
int iend,
int itdc,
int tdc,
float amp)
1805 constexpr int tdc_max = nsbun / 2;
1806 constexpr int tdc_min = -tdc_max;
1808 auto&
rec = mReco[ibun];
1812 rec.isBeg[itdc] =
true;
1815 rec.isEnd[itdc] =
true;
1823 float TDCValCorr = 0, TDCAmpCorr = 0;
1824 if (mCorrSignal ==
false || correctTDCSignal(itdc, tdc, amp, TDCValCorr, TDCAmpCorr,
rec.isBeg[itdc],
rec.isEnd[itdc]) != 0) {
1828 TDCVal = TDCValCorr;
1830 if (!
rec.tdcPedMissing[isig]) {
1831 TDCAmp = TDCAmpCorr;
1838 TDCVal = TDCVal - tdc_shift[itdc];
1839 if (!
rec.tdcPedMissing[isig]) {
1841 TDCAmp = (TDCAmp - tdc_offset[itdc]) * tdc_calib[itdc];
1845 rec.TDCVal[itdc].push_back(TDCVal);
1846 rec.TDCAmp[itdc].push_back(TDCAmp);
1847 int& ihit = mReco[ibun].ntdc[itdc];
1848#ifdef O2_ZDC_TDC_C_ARRAY
1850 rec.tdcVal[itdc][ihit] = TDCVal;
1851 rec.tdcAmp[itdc][ihit] = TDCAmp;
1853 LOG(
error) <<
rec.ir.orbit <<
"." <<
rec.ir.bc <<
" ibun=" << ibun <<
" itdc=" << itdc <<
" tdc=" << tdc <<
" TDCVal=" << TDCVal *
o2::zdc::FTDCVal <<
" TDCAmp=" << TDCAmp <<
" OVERFLOW";
1857 if (mSource[isig] ==
PedOr) {
1858 rec.tdcPedOr[isig] =
true;
1859 }
else if (mSource[isig] ==
PedQC) {
1860 rec.tdcPedQC[isig] =
true;
1861 }
else if (mSource[isig] ==
PedEv) {
1863 rec.tdcPedEv[isig] =
true;
1865 rec.tdcPedMissing[isig] =
true;
1867#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1868 LOG(info) << __func__ <<
" itdc=" << itdc <<
" " <<
ChannelNames[isig] <<
" @ ibun=" << ibun <<
" " << mReco[ibun].ir.orbit <<
"." << mReco[ibun].ir.bc <<
" "
1869 <<
" tdc=" << tdc <<
" -> " << TDCValCorr <<
" shift=" << tdc_shift[itdc] <<
" -> TDCVal=" << TDCVal <<
"=" << TDCVal *
o2::zdc::FTDCVal
1870 <<
" mSource[" << isig <<
"] = " << unsigned(mSource[isig]) <<
" = " << mOffset[isig]
1871 <<
" amp=" << amp <<
" -> " << TDCAmpCorr <<
" calib=" << tdc_calib[itdc] <<
" offset=" << tdc_offset[itdc] <<
" -> TDCAmp=" << TDCAmp
1872 << (ibun == ibeg ?
" B" :
"") << (ibun == iend ?
" E" :
"");
1873 mAssignedTDC[itdc]++;
1878void DigiReco::findSignals(
int ibeg,
int iend)
1881#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1882 LOG(info) << __func__ <<
"(" << ibeg <<
", " << iend <<
"): " << mReco[ibeg].ir.orbit <<
"." << mReco[ibeg].ir.bc <<
" - " << mReco[iend].ir.orbit <<
"." << mReco[iend].ir.bc;
1885 for (
int ibun = ibeg; ibun <= iend; ibun++) {
1886 updateOffsets(ibun);
1887 auto&
rec = mReco[ibun];
1889#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1891 if (
rec.fired[itdc] != 0x0) {
1895 printf(
"%d",
rec.fired[itdc] & mMask[isam] ? 1 : 0);
1899 rec.pattern[itdc] = 0;
1901#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1903 printf(
" %d TDC A=%5.0f @ T=%5.0f",
i,
rec.TDCAmp[itdc][
i],
rec.TDCVal[itdc][
i]);
1908 rec.pattern[itdc] = 1;
1910#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1911 if (
rec.pattern[itdc] == 1) {
1918#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1925#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
1926 printf(
"%d %u.%-4u TDC PATTERN: ", ibun, mReco[ibun].
ir.
orbit, mReco[ibun].ir.bc);
1928 printf(
"%d",
rec.pattern[itdc]);
1944 rec.chfired[ich] =
true;
1949 rec.chfired[ich] =
true;
1958 rec.chfired[ich] =
true;
1963 rec.chfired[ich] =
true;
1970 printf(
"%d %u.%-4u TDC FIRED ", ibun,
rec.ir.orbit,
rec.ir.bc);
1971 printf(
"ZNA:%d%d%d%d%d%d ZPA:%d%d%d%d%d%d ZEM:%d%d ZNC:%d%d%d%d%d%d ZPC:%d%d%d%d%d%d\n",
1982void DigiReco::correctTDCPile()
2007#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
2008 LOG(info) <<
"________________________________________________________________________________";
2009 LOG(info) << __func__;
2018 std::deque<DigiRecoTDC> tdc;
2019 for (
int ibc = 0; ibc < mNBC; ibc++) {
2021 auto rec = &mReco[ibc];
2024 int ntdc[
NBCAn] = {0};
2025 for (
auto it = tdc.begin(); it != tdc.end(); ++it) {
2026 auto bcd = (
rec->ir).differenceInBC((*it).ir);
2030 }
else if (bcd > 0) {
2034 if (
rec->ntdc[itdc] > 1) {
2039 for (
int ihit = 0; ihit <
rec->ntdc[itdc]; ihit++) {
2040 tdc.emplace_back(
rec->TDCVal[itdc][ihit],
rec->TDCAmp[itdc][ihit],
rec->ir);
2043 }
else if (
rec->ntdc[itdc] == 1) {
2045 if (tdc.size() > 0) {
2046 if (mCorrBackground) {
2047 correctTDCBackground(ibc, itdc, tdc);
2050 std::deque<DigiRecoTDC>::reverse_iterator rit = tdc.rbegin();
2052 for (rit = tdc.rbegin(); rit != tdc.rend(); ++rit) {
2053 auto bcd = (
rec->ir).differenceInBC((*rit).ir);
2055 if (bcd > 0 && bcd <=
NBCAn) {
2056 if (ntdc[bcd - 1] > 0) {
2060 }
else if (bcd == 2) {
2062 }
else if (bcd == 3) {
2071 for (
int ihit = 0; ihit <
rec->ntdc[itdc]; ihit++) {
2072 tdc.emplace_back(
rec->TDCVal[itdc][ihit],
rec->TDCAmp[itdc][ihit],
rec->ir);
2075#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
2094int DigiReco::correctTDCSignal(
int itdc, int16_t TDCVal,
float TDCAmp,
float& fTDCVal,
float& fTDCAmp,
bool isbeg,
bool isend)
2100 constexpr int TDCMax = TDCRange -
TSNH - 1;
2106 if (mTDCCorr ==
nullptr) {
2107#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
2108 printf(
"%21s itdc=%d TDC=%d AMP=%d MISSING mTDCCorr\n", __func__, itdc, TDCVal, TDCAmp);
2113 if (isbeg ==
false && isend ==
false) {
2115 fTDCAmp = TDCAmp / mTDCCorr->
mAFMidC[itdc][0];
2116 fTDCVal = TDCVal - mTDCCorr->
mTSMidC[itdc][0];
2117 }
else if (isbeg ==
true) {
2121 if (TDCVal >
TSNH && TDCVal < p0) {
2122 auto diff = TDCVal -
p0;
2125 fTDCVal = TDCVal - (
p1 +
p2 * diff +
p3 * diff * diff);
2127 fTDCVal = TDCVal -
p1;
2133 if (TDCVal >
TSNH && TDCVal < p0) {
2134 auto diff = TDCVal -
p0;
2137 fTDCAmp = TDCAmp / (
p1 +
p2 * diff +
p3 * diff * diff);
2139 fTDCAmp = TDCAmp /
p1;
2142 }
else if (isend ==
true) {
2146 if (TDCVal > p0 && TDCVal < TDCMax) {
2147 auto diff = TDCVal -
p0;
2150 fTDCVal = TDCVal - (
p1 +
p2 * diff +
p3 * diff * diff);
2152 fTDCVal = TDCVal -
p1;
2158 if (TDCVal > p0 && TDCVal < TDCMax) {
2159 auto diff = TDCVal -
p0;
2162 fTDCAmp = TDCAmp / (
p1 +
p2 * diff +
p3 * diff * diff);
2164 fTDCAmp = TDCAmp /
p1;
2168#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
2169 printf(
"%21s itdc=%d TDC=%d AMP=%d LONELY BUNCH\n", __func__, itdc, TDCVal, TDCAmp);
2176int DigiReco::correctTDCBackground(
int ibc,
int itdc, std::deque<DigiRecoTDC>& tdc)
2179 constexpr int BucketS = TDCRange /
NBucket;
2180 constexpr int BucketSH = BucketS / 2;
2181 auto rec = &mReco[ibc];
2185 float TDCValUnc =
rec->TDCVal[itdc][0];
2186 float TDCAmpUnc =
rec->TDCAmp[itdc][0];
2187#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
2188 auto TDCValUncBck =
rec->TDCVal[itdc][0];
2189 auto TDCAmpUncBck =
rec->TDCAmp[itdc][0];
2191 float TDCValBest = TDCValUnc;
2192 float TDCAmpBest = TDCAmpUnc;
2193 int TDCSigBest = -1;
2194 float dtime = std::numeric_limits<float>::infinity();
2196 for (
int ibuks = 0; ibuks <
NBucket; ibuks++) {
2197 std::deque<DigiRecoTDC>::reverse_iterator rit = tdc.rbegin();
2202 for (rit = tdc.rbegin(); rit != tdc.rend(); ++rit) {
2203 auto bcd = (
rec->ir).differenceInBC((*rit).ir);
2204 if (bcd > 0 && bcd <=
NBCAn) {
2206 if (mTDCCorr ==
nullptr) {
2208 rec->tdcPileM1E[isig] =
true;
2209 }
else if (bcd == 2) {
2210 rec->tdcPileM2E[isig] =
true;
2211 }
else if (bcd == 3) {
2212 rec->tdcPileM3E[isig] =
true;
2215 int16_t TDCBkgVal = (*rit).val;
2216 int16_t TDCBkgAmp = (*rit).amp;
2218 int arg1 = TDCBkgVal + BucketSH;
2219 int q1 = arg1 / BucketS;
2220 int r1 = arg1 % BucketS;
2234 auto p0 = mTDCCorr->
mAmpCorr[itdc][ibun][ibukb][ibuks][0];
2235 auto p1 = mTDCCorr->
mAmpCorr[itdc][ibun][ibukb][ibuks][1];
2236 auto p2 = mTDCCorr->
mAmpCorr[itdc][ibun][ibukb][ibuks][2];
2237#ifdef O2_ZDC_DEBUG_CORR
2238 printf(
"%+e,%+e,%+e, // as%d_bc%+d_bk%d_sn%d\n", p0,
p1,
p2, itdc, -bcd, ibukb, ibuks);
2241 if (std::isnan(p0) || std::isnan(
p1) || std::isnan(
p2)) {
2243 rec->tdcPileM1E[isig] =
true;
2244 }
else if (bcd == 2) {
2245 rec->tdcPileM2E[isig] =
true;
2246 }
else if (bcd == 3) {
2247 rec->tdcPileM3E[isig] =
true;
2253 sum[2] +=
p2 * TDCBkgAmp;
2258 if (
rec->tdcPileM1C[isig]) {
2259 rec->tdcPileM1E[isig] =
true;
2261 rec->tdcPileM1C[isig] =
true;
2263 }
else if (bcd == 2) {
2264 if (
rec->tdcPileM2C[isig]) {
2265 rec->tdcPileM2E[isig] =
true;
2267 rec->tdcPileM2C[isig] =
true;
2269 }
else if (bcd == 3) {
2270 if (
rec->tdcPileM3C[isig]) {
2271 rec->tdcPileM3E[isig] =
true;
2273 rec->tdcPileM3C[isig] =
true;
2281 if (mTDCCorr ==
nullptr) {
2286 float TDCAmpUpd = (TDCAmpUnc -
sum[0] -
sum[2]) / (1. -
float(nbkg) +
sum[1]);
2289 for (rit = tdc.rbegin(); rit != tdc.rend(); ++rit) {
2290 auto bcd = (
rec->ir).differenceInBC((*rit).ir);
2291 if (bcd > 0 && bcd <=
NBCAn) {
2292 int16_t TDCBkgVal = (*rit).val;
2293 int16_t TDCBkgAmp = (*rit).amp;
2295 int arg1 = TDCBkgVal + BucketSH;
2296 int q1 = arg1 / BucketS;
2297 int r1 = arg1 % BucketS;
2311 auto p0 = mTDCCorr->
mTDCCorr[itdc][ibun][ibukb][ibuks][0];
2312 auto p1 = mTDCCorr->
mTDCCorr[itdc][ibun][ibukb][ibuks][1];
2313 auto p2 = mTDCCorr->
mTDCCorr[itdc][ibun][ibukb][ibuks][2];
2314#ifdef O2_ZDC_DEBUG_CORR
2315 printf(
"%+e,%+e,%+e, // ts%d_bc%d_bk%d_sn%d\n", p0,
p1,
p2, itdc, -bcd, ibukb, ibuks);
2318 if (std::isnan(p0) || std::isnan(
p1)) {
2320 rec->tdcPileM1E[isig] =
true;
2321 }
else if (bcd == 2) {
2322 rec->tdcPileM2E[isig] =
true;
2323 }
else if (bcd == 3) {
2324 rec->tdcPileM3E[isig] =
true;
2327 tshift +=
p0 +
p1 / (TDCAmpUpd / TDCBkgAmp);
2328#ifdef O2_ZDC_DEBUG_CORR
2329 printf(
"ibuk = b.%d s.%d = %8.2f ts=%8.2f\n", ibukb, ibuks, TDCAmpUpd, TDCBkgAmp, tshift);
2335 float TDCValUpd = TDCValUnc - tshift;
2336 float TDCBucket = (ibuks -
NBKZero) * BucketS;
2340 float mydtime = std::min(std::abs(TDCBucket - TDCValUpd), std::min(std::abs(TDCBucket - TDCValUpd - TDCRange), std::abs(TDCBucket - TDCValUpd + TDCRange)));
2341#ifdef O2_ZDC_DEBUG_CORR
2342 printf(
"ibuks = %d = %8.2f AS=%8.2f ts=%8.2f TDC %8.2f -> %8.2f delta=%8.2f\n", ibuks, TDCBucket, TDCAmpUpd, tshift, TDCValUnc, TDCValUpd, mydtime);
2344 if (mydtime < dtime) {
2346 TDCValBest = TDCValUpd;
2347 TDCAmpBest = TDCAmpUpd;
2352 rec->TDCVal[itdc][0] = TDCValBest;
2353 rec->TDCAmp[itdc][0] = TDCAmpBest;
2354#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG
2355 if (
rec->TDCVal[itdc][0] != TDCValUnc ||
rec->TDCAmp[itdc][0] != TDCAmpUnc) {
2356 printf(
"%21s ibc=%d itdc=%d sn = %d", __func__, ibc, itdc, TDCSigBest);
2357 printf(
" TDC=%f -> %f", TDCValUncBck,
rec->TDCVal[itdc][0]);
2358 printf(
" AMP=%f -> %f\n", TDCAmpUncBck,
rec->TDCAmp[itdc][0]);
unsigned short int uint16_t
std::vector< double > sum
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder int32_t
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc true
configStandalone Reconstruction rec_tpc float
constexpr int p1()
constexpr to accelerate the coordinates changing
char error[CURL_ERROR_SIZE]
ZDC reconstruction parameters.
static const ZDCSimParam & Instance()
void prepareInterpolation()
int process(const gsl::span< const o2::zdc::OrbitData > &orbitdata, const gsl::span< const o2::zdc::BCData > &bcdata, const gsl::span< const o2::zdc::ChannelData > &chdata)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
struct o2::upgrades_utils::@482 zdc
structure to keep FT0 information
constexpr int DummyIntRange
const int TDCSignal[NTDCChannels]
constexpr int16_t Int16MaxVal
constexpr std::array< int, 17 > ChTowerCalib
float O2_ZDC_DIGIRECO_FLT
constexpr int NTimeBinsPerBC
constexpr uint32_t ZDCRefInitVal
constexpr int NChPerModule
constexpr std::array< int, 10 > ChEnergyCalib
constexpr int NTDCChannels
const int SignalTDC[NChannels]
constexpr int MaxTDCValues
constexpr std::string_view ChannelNames[]
constexpr std::array< int, NChannels > CaloCommonPM
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void print(bool printall=true) const
float getCalib(uint32_t ich) const
uint32_t getTriggerMask() const
std::array< Module, MaxNModules > modules
int32_t beg_ped_int[NChannels]
float ped_thr_hi[NChannels]
int32_t beg_int[NChannels]
int32_t tsh[NTDCChannels]
int32_t tth[NTDCChannels]
int32_t end_int[NChannels]
float ped_thr_lo[NChannels]
int32_t end_ped_int[NChannels]
int tdc_search[NTDCChannels]
float energy_calib[NChannels]
float tdc_shift[NTDCChannels]
int32_t tmod[NTDCChannels]
float tdc_calib[NTDCChannels]
float ped_thr_hi[NChannels]
float adc_offset[NChannels]
float tdc_offset[NTDCChannels]
int32_t end_int[NChannels]
bool bitset[NTDCChannels]
float tdc_search[NTDCChannels]
int32_t tsh[NTDCChannels]
int32_t beg_int[NChannels]
float ped_thr_lo[NChannels]
int full_interpolation_min_length
int32_t tth[NTDCChannels]
int32_t end_ped_int[NChannels]
float tower_calib[NChannels]
int32_t tch[NTDCChannels]
int32_t beg_ped_int[NChannels]
float energy_calib[NChannels]
float adc_offset[NChannels]
std::array< std::array< std::array< std::array< std::array< float, NFParA >, NBucket >, NBucket >, NBCAn >, NTDCChannels > mAmpCorr
std::array< std::array< float, NParExtC >, NTDCChannels > mTSBegC
std::array< std::array< float, NParExtC >, NTDCChannels > mTSEndC
std::array< std::array< std::array< std::array< std::array< float, NFParT >, NBucket >, NBucket >, NBCAn >, NTDCChannels > mTDCCorr
std::array< std::array< float, NParMidC >, NTDCChannels > mAFMidC
std::array< std::array< float, NParExtC >, NTDCChannels > mAFEndC
std::array< std::array< float, NParMidC >, NTDCChannels > mTSMidC
std::array< std::array< float, NParExtC >, NTDCChannels > mAFBegC
float getOffset(uint32_t ich) const
float getFactor(uint32_t ich) const
float getShift(uint32_t ich) const
float tower_calib[NChannels]
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
std::vector< ChannelData > channels
uint64_t const void const *restrict const msg