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";
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++) {
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);
747 int32_t
sum = mChData[ref_c].data[is];
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--) {
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];
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;
1637 uint16_t triggered = 0x0000;
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);
1648 constexpr uint16_t accept[14] = {
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;
1722 LOGF(error,
"%u.%-4d Missing pedestal for TDC %d %s ", mBCData[ibun].
ir.
orbit, mBCData[ibun].ir.bc, itdc,
ChannelNames[
TDCSignal[itdc]]);
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;
1788 LOGF(error,
"%u.%-4d Missing pedestal for TDC %d %s ", mBCData[ibun].
ir.
orbit, mBCData[ibun].ir.bc, itdc,
ChannelNames[
TDCSignal[itdc]]);
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;
1900 for (int32_t
i = 0;
i <
rec.ntdc[itdc];
i++) {
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;
2233 int32_t ibun =
NBCAn - bcd;
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;
2310 int32_t ibun =
NBCAn - bcd;
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]);
const GPUTPCGMMerger::trackCluster & b1
constexpr int p1()
constexpr to accelerate the coordinates changing
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)
float sum(float s, o2::dcs::DataPointValue v)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
uint8_t itsSharedClusterMap uint8_t
constexpr int LHCMaxBunches
struct o2::upgrades_utils::@463 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