From 10fe8914fd052dd935de642c933e0452b1585e87 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Fri, 20 Sep 2024 14:27:01 +0200 Subject: [PATCH 01/19] Fixes + orthogonal regression --- .../ZDC/calib/include/ZDCCalib/InterCalib.h | 2 + Detectors/ZDC/calib/src/InterCalib.cxx | 75 ++++++++++--------- Detectors/ZDC/calib/src/InterCalibEPN.cxx | 16 ++-- 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/Detectors/ZDC/calib/include/ZDCCalib/InterCalib.h b/Detectors/ZDC/calib/include/ZDCCalib/InterCalib.h index d53d3ae1eec0f..6d625464c714b 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/InterCalib.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/InterCalib.h @@ -80,6 +80,8 @@ class InterCalib void setInterCalibConfig(const InterCalibConfig* param) { mInterCalibConfig = param; }; const InterCalibConfig* getInterCalibConfig() const { return mInterCalibConfig; }; + InterCalibData& getData() { return mData; }; + void setVerbosity(int v) { mVerbosity = v; } int getVerbosity() const { return mVerbosity; } diff --git a/Detectors/ZDC/calib/src/InterCalib.cxx b/Detectors/ZDC/calib/src/InterCalib.cxx index dc75b172a3aca..1e763f434ccf6 100644 --- a/Detectors/ZDC/calib/src/InterCalib.cxx +++ b/Detectors/ZDC/calib/src/InterCalib.cxx @@ -210,12 +210,12 @@ void InterCalib::assign(int ih, bool ismod) } else if (ih == 5) { nid = 1; id = id_5; - LOG(warn) << "InterCalib::assign unimplemented coefficient ih = " << ih; + LOG(warn) << "InterCalib::assign is not implemented for coefficient ih = " << ih; return; } else if (ih == 6) { nid = 1; id = id_6; - LOG(warn) << "InterCalib::assign unimplemented coefficient ih = " << ih; + LOG(warn) << "InterCalib::assign is not implemented for coefficient ih = " << ih; return; } else if (ih == 7 || ih == 8) { nid = 4; @@ -246,15 +246,23 @@ void InterCalib::assign(int ih, bool ismod) if (oldval > 0) { val = val * mPar[ih][iid + 1]; } - if (mVerbosity > DbgZero) { + if (mTowerParamUpd.modified[ich]) { + LOGF(warn, "%s OVERWRITING MODIFIED PARAMETER %8.6f", ChannelNames[ich].data(), mTowerParamUpd.getTowerCalib(ich)); + LOGF(info, "%s updated %8.6f -> %8.6f", ChannelNames[ich].data(), oldval, val); + } else if (mVerbosity > DbgZero) { LOGF(info, "%s updated %8.6f -> %8.6f", ChannelNames[ich].data(), oldval, val); } mTowerParamUpd.setTowerCalib(ich, val, true); } else { - if (mVerbosity > DbgZero) { - LOGF(info, "%s NOT CHANGED %8.6f", ChannelNames[ich].data(), oldval); + // Check if another fit has already modified the parameters + if (mTowerParamUpd.modified[ich]) { + LOGF(warn, "%s NOT OVERWRITING MODIFIED PARAMETER %8.6f", ChannelNames[ich].data(), mTowerParamUpd.getTowerCalib(ich)); + } else { + if (mVerbosity > DbgZero) { + LOGF(info, "%s NOT CHANGED %8.6f", ChannelNames[ich].data(), oldval); + } + mTowerParamUpd.setTowerCalib(ich, oldval, false); } - mTowerParamUpd.setTowerCalib(ich, oldval, false); } } } @@ -294,6 +302,10 @@ int InterCalib::process(const char* hname, int ic) ih = HidZNI; } else if (hn.EqualTo("hZPI")) { ih = HidZPI; + } else if (hn.EqualTo("hZPAX")) { + ih = HidZPAX; + } else if (hn.EqualTo("hZPCX")) { + ih = HidZPCX; } else { LOGF(error, "Not recognized histogram name: %s\n", hname); return -1; @@ -434,18 +446,19 @@ void InterCalib::add(int ih, o2::dataformats::FlatHisto2D& h2) void InterCalib::cumulate(int ih, double tc, double t1, double t2, double t3, double t4, double w = 1) { + constexpr double minfty = -std::numeric_limits::infinity(); if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->cutHigh[ih]) { return; } - double val[NPAR] = {0, 0, 0, 0, 0, 1}; - val[0] = tc; - val[1] = t1; - val[2] = t2; - val[3] = t3; - val[4] = t4; - for (int32_t i = 0; i < NPAR; i++) { - for (int32_t j = i; j < NPAR; j++) { - mData.mSum[ih][i][j] += val[i] * val[j] * w; + if ((ih == 7 || ih == 8) && (t1 < mInterCalibConfig->tower_cut_ZP || t2 < mInterCalibConfig->tower_cut_ZP || t3 < mInterCalibConfig->tower_cut_ZP || t4 < mInterCalibConfig->tower_cut_ZP)) { + return; + } + double val[NPAR] = {tc, t1, t2, t3, t4, 1}; + if (tc > minfty && t1 > minfty && t2 > minfty && t3 > minfty && t4 > minfty) { + for (int32_t i = 0; i < NPAR; i++) { + for (int32_t j = i; j < NPAR; j++) { + mData.mSum[ih][i][j] += val[i] * val[j] * w; + } } } // mData.mSum[ih][5][5] contains the number of analyzed events @@ -470,6 +483,7 @@ void InterCalib::fcn(int& npar, double* gin, double& chi, double* par, int iflag chi += (i == 0 ? par[i] : -par[i]) * (j == 0 ? par[j] : -par[j]) * mAdd[i][j]; } } + chi = chi / (1 + par[1]*par[1] + par[2]*par[2] + par[3]*par[3] + par[4]*par[4]); } int InterCalib::mini(int ih) @@ -498,15 +512,11 @@ int InterCalib::mini(int ih) // Calibration cvoefficient is forced to and step is forced to zero mMn[ih]->mnparm(0, "c0", 1., 0., 1., 1., ierflg); - // Special fit for proton calorimeters: fit least exposed towers with using previous - // fit of all towers + // Special fit for proton calorimeters: fit least exposed towers + // starting from parameters of previous fit to all towers // Tower 1 - if (ih == HidZPCX) { - mMn[ih]->mnparm(1, "c1", mPar[HidZPC][1], 0, l_bnd, u_bnd, ierflg); - } else { - mMn[ih]->mnparm(1, "c1", start, step, l_bnd, u_bnd, ierflg); - } + mMn[ih]->mnparm(1, "c1", start, step, l_bnd, u_bnd, ierflg); // Tower 2 // Only two ZEM calorimeters: equalize response @@ -518,20 +528,11 @@ int InterCalib::mini(int ih) step = 0; } - if (ih == HidZPCX) { - mMn[ih]->mnparm(2, "c2", mPar[HidZPC][2], 0, l_bnd, u_bnd, ierflg); - } else { - mMn[ih]->mnparm(2, "c2", start, step, l_bnd, u_bnd, ierflg); - } + mMn[ih]->mnparm(2, "c2", start, step, l_bnd, u_bnd, ierflg); // Towers 3 and 4 - if (ih == HidZPAX) { - mMn[ih]->mnparm(3, "c3", mPar[HidZPA][3], 0, l_bnd, u_bnd, ierflg); - mMn[ih]->mnparm(4, "c4", mPar[HidZPA][4], 0, l_bnd, u_bnd, ierflg); - } else { - mMn[ih]->mnparm(3, "c3", start, step, l_bnd, u_bnd, ierflg); - mMn[ih]->mnparm(4, "c4", start, step, l_bnd, u_bnd, ierflg); - } + mMn[ih]->mnparm(3, "c3", start, step, l_bnd, u_bnd, ierflg); + mMn[ih]->mnparm(4, "c4", start, step, l_bnd, u_bnd, ierflg); // Offset l_bnd = mInterCalibConfig->l_bnd_o[ih]; @@ -555,9 +556,11 @@ int InterCalib::mini(int ih) retry = true; LOG(warn) << "ih=" << ih << " par " << i << " too close to boundaries"; if (ih == 1 || ih == 7) { - mMn[ih]->mnparm(i, parn[i], mTowerParam->tower_calib[IdZPAC + i], 0, l_bnd, u_bnd, ierflg); + // mMn[ih]->mnparm(i, parn[i], mTowerParam->tower_calib[IdZPAC + i], 0, l_bnd, u_bnd, ierflg); + mMn[ih]->mnparm(i, parn[i], mInterCalibConfig->start[ih], 0, l_bnd, u_bnd, ierflg); } else if (ih == 3 || ih == 8) { - mMn[ih]->mnparm(i, parn[i], mTowerParam->tower_calib[IdZPCC + i], 0, l_bnd, u_bnd, ierflg); + // mMn[ih]->mnparm(i, parn[i], mTowerParam->tower_calib[IdZPCC + i], 0, l_bnd, u_bnd, ierflg); + mMn[ih]->mnparm(i, parn[i], mInterCalibConfig->start[ih], 0, l_bnd, u_bnd, ierflg); } else { LOG(fatal) << "ERROR on InterCalib minimization ih=" << ih; } diff --git a/Detectors/ZDC/calib/src/InterCalibEPN.cxx b/Detectors/ZDC/calib/src/InterCalibEPN.cxx index 3f17d256c042f..f0fab38192b4b 100644 --- a/Detectors/ZDC/calib/src/InterCalibEPN.cxx +++ b/Detectors/ZDC/calib/src/InterCalibEPN.cxx @@ -266,6 +266,7 @@ void InterCalibEPN::clear(int ih) void InterCalibEPN::cumulate(int ih, double tc, double t1, double t2, double t3, double t4, double w = 1) { + constexpr double minfty = -std::numeric_limits::infinity(); // printf("%s: ih=%d tc=%g t1=%g t2=%g t3=%g t4=%g w=%g\n",__func__,ih, tc, t1, t2, t3, t4, w); fflush(stdout); if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->cutHigh[ih]) { return; @@ -273,15 +274,12 @@ void InterCalibEPN::cumulate(int ih, double tc, double t1, double t2, double t3, if ((ih == 7 || ih == 8) && (t1 < mInterCalibConfig->tower_cut_ZP || t2 < mInterCalibConfig->tower_cut_ZP || t3 < mInterCalibConfig->tower_cut_ZP || t4 < mInterCalibConfig->tower_cut_ZP)) { return; } - double val[NPAR] = {0, 0, 0, 0, 0, 1}; - val[0] = tc; - val[1] = t1; - val[2] = t2; - val[3] = t3; - val[4] = t4; - for (int32_t i = 0; i < NPAR; i++) { - for (int32_t j = i; j < NPAR; j++) { - mData.mSum[ih][i][j] += val[i] * val[j] * w; + double val[NPAR] = {tc, t1, t2, t3, t4, 1}; + if (tc > minfty && t1 > minfty && t2 > minfty && t3 > minfty && t4 > minfty) { + for (int32_t i = 0; i < NPAR; i++) { + for (int32_t j = i; j < NPAR; j++) { + mData.mSum[ih][i][j] += val[i] * val[j] * w; + } } } // mData.mSum[ih][5][5] contains the number of analyzed events From e0e5809da9d0ed24496eefce4c3d2d7032b5960b Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Wed, 9 Oct 2024 23:03:29 +0200 Subject: [PATCH 02/19] Various fixes --- .../calib/include/ZDCCalib/InterCalibConfig.h | 12 +++++++---- Detectors/ZDC/calib/src/InterCalib.cxx | 21 +++++++++++++++---- Detectors/ZDC/calib/src/InterCalibConfig.cxx | 6 +++++- Detectors/ZDC/calib/src/InterCalibEPN.cxx | 21 +++++++++++++++---- .../include/ZDCWorkflow/DigitRecoSpec.h | 3 +-- .../include/ZDCWorkflow/RecoReaderSpec.h | 1 + .../include/ZDCWorkflow/RecoWorkflow.h | 3 +-- Detectors/ZDC/workflow/src/DigitRecoSpec.cxx | 6 ++---- Detectors/ZDC/workflow/src/RecoReaderSpec.cxx | 21 ++++++++++++++++--- Detectors/ZDC/workflow/src/RecoWorkflow.cxx | 3 +-- 10 files changed, 71 insertions(+), 26 deletions(-) diff --git a/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h b/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h index d9e729cd57f3f..74148b81e16aa 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h @@ -36,9 +36,13 @@ struct InterCalibConfig { // Meaningful values are in the range of tower x centers i.e. from // 2.8 to 19.6 If one puts less than 2.8 then the computation will be // the same as for ZPA/ZPC with no cuts - double xcut_ZPA = 6; - double xcut_ZPC = 6; - double tower_cut_ZP = 0; + double xcut_ZPA = 0; + double xcut_ZPC = 0; + double rms_cut_ZP = 0; // RMS of ZP centroid can go from 0 to 8.4 cm + double towerCutLow_ZPA[4] = { 0, 0, 0, 0}; // Applied to all ZP fits except ZPI + double towerCutLow_ZPC[4] = { 0, 0, 0, 0}; // Applied to all ZP fits except ZPI + double towerCutHigh_ZPA[4] = { std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity() }; // Applied to all ZP fits except ZPI + double towerCutHigh_ZPC[4] = { std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity() }; // Applied to all ZP fits except ZPI bool cross_check = false; int nb1[NH] = {0}; /// 1D histogram: number of bins @@ -87,7 +91,7 @@ struct InterCalibConfig { enabled[7] = c7; enabled[8] = c8; } - ClassDefNV(InterCalibConfig, 4); + ClassDefNV(InterCalibConfig, 5); }; } // namespace zdc } // namespace o2 diff --git a/Detectors/ZDC/calib/src/InterCalib.cxx b/Detectors/ZDC/calib/src/InterCalib.cxx index 1e763f434ccf6..1dff221bc2c22 100644 --- a/Detectors/ZDC/calib/src/InterCalib.cxx +++ b/Detectors/ZDC/calib/src/InterCalib.cxx @@ -450,8 +450,21 @@ void InterCalib::cumulate(int ih, double tc, double t1, double t2, double t3, do if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->cutHigh[ih]) { return; } - if ((ih == 7 || ih == 8) && (t1 < mInterCalibConfig->tower_cut_ZP || t2 < mInterCalibConfig->tower_cut_ZP || t3 < mInterCalibConfig->tower_cut_ZP || t4 < mInterCalibConfig->tower_cut_ZP)) { - return; + if ((ih == HidZPA || ih == HidZPAX)){ + if(t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[3]){ + return; + } + if(t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[3]){ + return; + } + } + if (ih == HidZPC || ih == HidZPCX) { + if(t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[3]){ + return; + } + if(t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[3]){ + return; + } } double val[NPAR] = {tc, t1, t2, t3, t4, 1}; if (tc > minfty && t1 > minfty && t2 > minfty && t3 > minfty && t4 > minfty) { @@ -483,7 +496,7 @@ void InterCalib::fcn(int& npar, double* gin, double& chi, double* par, int iflag chi += (i == 0 ? par[i] : -par[i]) * (j == 0 ? par[j] : -par[j]) * mAdd[i][j]; } } - chi = chi / (1 + par[1]*par[1] + par[2]*par[2] + par[3]*par[3] + par[4]*par[4]); + chi = chi / (1 + par[1] * par[1] + par[2] * par[2] + par[3] * par[3] + par[4] * par[4]); } int InterCalib::mini(int ih) @@ -552,7 +565,7 @@ int InterCalib::mini(int ih) l_bnd = mInterCalibConfig->l_bnd[ih]; u_bnd = mInterCalibConfig->u_bnd[ih]; for (int i = 1; i <= 4; i++) { - if (TMath::Abs(mPar[ih][i] - l_bnd) < 1e-3 || TMath::Abs(mPar[ih][i] - u_bnd) < 1e-3) { + if (TMath::Abs(mPar[ih][i] - l_bnd) < 1e-2 || TMath::Abs(mPar[ih][i] - u_bnd) < 1e-2) { retry = true; LOG(warn) << "ih=" << ih << " par " << i << " too close to boundaries"; if (ih == 1 || ih == 7) { diff --git a/Detectors/ZDC/calib/src/InterCalibConfig.cxx b/Detectors/ZDC/calib/src/InterCalibConfig.cxx index f70420eb6b67a..b65a060255be7 100644 --- a/Detectors/ZDC/calib/src/InterCalibConfig.cxx +++ b/Detectors/ZDC/calib/src/InterCalibConfig.cxx @@ -28,7 +28,11 @@ void InterCalibConfig::print() const } LOG(info) << "xcut_ZPA = " << xcut_ZPA; LOG(info) << "xcut_ZPC = " << xcut_ZPC; - LOG(info) << "tower_cut_ZP = " << tower_cut_ZP; + LOG(info) << "towerCutLow_ZPA = {" << towerCutLow_ZPA[0] << ", " << towerCutLow_ZPA[1] << ", " << towerCutLow_ZPA[2] << ", " << towerCutLow_ZPA[3] << "};"; + LOG(info) << "towerCutHigh_ZPA = {" << towerCutHigh_ZPA[0] << ", " << towerCutHigh_ZPA[1] << ", " << towerCutHigh_ZPA[2] << ", " << towerCutHigh_ZPA[3] << "};"; + LOG(info) << "towerCutLow_ZPC = {" << towerCutLow_ZPC[0] << ", " << towerCutLow_ZPC[1] << ", " << towerCutLow_ZPC[2] << ", " << towerCutLow_ZPC[3] << "};"; + LOG(info) << "towerCutHigh_ZPC = {" << towerCutHigh_ZPC[0] << ", " << towerCutHigh_ZPC[1] << ", " << towerCutHigh_ZPC[2] << ", " << towerCutHigh_ZPC[3] << "};"; + LOG(info) << "rms_cut_ZP = " << rms_cut_ZP; if (cross_check) { LOG(warn) << "THIS IS A CROSS CHECK CONFIGURATION (vs SUM)"; } diff --git a/Detectors/ZDC/calib/src/InterCalibEPN.cxx b/Detectors/ZDC/calib/src/InterCalibEPN.cxx index f0fab38192b4b..b85da2cdaa3c6 100644 --- a/Detectors/ZDC/calib/src/InterCalibEPN.cxx +++ b/Detectors/ZDC/calib/src/InterCalibEPN.cxx @@ -106,7 +106,7 @@ int InterCalibEPN::process(const gsl::span& RecBC, float x, rms; ev.centroidZPA(x, rms); cumulate(HidZPA, ev.EZDC(IdZPAC), ev.EZDC(IdZPA1), ev.EZDC(IdZPA2), ev.EZDC(IdZPA3), ev.EZDC(IdZPA4), 1.); - if (x < -(mInterCalibConfig->xcut_ZPA)) { + if (x < -(mInterCalibConfig->xcut_ZPA) && rms >= mInterCalibConfig->rms_cut_ZP ) { cumulate(HidZPAX, ev.EZDC(IdZPAC), ev.EZDC(IdZPA1), ev.EZDC(IdZPA2), ev.EZDC(IdZPA3), ev.EZDC(IdZPA4), 1.); } } @@ -117,7 +117,7 @@ int InterCalibEPN::process(const gsl::span& RecBC, float x, rms; ev.centroidZPC(x, rms); cumulate(HidZPC, ev.EZDC(IdZPCC), ev.EZDC(IdZPC1), ev.EZDC(IdZPC2), ev.EZDC(IdZPC3), ev.EZDC(IdZPC4), 1.); - if (x > (mInterCalibConfig->xcut_ZPC)) { + if (x > (mInterCalibConfig->xcut_ZPC) && rms >= mInterCalibConfig->rms_cut_ZP) { cumulate(HidZPCX, ev.EZDC(IdZPCC), ev.EZDC(IdZPC1), ev.EZDC(IdZPC2), ev.EZDC(IdZPC3), ev.EZDC(IdZPC4), 1.); } } @@ -271,8 +271,21 @@ void InterCalibEPN::cumulate(int ih, double tc, double t1, double t2, double t3, if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->cutHigh[ih]) { return; } - if ((ih == 7 || ih == 8) && (t1 < mInterCalibConfig->tower_cut_ZP || t2 < mInterCalibConfig->tower_cut_ZP || t3 < mInterCalibConfig->tower_cut_ZP || t4 < mInterCalibConfig->tower_cut_ZP)) { - return; + if ((ih == HidZPA || ih == HidZPAX)){ + if(t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[4]){ + return; + } + if(t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[4]){ + return; + } + } + if (ih == HidZPC || ih == HidZPCX) { + if(t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[4]){ + return; + } + if(t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[4]){ + return; + } } double val[NPAR] = {tc, t1, t2, t3, t4, 1}; if (tc > minfty && t1 > minfty && t2 > minfty && t3 > minfty && t4 > minfty) { diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitRecoSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitRecoSpec.h index 8141fdeb46dfe..1d7f6ccfbc50b 100644 --- a/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitRecoSpec.h +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitRecoSpec.h @@ -34,8 +34,7 @@ class DigitRecoSpec : public o2::framework::Task { public: DigitRecoSpec(); - DigitRecoSpec(const int verbosity, const bool debugOut, - const bool enableZDCTDCCorr, const bool enableZDCEnergyParam, const bool enableZDCTowerParam, const bool enableBaselineParam); + DigitRecoSpec(const int verbosity, const bool debugOut, const bool enableZDCTDCCorr, const bool enableZDCEnergyParam, const bool enableZDCTowerParam, const bool enableBaselineParam); ~DigitRecoSpec() override = default; void init(o2::framework::InitContext& ic) final; void updateTimeDependentParams(o2::framework::ProcessingContext& pc); diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h index ae2ed186cdf45..d81b7b6b199be 100644 --- a/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h @@ -33,6 +33,7 @@ class RecoReader : public framework::Task private: std::unique_ptr mTree; std::unique_ptr mFile; + bool mWaveformEnable = false; }; /// create a processor spec diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoWorkflow.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoWorkflow.h index a06e768377ad9..3df76af188c1b 100644 --- a/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoWorkflow.h +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoWorkflow.h @@ -20,8 +20,7 @@ namespace o2 { namespace zdc { -framework::WorkflowSpec getRecoWorkflow(const bool useMC, const bool disableRootInp, const bool disableRootOut, const int verbosity, const bool enableDebugOut, - const bool enableZDCTDCCorr, const bool enableZDCEnergyParam, const bool enableZDCTowerParam, const bool enableBaselineParam); +framework::WorkflowSpec getRecoWorkflow(const bool useMC, const bool disableRootInp, const bool disableRootOut, const int verbosity, const bool enableDebugOut, const bool enableZDCTDCCorr, const bool enableZDCEnergyParam, const bool enableZDCTowerParam, const bool enableBaselineParam); } // namespace zdc } // namespace o2 #endif diff --git a/Detectors/ZDC/workflow/src/DigitRecoSpec.cxx b/Detectors/ZDC/workflow/src/DigitRecoSpec.cxx index e9b63c5b49d5b..8f0ab82fa5b9b 100644 --- a/Detectors/ZDC/workflow/src/DigitRecoSpec.cxx +++ b/Detectors/ZDC/workflow/src/DigitRecoSpec.cxx @@ -275,12 +275,10 @@ void DigitRecoSpec::run(ProcessingContext& pc) void DigitRecoSpec::endOfStream(EndOfStreamContext& ec) { mWorker.eor(); - LOGF(info, "ZDC Reconstruction total timing: Cpu: %.3e Real: %.3e s in %d slots", - mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); + LOGF(info, "ZDC Reconstruction total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } -framework::DataProcessorSpec getDigitRecoSpec(const int verbosity = 0, const bool enableDebugOut = true, - const bool enableZDCTDCCorr = true, const bool enableZDCEnergyParam = true, const bool enableZDCTowerParam = true, const bool enableBaselineParam = true) +framework::DataProcessorSpec getDigitRecoSpec(const int verbosity = 0, const bool enableDebugOut = true, const bool enableZDCTDCCorr = true, const bool enableZDCEnergyParam = true, const bool enableZDCTowerParam = true, const bool enableBaselineParam = true) { std::vector inputs; inputs.emplace_back("trig", "ZDC", "DIGITSBC", 0, Lifetime::Timeframe); diff --git a/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx b/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx index ebea51c932c5c..f952eeadddeaf 100644 --- a/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx +++ b/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx @@ -22,6 +22,8 @@ #include "DataFormatsZDC/BCData.h" #include "DataFormatsZDC/ChannelData.h" #include "DataFormatsZDC/RecEvent.h" +#include "DataFormatsZDC/RecEvent.h" +#include "DataFormatsZDC/ZDCWaveform.h" #include "CommonUtils/NameConf.h" using namespace o2::framework; @@ -33,8 +35,8 @@ namespace zdc void RecoReader::init(InitContext& ic) { - auto filename = o2::utils::Str::concat_string(o2::utils::Str::rectifyDirectory(ic.options().get("input-dir")), - ic.options().get("zdc-reco-infile")); + auto filename = o2::utils::Str::concat_string(o2::utils::Str::rectifyDirectory(ic.options().get("input-dir")), ic.options().get("zdc-reco-infile")); + mWaveformEnable = ic.options().get("waveform-enable"); mFile.reset(TFile::Open(filename.c_str())); if (!mFile->IsOpen()) { LOG(error) << "Cannot open the " << filename.c_str() << " file !"; @@ -54,20 +56,29 @@ void RecoReader::run(ProcessingContext& pc) std::vector Energy, *EnergyPtr = &Energy; std::vector TDCData, *TDCDataPtr = &TDCData; std::vector Info, *InfoPtr = &Info; + std::vector WaveformData, *WaveformDataPtr = &WaveformData; mTree->SetBranchAddress("ZDCRecBC", &RecBCPtr); mTree->SetBranchAddress("ZDCRecE", &EnergyPtr); mTree->SetBranchAddress("ZDCRecTDC", &TDCDataPtr); mTree->SetBranchAddress("ZDCRecInfo", &InfoPtr); + if(mWaveformEnable){ + mTree->SetBranchAddress("ZDCWaveform", &WaveformPtr); + } auto ent = mTree->GetReadEntry() + 1; assert(ent < mTree->GetEntries()); // this should not happen mTree->GetEntry(ent); - LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos"; pc.outputs().snapshot(Output{"ZDC", "BCREC", 0}, RecBC); pc.outputs().snapshot(Output{"ZDC", "ENERGY", 0}, Energy); pc.outputs().snapshot(Output{"ZDC", "TDCDATA", 0}, TDCData); pc.outputs().snapshot(Output{"ZDC", "INFO", 0}, Info); + if(mWaveformEnable){ + LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos"; + pc.outputs().snapshot(Output{"ZDC", "WAVE", 0}, Waveform); + }else{ + LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos" << Wave.size() << " Waveform chunks"; + } if (mTree->GetReadEntry() + 1 >= mTree->GetEntries()) { pc.services().get().endOfStream(); pc.services().get().readyToQuit(QuitRequest::Me); @@ -81,6 +92,9 @@ DataProcessorSpec getRecoReaderSpec() outputs.emplace_back("ZDC", "ENERGY", 0, Lifetime::Timeframe); outputs.emplace_back("ZDC", "TDCDATA", 0, Lifetime::Timeframe); outputs.emplace_back("ZDC", "INFO", 0, Lifetime::Timeframe); + if(mWaveformEnable){ + outputs.emplace_back("ZDC", "WAVE", 0, Lifetime::Timeframe); + } return DataProcessorSpec{ "zdc-reco-reader", Inputs{}, @@ -88,6 +102,7 @@ DataProcessorSpec getRecoReaderSpec() AlgorithmSpec{adaptFromTask()}, Options{ {"zdc-reco-infile", VariantType::String, "zdcreco.root", {"Name of the input file"}}, + {"waveform-enable", VariantType::Bool, false, {"Read waveform data"}} {"input-dir", VariantType::String, "none", {"Input directory"}}}}; } diff --git a/Detectors/ZDC/workflow/src/RecoWorkflow.cxx b/Detectors/ZDC/workflow/src/RecoWorkflow.cxx index b93a86f6237b5..3004f045d8237 100644 --- a/Detectors/ZDC/workflow/src/RecoWorkflow.cxx +++ b/Detectors/ZDC/workflow/src/RecoWorkflow.cxx @@ -22,8 +22,7 @@ namespace o2 namespace zdc { -framework::WorkflowSpec getRecoWorkflow(const bool useMC, const bool disableRootInp, const bool disableRootOut, const int verbosity, const bool enableDebugOut, - const bool enableZDCTDCCorr, const bool enableZDCEnergyParam, const bool enableZDCTowerParam, const bool enableBaselineParam) +framework::WorkflowSpec getRecoWorkflow(const bool useMC, const bool disableRootInp, const bool disableRootOut, const int verbosity, const bool enableDebugOut, const bool enableZDCTDCCorr, const bool enableZDCEnergyParam, const bool enableZDCTowerParam, const bool enableBaselineParam) { framework::WorkflowSpec specs; if (!disableRootInp) { From 4022afd6d5dbedb4e210bd4fa5bb757ebe593096 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Fri, 11 Oct 2024 10:23:39 +0200 Subject: [PATCH 03/19] Small updates --- .../calib/include/ZDCCalib/CalibParamZDC.h | 1 + .../include/ZDCCalib/WaveformCalibData.h | 1 + .../calib/include/ZDCCalib/WaveformCalibEPN.h | 3 +++ .../ZDC/calib/src/WaveformCalibConfig.cxx | 5 ++-- Detectors/ZDC/calib/src/WaveformCalibData.cxx | 15 ++++++++++++ Detectors/ZDC/calib/src/WaveformCalibEPN.cxx | 23 +++++++++++++++++-- .../ZDC/calib/src/WaveformCalibQueue.cxx | 16 +++++++++---- .../include/ZDCWorkflow/RecoReaderSpec.h | 1 - Detectors/ZDC/workflow/src/RecoReaderSpec.cxx | 21 ++++++----------- 9 files changed, 63 insertions(+), 23 deletions(-) diff --git a/Detectors/ZDC/calib/include/ZDCCalib/CalibParamZDC.h b/Detectors/ZDC/calib/include/ZDCCalib/CalibParamZDC.h index 38416a3ec9d99..2e2b91e07482f 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/CalibParamZDC.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/CalibParamZDC.h @@ -27,6 +27,7 @@ namespace o2 namespace zdc { struct CalibParamZDC : public o2::conf::ConfigurableParamHelper { + bool dumpCalib = false; // Dump partial calibration object bool debugOutput = false; // Debug output bool rootOutput = true; // Output histograms to EOS std::string outputDir = "./"; // ROOT files output directory diff --git a/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibData.h b/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibData.h index 2818146d75f32..8701e3667b74a 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibData.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibData.h @@ -87,6 +87,7 @@ struct WaveformCalibData { void setCreationTime(uint64_t ctime); void setN(int n); int saveDebugHistos(const std::string fn); + int dumpCalib(const std::string fn); ClassDefNV(WaveformCalibData, 1); }; diff --git a/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibEPN.h b/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibEPN.h index 929190f09d162..86dff268ee0ad 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibEPN.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/WaveformCalibEPN.h @@ -37,9 +37,11 @@ class WaveformCalibEPN const gsl::span& wave); int endOfRun(); int saveDebugHistos(const std::string fn = "ZDCWaveformCalibEPN.root"); + int dumpCalib(const std::string fn = "ZDCWaveformCalibEPNDump.root"); void setConfig(const WaveformCalibConfig* param) { mConfig = param; }; const WaveformCalibConfig* getConfig() const { return mConfig; }; void setSaveDebugHistos() { mSaveDebugHistos = true; } + void setDumpCalib() { mDumpCalib = true; } void setDontSaveDebugHistos() { mSaveDebugHistos = false; } void setVerbosity(int val) { mVerbosity = val; } WaveformCalibData mData; @@ -48,6 +50,7 @@ class WaveformCalibEPN private: bool mInitDone = false; bool mSaveDebugHistos = false; + bool mDumpCalib = false; int32_t mNBin = 0; int32_t mVerbosity = DbgMinimal; const WaveformCalibConfig* mConfig = nullptr; /// Configuration of intercalibration diff --git a/Detectors/ZDC/calib/src/WaveformCalibConfig.cxx b/Detectors/ZDC/calib/src/WaveformCalibConfig.cxx index f0aeff5d53fc7..923d53f27f734 100644 --- a/Detectors/ZDC/calib/src/WaveformCalibConfig.cxx +++ b/Detectors/ZDC/calib/src/WaveformCalibConfig.cxx @@ -20,9 +20,10 @@ WaveformCalibConfig::WaveformCalibConfig() cutLow[isig] = -std::numeric_limits::infinity(); cutHigh[isig] = std::numeric_limits::infinity(); } + // Firmware aligns signals within one sample for (int itdc = 0; itdc < NTDCChannels; itdc++) { - cutTimeLow[itdc] = -1.25; - cutTimeHigh[itdc] = 1.25; + cutTimeHigh[itdc] = o2::constants::lhc::LHCBunchSpacingNS / NTimeBinsPerBC; + cutTimeLow[itdc] = -cutTimeHigh[itdc]; } } diff --git a/Detectors/ZDC/calib/src/WaveformCalibData.cxx b/Detectors/ZDC/calib/src/WaveformCalibData.cxx index 759d85a6a0f88..634ccd7ee9c1c 100644 --- a/Detectors/ZDC/calib/src/WaveformCalibData.cxx +++ b/Detectors/ZDC/calib/src/WaveformCalibData.cxx @@ -187,6 +187,21 @@ int WaveformCalibData::saveDebugHistos(const std::string fn) return 0; } +//______________________________________________________________________________ +int WaveformCalibData::dumpCalib(const std::string fn) +{ + TDirectory* cwd = gDirectory; + TFile* f = new TFile(fn.data(), "recreate"); + if (f->IsZombie()) { + LOG(error) << "Cannot create file: " << fn; + return 1; + } + f->WriteObjectAny((void*)this,o2::zdc::WaveformCalibData::Class(),"WaveformCalibData"); + f->Close(); + cwd->cd(); + return 0; +} + //______________________________________________________________________________ void WaveformCalibData::clear() { diff --git a/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx b/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx index cda158e9f5b6a..b418046cfdae0 100644 --- a/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx +++ b/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx @@ -41,6 +41,10 @@ int WaveformCalibEPN::init() setSaveDebugHistos(); } + if (opt.dumpCalib == true) { + setDumpCalib(); + } + mQueue.configure(cfg); if (mVerbosity > DbgZero) { mQueue.printConf(); @@ -99,6 +103,7 @@ int WaveformCalibEPN::process(const gsl::span& RecBC, #endif if (mask != 0) { #ifdef O2_ZDC_WAVEFORMCALIB_DEBUG + // Print last recorded event. Not the event at peak position ev.print(); ev.printDecodedMessages(); mQueue.print(); @@ -122,17 +127,25 @@ int WaveformCalibEPN::endOfRun() if (mVerbosity > DbgZero) { LOGF(info, "WaveformCalibEPN::endOfRun ts (%llu:%llu)", mData.mCTimeBeg, mData.mCTimeEnd); for (int is = 0; is < NChannels; is++) { + int itdc = SignalTDC[is]; if (mData.getEntries(is) > 0) { - int itdc = SignalTDC[is]; LOGF(info, "Waveform %2d %s with %10d events and cuts AMP:(%g:%g) TDC:%d:(%g:%g) Valid:[%d:%d:%d]", is, ChannelNames[is].data(), mData.getEntries(is), mConfig->cutLow[is], mConfig->cutHigh[is], itdc, mConfig->cutTimeLow[itdc], mConfig->cutTimeHigh[itdc], mData.getFirstValid(is), mData.mPeak, mData.getLastValid(is)); + }else{ + LOGF(info, "Waveform %2d %s with %10d events and cuts AMP:(%g:%g) TDC:%d:(%g:%g)", is, ChannelNames[is].data(), + mData.getEntries(is), mConfig->cutLow[is], mConfig->cutHigh[is], + itdc, mConfig->cutTimeLow[itdc], mConfig->cutTimeHigh[itdc]); } } } + const auto& opt = CalibParamZDC::Instance(); if (mSaveDebugHistos) { - saveDebugHistos(); + saveDebugHistos(opt.outputDir + "ZDCWaveformCalibEPN.root"); + } + if (mDumpCalib) { + dumpCalib(opt.outputDir + "ZDCWaveformCalibEPNDump.root"); } return 0; } @@ -142,3 +155,9 @@ int WaveformCalibEPN::saveDebugHistos(const std::string fn) { return mData.saveDebugHistos(fn); } + +//______________________________________________________________________________ +int WaveformCalibEPN::dumpCalib(const std::string fn) +{ + return mData.dumpCalib(fn); +} diff --git a/Detectors/ZDC/calib/src/WaveformCalibQueue.cxx b/Detectors/ZDC/calib/src/WaveformCalibQueue.cxx index c62306f21b1ad..76d66c7577029 100644 --- a/Detectors/ZDC/calib/src/WaveformCalibQueue.cxx +++ b/Detectors/ZDC/calib/src/WaveformCalibQueue.cxx @@ -201,6 +201,9 @@ int WaveformCalibQueue::hasData(int isig, const gsl::span& wave, WaveformCalibData& data) { +#ifdef O2_ZDC_WAVEFORMCALIB_DEBUG + LOG(info) << "WaveformCalibQueue::" << __func__ << " isig=" << isig << " " << ChannelNames[isig] << " tdcid=" << SignalTDC[isig] << " tdc_sig=" << TDCSignal[SignalTDC[isig]] << " " << ChannelNames[TDCSignal[SignalTDC[isig]]]; +#endif int ipkb = -1; // Bunch where peak is found int ipk = -1; // peak position within bunch float min = std::numeric_limits::infinity(); @@ -213,7 +216,7 @@ int WaveformCalibQueue::addData(int isig, const gsl::spancutLow[isig] || amp > mCfg->cutHigh[isig]) { // No warning messages for amplitude cuts on towers +#ifdef O2_ZDC_WAVEFORMCALIB_DEBUG + LOG(info) << " isig = " << isig << " amplitude " << amp << " not in range " << mCfg->cutLow[isig] << " : " << mCfg->cutHigh[isig]; +#endif return -1; } if ((ppos - mPeak) < mTimeLow[itdc] || (ppos - mPeak) > mTimeHigh[itdc]) { diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h index d81b7b6b199be..ae2ed186cdf45 100644 --- a/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/RecoReaderSpec.h @@ -33,7 +33,6 @@ class RecoReader : public framework::Task private: std::unique_ptr mTree; std::unique_ptr mFile; - bool mWaveformEnable = false; }; /// create a processor spec diff --git a/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx b/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx index f952eeadddeaf..0d23527fcc857 100644 --- a/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx +++ b/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx @@ -36,7 +36,6 @@ namespace zdc void RecoReader::init(InitContext& ic) { auto filename = o2::utils::Str::concat_string(o2::utils::Str::rectifyDirectory(ic.options().get("input-dir")), ic.options().get("zdc-reco-infile")); - mWaveformEnable = ic.options().get("waveform-enable"); mFile.reset(TFile::Open(filename.c_str())); if (!mFile->IsOpen()) { LOG(error) << "Cannot open the " << filename.c_str() << " file !"; @@ -62,23 +61,18 @@ void RecoReader::run(ProcessingContext& pc) mTree->SetBranchAddress("ZDCRecE", &EnergyPtr); mTree->SetBranchAddress("ZDCRecTDC", &TDCDataPtr); mTree->SetBranchAddress("ZDCRecInfo", &InfoPtr); - if(mWaveformEnable){ - mTree->SetBranchAddress("ZDCWaveform", &WaveformPtr); - } + mTree->SetBranchAddress("ZDCWaveform", &WaveformDataPtr); auto ent = mTree->GetReadEntry() + 1; assert(ent < mTree->GetEntries()); // this should not happen mTree->GetEntry(ent); + LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos " << WaveformData.size() << " Waveform chunks"; pc.outputs().snapshot(Output{"ZDC", "BCREC", 0}, RecBC); pc.outputs().snapshot(Output{"ZDC", "ENERGY", 0}, Energy); pc.outputs().snapshot(Output{"ZDC", "TDCDATA", 0}, TDCData); pc.outputs().snapshot(Output{"ZDC", "INFO", 0}, Info); - if(mWaveformEnable){ - LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos"; - pc.outputs().snapshot(Output{"ZDC", "WAVE", 0}, Waveform); - }else{ - LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos" << Wave.size() << " Waveform chunks"; - } + pc.outputs().snapshot(Output{"ZDC", "WAVE", 0}, WaveformData); + if (mTree->GetReadEntry() + 1 >= mTree->GetEntries()) { pc.services().get().endOfStream(); pc.services().get().readyToQuit(QuitRequest::Me); @@ -92,9 +86,8 @@ DataProcessorSpec getRecoReaderSpec() outputs.emplace_back("ZDC", "ENERGY", 0, Lifetime::Timeframe); outputs.emplace_back("ZDC", "TDCDATA", 0, Lifetime::Timeframe); outputs.emplace_back("ZDC", "INFO", 0, Lifetime::Timeframe); - if(mWaveformEnable){ - outputs.emplace_back("ZDC", "WAVE", 0, Lifetime::Timeframe); - } + outputs.emplace_back("ZDC", "WAVE", 0, Lifetime::Timeframe); + return DataProcessorSpec{ "zdc-reco-reader", Inputs{}, @@ -102,7 +95,7 @@ DataProcessorSpec getRecoReaderSpec() AlgorithmSpec{adaptFromTask()}, Options{ {"zdc-reco-infile", VariantType::String, "zdcreco.root", {"Name of the input file"}}, - {"waveform-enable", VariantType::Bool, false, {"Read waveform data"}} + {"enable-waveform", VariantType::Bool, false, {"Read waveform data"}}, {"input-dir", VariantType::String, "none", {"Input directory"}}}}; } From 84d6793e4aeffc2014800dc755d1eb19f00d54c6 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Thu, 17 Oct 2024 17:08:03 +0200 Subject: [PATCH 04/19] Digits parser workflow --- Detectors/ZDC/workflow/CMakeLists.txt | 6 ++ .../include/ZDCWorkflow/ParserWorkflow.h | 26 ++++++++ Detectors/ZDC/workflow/src/ParserWorkflow.cxx | 31 ++++++++++ .../ZDC/workflow/src/zdc-parser-workflow.cxx | 60 +++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 Detectors/ZDC/workflow/include/ZDCWorkflow/ParserWorkflow.h create mode 100644 Detectors/ZDC/workflow/src/ParserWorkflow.cxx create mode 100644 Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx diff --git a/Detectors/ZDC/workflow/CMakeLists.txt b/Detectors/ZDC/workflow/CMakeLists.txt index 90de7e1bc2659..bf7d4f121d21c 100644 --- a/Detectors/ZDC/workflow/CMakeLists.txt +++ b/Detectors/ZDC/workflow/CMakeLists.txt @@ -64,3 +64,9 @@ o2_add_executable(digits-writer COMPONENT_NAME zdc SOURCES src/digits-writer-workflow.cxx PUBLIC_LINK_LIBRARIES O2::ZDCWorkflow O2::ZDCReconstruction) + +o2_add_executable(digits-parser + COMPONENT_NAME zdc + SOURCES src/zdc-parser-workflow.cxx + PUBLIC_LINK_LIBRARIES O2::ZDCWorkflow O2::ZDCReconstruction) + diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/ParserWorkflow.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/ParserWorkflow.h new file mode 100644 index 0000000000000..0aced0b444983 --- /dev/null +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/ParserWorkflow.h @@ -0,0 +1,26 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_ZDC_PARSERWORKFLOW_H +#define O2_ZDC_PARSERWORKFLOW_H + +/// @file ParserWorkflow.h + +#include "Framework/WorkflowSpec.h" + +namespace o2 +{ +namespace zdc +{ +framework::WorkflowSpec getParserWorkflow(const int verbosity); +} // namespace zdc +} // namespace o2 +#endif diff --git a/Detectors/ZDC/workflow/src/ParserWorkflow.cxx b/Detectors/ZDC/workflow/src/ParserWorkflow.cxx new file mode 100644 index 0000000000000..c8cb3811e029f --- /dev/null +++ b/Detectors/ZDC/workflow/src/ParserWorkflow.cxx @@ -0,0 +1,31 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file ParserWorkflow.cxx + +#include "ZDCWorkflow/ParserWorkflow.h" +#include "ZDCWorkflow/DigitReaderSpec.h" + +namespace o2 +{ +namespace zdc +{ + +framework::WorkflowSpec getRecoWorkflow(const int verbosity) +{ + framework::WorkflowSpec specs; + specs.emplace_back(o2::zdc::getDigitReaderSpec(false)); +// specs.emplace_back(o2::zdc::getDigitRecoSpec(verbosity, enableDebugOut, enableZDCTDCCorr, enableZDCEnergyParam, enableZDCTowerParam, enableBaselineParam)); + return specs; +} + +} // namespace zdc +} // namespace o2 diff --git a/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx b/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx new file mode 100644 index 0000000000000..40299744cd3d5 --- /dev/null +++ b/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx @@ -0,0 +1,60 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "ZDCWorkflow/ParserWorkflow.h" +#include "CommonUtils/ConfigurableParam.h" +#include "DetectorsRaw/HBFUtilsInitializer.h" +#include "Framework/CallbacksPolicy.h" +#include "Framework/CompletionPolicyHelpers.h" + +using namespace o2::framework; + +// ------------------------------------------------------------------ +void customize(std::vector& policies) +{ + o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); +} + +void customize(std::vector& policies) +{ + // ordered policies for the writers + policies.push_back(CompletionPolicyHelpers::consumeWhenAllOrdered(".*(?:ZDC|zdc).*[W,w]riter.*")); +} + +// we need to add workflow options before including Framework/runDataProcessing +void customize(std::vector& workflowOptions) +{ + // option allowing to set parameters + workflowOptions.push_back(ConfigParamSpec{"verbosity", VariantType::Int, 0, {"verbosity level"}}); + std::string keyvaluehelp("Semicolon separated key=value strings ..."); + workflowOptions.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {keyvaluehelp}}); + o2::raw::HBFUtilsInitializer::addConfigOption(workflowOptions); +} + +// ------------------------------------------------------------------ + +#include "Framework/runDataProcessing.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) +{ + LOG(info) << "WorkflowSpec defineDataProcessing"; + // Update the (declared) parameters if changed from the command line + o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); + + auto verbosity = configcontext.options().get("reco-verbosity"); + + auto wf = o2::zdc::getParserWorkflow(verbosity); + + // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit + o2::raw::HBFUtilsInitializer hbfIni(configcontext, wf); + + return std::move(wf); +} From a234254dc6da856748f4b1fe52ea5940e5e5c587 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Thu, 17 Oct 2024 17:20:28 +0200 Subject: [PATCH 05/19] Digits parser workflow --- Detectors/ZDC/workflow/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Detectors/ZDC/workflow/CMakeLists.txt b/Detectors/ZDC/workflow/CMakeLists.txt index bf7d4f121d21c..e17105eadb469 100644 --- a/Detectors/ZDC/workflow/CMakeLists.txt +++ b/Detectors/ZDC/workflow/CMakeLists.txt @@ -21,6 +21,7 @@ o2_add_library(ZDCWorkflow src/DigitRecoSpec.cxx src/DigitReaderSpec.cxx src/RecoReaderSpec.cxx + src/ParserWorkflow.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DataFormatsZDC O2::ZDCRaw From 587dffa454e5dcbc118ec74a41e6705b4870ab49 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Thu, 17 Oct 2024 22:39:02 +0200 Subject: [PATCH 06/19] Digits parser workflow --- .../include/ZDCReconstruction/DigiParser.h | 98 ++++ .../ZDC/reconstruction/src/DigiParser.cxx | 489 ++++++++++++++++++ Detectors/ZDC/workflow/CMakeLists.txt | 1 + .../include/ZDCWorkflow/DigitParserSpec.h | 57 ++ .../ZDC/workflow/src/DigitParserSpec.cxx | 125 +++++ Detectors/ZDC/workflow/src/ParserWorkflow.cxx | 2 +- 6 files changed, 771 insertions(+), 1 deletion(-) create mode 100644 Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h create mode 100644 Detectors/ZDC/reconstruction/src/DigiParser.cxx create mode 100644 Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h create mode 100644 Detectors/ZDC/workflow/src/DigitParserSpec.cxx diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h new file mode 100644 index 0000000000000..786e8abbb5597 --- /dev/null +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h @@ -0,0 +1,98 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include +#include +#include +#include +#include "Framework/Logger.h" +#include "ZDCBase/Constants.h" +#include "ZDCSimulation/ZDCSimParam.h" +#include "ZDCReconstruction/RecoParamZDC.h" +#include "ZDCReconstruction/ZDCTDCParam.h" +#include "ZDCReconstruction/ZDCTDCCorr.h" +#include "ZDCReconstruction/ZDCEnergyParam.h" +#include "ZDCReconstruction/ZDCTowerParam.h" +#include "ZDCReconstruction/BaselineParam.h" +#include "ZDCReconstruction/RecoConfigZDC.h" +#include "ZDCBase/ModuleConfig.h" +#include "CommonDataFormat/InteractionRecord.h" +#include "DataFormatsZDC/BCData.h" +#include "DataFormatsZDC/ChannelData.h" +#include "DataFormatsZDC/OrbitData.h" +#include "DataFormatsZDC/RecEvent.h" +#include "DataFormatsZDC/RecEventAux.h" + +#ifndef ALICEO2_ZDC_DIGI_PARSER_H +#define ALICEO2_ZDC_DIGI_PARSER_H + +namespace o2 +{ +namespace zdc +{ + +class DigiParser +{ + public: + DigiParser() = default; + ~DigiParser() = default; + void init(); + int process(const gsl::span& orbitdata, + const gsl::span& bcdata, + const gsl::span& chdata); + int write(); + void setVerbosity(int v) + { + mVerbosity = v; + } + int getVerbosity() const { return mVerbosity; } + void eor(); + + void setModuleConfig(const ModuleConfig* moduleConfig) { mModuleConfig = moduleConfig; }; + const ModuleConfig* getModuleConfig() { return mModuleConfig; }; + +private: + const ModuleConfig* mModuleConfig = nullptr; /// Trigger/readout configuration object + + const RecoParamZDC* mRopt = nullptr; + int mNBCAHead = 0; /// when storing triggered BC, store also mNBCAHead BCs + uint32_t mTriggerMask = 0; /// Mask of triggering channels + const RecoConfigZDC* mRecoConfigZDC = nullptr; /// CCDB configuration parameters + int32_t mVerbosity = DbgMinimal; + std::unique_ptr mDbg = nullptr; /// Debug output file + std::unique_ptr mTDbg = nullptr; /// Debug tree + gsl::span mOrbitData; /// Reconstructed data + gsl::span mBCData; /// BC info + gsl::span mChData; /// Payload + std::vector mReco; /// Reconstructed data + std::map mOrbit; /// Information about orbit + float mOffset[NChannels]; /// Offset in current orbit + uint32_t mOffsetOrbit = 0xffffffff; /// Current orbit + uint8_t mSource[NChannels]; /// Source of pedestal + static constexpr int mNSB = TSN * NTimeBinsPerBC; /// Total number of interpolated points per bunch crossing + RecEventAux mRec; /// Debug reconstruction event + int mNBC = 0; + int mNLonely = 0; + int mLonely[o2::constants::lhc::LHCMaxBunches] = {0}; + int mLonelyTrig[o2::constants::lhc::LHCMaxBunches] = {0}; + uint32_t mMissingPed[NChannels] = {0}; + constexpr static uint16_t mMask[NTimeBinsPerBC] = {0x0001, 0x002, 0x004, 0x008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800}; + // Configuration of interpolation for current TDC + int mNbun; // Number of adjacent bunches + int mNsam; // Number of acquired samples + int mNtot; // Total number of points in the interpolated arrays + int mIlast; // Index of last acquired sample + int mNint; // Total points in the interpolation region (-1) +}; +} // namespace zdc +} // namespace o2 +#endif diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx new file mode 100644 index 0000000000000..2d8bdb3544858 --- /dev/null +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -0,0 +1,489 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include +#include "Framework/Logger.h" +#include "ZDCReconstruction/DigiParser.h" +#include "ZDCReconstruction/RecoParamZDC.h" + +namespace o2 +{ +namespace zdc +{ + +void DigiReco::init() +{ + LOG(info) << "Initialization of ZDC DigiParser"; + if (!mModuleConfig) { + LOG(fatal) << "Missing ModuleConfig configuration object"; + return; + } + + mTriggerMask = mModuleConfig->getTriggerMask(); +} // init + +void DigiReco::eor() +{ + if (mTreeDbg) { + LOG(info) << "o2::zdc::DigiReco: closing debug output"; + mTDbg->Write(); + mTDbg.reset(); + mDbg->Close(); + mDbg.reset(); + } + + ZDCTDCDataErr::print(); + + if (mNLonely > 0) { + LOG(warn) << "Detected " << mNLonely << " lonely bunches"; + for (int ib = 0; ib < o2::constants::lhc::LHCMaxBunches; ib++) { + if (mLonely[ib]) { + LOGF(warn, "lonely bunch %4d #times=%u #trig=%u", ib, mLonely[ib], mLonelyTrig[ib]); + } + } + } + for (int ich = 0; ich < NChannels; ich++) { + if (mMissingPed[ich] > 0) { + LOGF(error, "Missing pedestal for ch %2d %s: %u", ich, ChannelNames[ich], mMissingPed[ich]); + } + } +} + +int DigiReco::process(const gsl::span& orbitdata, const gsl::span& bcdata, const gsl::span& chdata) +{ +#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG + LOG(info) << "________________________________________________________________________________"; + LOG(info) << __func__; +#endif + // We assume that vectors contain data from a full time frame + mOrbitData = orbitdata; + mBCData = bcdata; + mChData = chdata; + mInError = false; + + // Initialization of lookup structure for pedestals + mOrbit.clear(); + int norb = mOrbitData.size(); + if (mVerbosity >= DbgFull) { + LOG(info) << "Dump of pedestal data lookup table"; + } + // TODO: send scalers to aggregator + uint32_t scaler[NChannels] = {0}; + for (int iorb = 0; iorb < norb; iorb++) { + mOrbit[mOrbitData[iorb].ir.orbit] = iorb; + if (mVerbosity >= DbgFull) { + LOG(info) << "mOrbitData[" << mOrbitData[iorb].ir.orbit << "] = " << iorb; + } + // TODO: add only if orbit is good. Here we check only the individual scaler values + for (int ich = 0; ich < NChannels; ich++) { + if (mOrbitData[iorb].scaler[ich] <= o2::constants::lhc::LHCMaxBunches) { + scaler[ich] += mOrbitData[iorb].scaler[ich]; + } + } + } + if (mVerbosity > DbgMinimal) { + for (int ich = 0; ich < NChannels; ich++) { + LOG(info) << ChannelNames[ich] << " cnt: " << scaler[ich]; + } + } + + mNBC = mBCData.size(); + mReco.clear(); + mReco.resize(mNBC); + // Initialization of reco structure + for (int ibc = 0; ibc < mNBC; ibc++) { + auto& bcr = mReco[ibc]; +#ifdef O2_ZDC_TDC_C_ARRAY + for (int itdc = 0; itdc < NTDCChannels; itdc++) { + for (int i = 0; i < MaxTDCValues; i++) { + bcr.tdcVal[itdc][i] = kMinShort; + bcr.tdcAmp[itdc][i] = kMinShort; + } + } +#endif + auto& bcd = mBCData[ibc]; + bcr.ir = bcd.ir; + int chEnt = bcd.ref.getFirstEntry(); + for (int ic = 0; ic < bcd.ref.getEntries(); ic++) { + auto& chd = mChData[chEnt]; + if (chd.id > IdDummy && chd.id < NChannels) { + bcr.ref[chd.id] = chEnt; + } + chEnt++; + } + } + + // Probably this is not necessary + // for(int isig=0; isig DbgMinimal) { + LOG(info) << "Processing ZDC reconstruction for " << mNBC << " bunch crossings"; + } + + // TDC reconstruction + for (int ibc = 0; ibc < mNBC; ibc++) { + auto& ir = mBCData[seq_end].ir; + auto bcd = mBCData[ibc].ir.differenceInBC(ir); + if (bcd < 0) { + LOG(error) << "Bunch order error in TDC reconstruction"; + for (int ibcdump = 0; ibcdump < mNBC; ibcdump++) { + LOG(error) << "mBCData[" << ibcdump << "] @ " << mBCData[ibcdump].ir.orbit << "." << mBCData[ibcdump].ir.bc; + } + 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; + return __LINE__; + } else if (bcd > 1) { + // Detected a gap + int rval = reconstructTDC(seq_beg, seq_end); + if (rval) { + return rval; + } + + seq_beg = ibc; + seq_end = ibc; + } else if (ibc == (mNBC - 1)) { + // Last bunch + seq_end = ibc; + int rval = reconstructTDC(seq_beg, seq_end); + if (rval) { + return rval; + } + + seq_beg = mNBC; + seq_end = mNBC; + } else { + // Look for another bunch + seq_end = ibc; + } +#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG + // Here in order to avoid mixing information + mBCData[ibc].print(mTriggerMask); +#endif + } + + // Apply pile-up correction for TDCs to get corrected TDC amplitudes and values + correctTDCPile(); + + // ADC reconstruction + seq_beg = 0; + seq_end = 0; + for (int ibc = 0; ibc < mNBC; ibc++) { + auto& ir = mBCData[seq_end].ir; + auto bcd = mBCData[ibc].ir.differenceInBC(ir); + if (bcd < 0) { + LOG(error) << "Bunch order error in ADC reconstruction"; + for (int ibcdump = 0; ibcdump < mNBC; ibcdump++) { + LOG(error) << "mBCData[" << ibcdump << "] @ " << mBCData[ibcdump].ir.orbit << "." << mBCData[ibcdump].ir.bc; + } + 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; + return __LINE__; + } else if (bcd > 1) { + // Detected a gap + int rval = reconstruct(seq_beg, seq_end); + if (rval != 0) { + return rval; + } + seq_beg = ibc; + seq_end = ibc; + } else if (ibc == (mNBC - 1)) { + // Last bunch + seq_end = ibc; + int rval = reconstruct(seq_beg, seq_end); + if (rval != 0) { + return rval; + } + seq_beg = mNBC; + seq_end = mNBC; + } else { + // Look for another bunch + seq_end = ibc; + } + } + return 0; +} // process + +int DigiReco::reconstruct(int ibeg, int iend) +{ +#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG + LOG(info) << "________________________________________________________________________________"; + LOG(info) << __func__ << "(" << ibeg << ", " << iend << "): " << mReco[ibeg].ir.orbit << "." << mReco[ibeg].ir.bc << " - " << mReco[iend].ir.orbit << "." << mReco[iend].ir.bc; +#endif + // Process consecutive BCs + if (ibeg == iend) { + mNLonely++; + mLonely[mReco[ibeg].ir.bc]++; + if (mBCData[ibeg].triggers != 0x0) { + mLonelyTrig[mReco[ibeg].ir.bc]++; + } + // Cannot reconstruct lonely bunch + // LOG(info) << "Lonely bunch " << mReco[ibeg].ir.orbit << "." << mReco[ibeg].ir.bc; + return 0; + } +#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG + for (int ibun = ibeg; ibun <= iend; ibun++) { + printf("%d CH Mask: 0x%08x TDC data for:", ibun, mBCData[ibun].channels); + for (int itdc = 0; itdc < NTDCChannels; itdc++) { + if (mBCData[ibun].channels & mTDCMask[itdc]) { + printf(" %s", ChannelNames[TDCSignal[itdc]].data()); + } else { + printf(" "); + } + } + printf("\n"); + } +#endif + + // After pile-up correction, find signals around main-main that satisfy condition on TDC + findSignals(ibeg, iend); + + // For each calorimeter that has detects a collision at the time of main-main + // collisions we reconstruct integrated charges and fill output tree + for (int ich = 0; ich < NChannels; ich++) { + // We consder the longest sequence of acquired bunches that can be readout by + // the acquisition in case of isolated events (filling scheme with sigle bunches) + uint32_t ref[NBCReadOut] = {ZDCRefInitVal, ZDCRefInitVal, ZDCRefInitVal, ZDCRefInitVal}; + // Flags to investigate pile-up + bool hasFired[NBCReadOut] = {0}; // Channel has a TDC fired + bool hasHit[NBCReadOut] = {0}; // Channel has hit + bool hasAuto0[NBCReadOut] = {0}; // Module has Auto_0 trigger bit + bool hasAutoM[NBCReadOut] = {0}; // Module has Auto_m trigger bit + // Initialize info about previous bunches + for (int ibp = 1; ibp < 4; ibp++) { + int ibun = ibeg - ibp; + // For the time being, we cannot access previous time frame (ibun<0) + if (ibun < 0) { + break; + } + auto bcd = mBCData[ibeg].ir.differenceInBC(mBCData[ibun].ir); + if (bcd < 1) { + 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; + return __LINE__; + } + if (bcd > 3) { + break; + } + // Assignment is done taking into account bunch crossing difference + ref[bcd] = mReco[ibun].ref[ich]; + // If channel has no waverform data cannot have a hit or trigger bit assigned + // because all channels of a module are acquired if trigger condition is + // satisfied + if (ref[bcd] == ZDCRefInitVal) { + continue; + } + // This condition is not comprehensive of all pile-up sources + // chfired: Fired TDC condition related to channel (e.g. AND of TC and SUM @ main-main) + hasFired[bcd] = mReco[ibun].chfired[ich]; + // Information from hardware autotrigger is not restricted to hits in main-main + // but it may extend outside the correct bunch for signals near the bunch edges + // hasHit refers to a single channel since it is derived from ChannelDataV0::Hit + hasHit[bcd] = mBCData[ibun].triggers & mChMask[ich]; + // hasAuto0 and hasAutoM are derived from autotrigger decisions and therefore + // refer to a module (max 4 channels) and not to a single channel + ModuleTriggerMapData mt; + mt.w = mBCData[ibun].moduleTriggers[mRopt->amod[ich]]; + hasAuto0[bcd] = mt.f.Auto_0; + hasAutoM[bcd] = mt.f.Auto_m; +#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG + printf("%2d %s bcd = %d ibun = %d ibeg = %d ref = %3u %s %s %s\n", + ich, ChannelNames[ich].data(), bcd, ibun, ibeg, ref[bcd], + hasHit[bcd] ? "H" : "-", hasAuto0[bcd] ? "A0" : "--", hasAutoM[bcd] ? "AM" : "--"); +#endif + } + // Analyze all bunches + for (int ibun = ibeg; ibun <= iend; ibun++) { + updateOffsets(ibun); // Get Orbit pedestals + auto& rec = mReco[ibun]; + // Check if the corresponding TDC is fired + ref[0] = mReco[ibun].ref[ich]; + hasHit[0] = mBCData[ibun].triggers & mChMask[ich]; + ModuleTriggerMapData mt; + mt.w = mBCData[ibun].moduleTriggers[mRopt->amod[ich]]; + hasAuto0[0] = mt.f.Auto_0; + hasAutoM[0] = mt.f.Auto_m; + if (rec.chfired[ich]) { + // Check if channel data are present in payload + if (ref[0] < ZDCRefInitVal) { + // Energy reconstruction + // Compute event by event pedestal + bool hasEvPed = false; + float evPed = 0; + if (ibun > ibeg) { + auto ref_m = ref[1]; + if (mRopt->beg_ped_int[ich] >= 0 || ref_m < ZDCRefInitVal) { + for (int is = mRopt->beg_ped_int[ich]; is <= mRopt->end_ped_int[ich]; is++) { + if (is < 0) { + // Sample is in previous BC + evPed += float(mChData[ref_m].data[is + NTimeBinsPerBC]); + } else { + // Sample is in current BC + evPed += float(mChData[ref[0]].data[is]); + } + } + evPed /= float(mRopt->end_ped_int[ich] - mRopt->beg_ped_int[ich] + 1); + hasEvPed = true; + } + } + // Pile-up detection using trigger information allows to identify + // the presence of a signal in previous bunch and is module-wise + + // Detection of pile-up from previous bunch by comparing event pedestal with reference + // (reference can be orbit or QC). If pile-up is detected we use orbit pedestal + // instead of event pedestal + // TODO: pedestal event could have a TM.. + if (hasEvPed && (mSource[ich] == PedOr || mSource[ich] == PedQC)) { + auto pedref = mOffset[ich]; + if (evPed > pedref && (evPed - pedref) > mRopt->ped_thr_hi[ich]) { + // Anomalous offset (put a warning but use event pedestal) + rec.offPed[ich] = true; + } else if (evPed < pedref && (pedref - evPed) > mRopt->ped_thr_lo[ich]) { + // Possible presence of pile-up (will need to use orbit pedestal) + rec.pilePed[ich] = true; + } + } + float myPed = std::numeric_limits::infinity(); + // TODO: + if (hasEvPed && rec.pilePed[ich] == false) { + myPed = evPed; + rec.adcPedEv[ich] = true; + } else if (mSource[ich] == PedOr) { + myPed = mOffset[ich]; + rec.adcPedOr[ich] = true; + } else if (mSource[ich] == PedQC) { + myPed = mOffset[ich]; + rec.adcPedQC[ich] = true; + } else { + rec.adcPedMissing[ich] = true; + } + if (myPed < std::numeric_limits::infinity()) { + float sum = 0; + for (int is = mRopt->beg_int[ich]; is <= mRopt->end_int[ich]; is++) { + // TODO: pile-up correction + // TODO: manage signal positioned across boundary + sum += (myPed - float(mChData[ref[0]].data[is])); + } + rec.ezdc[ich] = (sum - mRopt->adc_offset[ich]) * mRopt->energy_calib[ich]; + } else { + LOGF(warn, "%d.%-4d CH %2d %s missing pedestal", rec.ir.orbit, rec.ir.bc, ich, ChannelNames[ich].data()); + } + } else { + // This could arise from memory corruption or in the case when TDC bits are forced to 1 + // due to a broken channel. For example Sum is broken and sum TDC is forced to 1 + // Take a very small signal that triggers on one module and not the other + // 1) module 0 triggered by ZNATC is autotriggered + // 2) module 1 triggered by ZNATC is not triggered -> Sum is missing + // 3) sum TDC is forced to 1 and therefore the TDC is fired even if data are not present + // 4) you get this error flag in reconstruction + // This should happen only in case of hardware fault and signals near threshold + // This should be mitigated by having a software threshold higher than the hardware one + rec.adcPedMissing[ich] = true; + if (mVerbosity >= DbgMedium) { + LOGF(warn, "%d.%-4d CH %2d %s ADC missing, TDC present", rec.ir.orbit, rec.ir.bc, ich, ChannelNames[ich].data()); + } + } + } + // Shift bunches by 1 taking into account bunch crossing difference + // TODO + // This is a simple shift by 1 position + if (ibun != iend) { + for (int ibcr = NBCReadOut - 1; ibcr > 0; ibcr--) { + ref[ibcr] = ref[ibcr - 1]; + hasHit[ibcr] = hasHit[ibcr - 1]; + hasAuto0[ibcr] = hasAuto0[ibcr - 1]; + hasAutoM[ibcr] = hasAutoM[ibcr - 1]; + hasFired[ibcr] = hasFired[ibcr - 1]; + } + } + } // Loop on bunches + } // Loop on channels + if (mTreeDbg) { + for (int ibun = ibeg; ibun <= iend; ibun++) { + auto& rec = mReco[ibun]; + mRec = rec; + mTDbg->Fill(); + } + } + return 0; +} // reconstruct + +} // namespace zdc +} // namespace o2 diff --git a/Detectors/ZDC/workflow/CMakeLists.txt b/Detectors/ZDC/workflow/CMakeLists.txt index e17105eadb469..21de8322a81fe 100644 --- a/Detectors/ZDC/workflow/CMakeLists.txt +++ b/Detectors/ZDC/workflow/CMakeLists.txt @@ -20,6 +20,7 @@ o2_add_library(ZDCWorkflow src/RecoWorkflow.cxx src/DigitRecoSpec.cxx src/DigitReaderSpec.cxx + src/DigitParserSpec.cxx src/RecoReaderSpec.cxx src/ParserWorkflow.cxx PUBLIC_LINK_LIBRARIES O2::Framework diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h new file mode 100644 index 0000000000000..d0aa027a0d5ad --- /dev/null +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h @@ -0,0 +1,57 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file DigitRecoSpec.h +/// @brief Run ZDC digits reconstruction +/// @author pietro.cortese@cern.ch + +#ifndef O2_ZDC_DIGITPARSER_SPEC +#define O2_ZDC_DIGITPARSER_SPEC + +#include "Framework/Logger.h" +#include "Framework/DataProcessorSpec.h" +#include "Framework/DataAllocator.h" +#include "Framework/DataSpecUtils.h" +#include "Framework/Task.h" +#include +#include "CommonUtils/NameConf.h" + +namespace o2 +{ +namespace zdc +{ + +class DigitParserSpec : public o2::framework::Task +{ + public: + DigitParserSpec(); + DigitParserSpec(const int verbosity); + ~DigitParserSpec() override = default; + void init(o2::framework::InitContext& ic) final; + void updateTimeDependentParams(o2::framework::ProcessingContext& pc); + void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final; + void run(o2::framework::ProcessingContext& pc) final; + void endOfStream(o2::framework::EndOfStreamContext& ec) final; + + private: + //DigiReco mWorker; // Reconstruction object + int mVerbosity = 0; // Verbosity level during recostruction + bool mInitialized = false; // Connect once to CCDB during initialization + TStopwatch mTimer; +}; + +/// create a processor spec +framework::DataProcessorSpec getDigitParserSpec(const int verbosity); + +} // namespace zdc +} // namespace o2 + +#endif diff --git a/Detectors/ZDC/workflow/src/DigitParserSpec.cxx b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx new file mode 100644 index 0000000000000..fa88af0f8436a --- /dev/null +++ b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx @@ -0,0 +1,125 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file DigitParserSpec.cxx +/// @brief ZDC digits parser +/// @author pietro.cortese@cern.ch + +#include +#include +#include +#include +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "Framework/Logger.h" +#include "Framework/DataProcessorSpec.h" +#include "Framework/ControlService.h" +#include "Framework/ConfigParamRegistry.h" +#include "Framework/CCDBParamSpec.h" +#include "ZDCWorkflow/DigitParserSpec.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "DataFormatsZDC/BCData.h" +#include "DataFormatsZDC/ChannelData.h" +#include "DataFormatsZDC/OrbitData.h" +#include "ZDCBase/ModuleConfig.h" +#include "CommonUtils/NameConf.h" +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" + +using namespace o2::framework; + +namespace o2 +{ +namespace zdc +{ + +DigitParserSpec::DigitParserSpec() +{ + mTimer.Stop(); + mTimer.Reset(); +} + +DigitParserSpec::DigitParserSpec(const int verbosity) : mVerbosity(verbosity) +{ + mTimer.Stop(); + mTimer.Reset(); +} + +void DigitParserSpec::init(o2::framework::InitContext& ic) +{ +} + +void DigitParserSpec::updateTimeDependentParams(ProcessingContext& pc) +{ + // we call these methods just to trigger finaliseCCDB callback + pc.inputs().get("moduleconfig"); +} + +void DigitParserSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) +{ + if (matcher == ConcreteDataMatcher("ZDC", "MODULECONFIG", 0)) { + auto* config = (const o2::zdc::ModuleConfig*)obj; + if (mVerbosity > DbgZero) { + config->print(); + } + // mWorker.setModuleConfig(config); + } +} + +void DigitParserSpec::run(ProcessingContext& pc) +{ + if (!mInitialized) { + LOG(info) << "DigitParserSpec::run initialization"; + mInitialized = true; + updateTimeDependentParams(pc); + // mWorker.setVerbosity(mVerbosity); + // mWorker.init(); + } + auto cput = mTimer.CpuTime(); + mTimer.Start(false); + + auto bcdata = pc.inputs().get>("trig"); + auto chans = pc.inputs().get>("chan"); + auto peds = pc.inputs().get>("peds"); + +// int rval = mWorker.process(peds, bcdata, chans); +// if (rval != 0 || mWorker.inError()) { +// LOG(warning) << bcdata.size() << " BC " << chans.size() << " CH " << peds.size() << " OD -> processing ended in ERROR @ line " << rval; +// } + mTimer.Stop(); +} + +void DigitParserSpec::endOfStream(EndOfStreamContext& ec) +{ + // mWorker.eor(); + LOGF(info, "ZDC digits parsing total time: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); +} + +framework::DataProcessorSpec getDigitParserSpec(const int verbosity = 0) +{ + std::vector inputs; + inputs.emplace_back("trig", "ZDC", "DIGITSBC", 0, Lifetime::Timeframe); + inputs.emplace_back("chan", "ZDC", "DIGITSCH", 0, Lifetime::Timeframe); + inputs.emplace_back("peds", "ZDC", "DIGITSPD", 0, Lifetime::Timeframe); + inputs.emplace_back("moduleconfig", "ZDC", "MODULECONFIG", 0, Lifetime::Condition, o2::framework::ccdbParamSpec(o2::zdc::CCDBPathConfigModule.data())); + + std::vector outputs; + + return DataProcessorSpec{ + "zdc-digi-parser", + inputs, + outputs, + AlgorithmSpec{adaptFromTask(verbosity)}, + o2::framework::Options{}}; +} + +} // namespace zdc +} // namespace o2 diff --git a/Detectors/ZDC/workflow/src/ParserWorkflow.cxx b/Detectors/ZDC/workflow/src/ParserWorkflow.cxx index c8cb3811e029f..f373a7dbea2db 100644 --- a/Detectors/ZDC/workflow/src/ParserWorkflow.cxx +++ b/Detectors/ZDC/workflow/src/ParserWorkflow.cxx @@ -19,7 +19,7 @@ namespace o2 namespace zdc { -framework::WorkflowSpec getRecoWorkflow(const int verbosity) +framework::WorkflowSpec getParserWorkflow(const int verbosity) { framework::WorkflowSpec specs; specs.emplace_back(o2::zdc::getDigitReaderSpec(false)); From 0adb3e317aaf0a45be60b246fde6eeb7f2c7cca7 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Fri, 18 Oct 2024 15:06:59 +0200 Subject: [PATCH 07/19] WIP --- .../ZDC/include/DataFormatsZDC/BCData.h | 3 +- Detectors/ZDC/reconstruction/CMakeLists.txt | 1 + .../include/ZDCReconstruction/DigiParser.h | 46 +- .../ZDC/reconstruction/src/DigiParser.cxx | 613 ++++++------------ .../include/ZDCWorkflow/DigitParserSpec.h | 3 +- .../ZDC/workflow/src/DigitParserSpec.cxx | 16 +- 6 files changed, 229 insertions(+), 453 deletions(-) diff --git a/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h b/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h index da1ca9d1d0292..916181030c583 100644 --- a/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h +++ b/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h @@ -55,8 +55,9 @@ struct BCData { o2::dataformats::RangeRefComp<6> ref; o2::InteractionRecord ir; std::array moduleTriggers{}; + // N.B. channels and triggers have geographical addressing (0x1 << (NChPerModule * im + ic) uint32_t channels = 0; // pattern of channels it refers to - uint32_t triggers = 0; // pattern of triggered channels (not necessarily stored) in this BC + uint32_t triggers = 0; // pattern of triggered channels (not necessarily stored) in this BC (i.e. with Hit bit on) uint8_t ext_triggers = 0; // pattern of ALICE triggers BCData() = default; diff --git a/Detectors/ZDC/reconstruction/CMakeLists.txt b/Detectors/ZDC/reconstruction/CMakeLists.txt index f06819f8e2cf8..ea4b4b60d22b5 100644 --- a/Detectors/ZDC/reconstruction/CMakeLists.txt +++ b/Detectors/ZDC/reconstruction/CMakeLists.txt @@ -13,6 +13,7 @@ o2_add_library(ZDCReconstruction SOURCES src/CTFCoder.cxx src/CTFHelper.cxx src/DigiReco.cxx + src/DigiParser.cxx src/RecoParamZDC.cxx src/ZDCTDCParam.cxx src/ZDCEnergyParam.cxx diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h index 786e8abbb5597..43550ee8df320 100644 --- a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h @@ -13,7 +13,8 @@ #include #include #include -#include +#include +#include #include "Framework/Logger.h" #include "ZDCBase/Constants.h" #include "ZDCSimulation/ZDCSimParam.h" @@ -49,7 +50,6 @@ class DigiParser int process(const gsl::span& orbitdata, const gsl::span& bcdata, const gsl::span& chdata); - int write(); void setVerbosity(int v) { mVerbosity = v; @@ -62,36 +62,24 @@ class DigiParser private: const ModuleConfig* mModuleConfig = nullptr; /// Trigger/readout configuration object - const RecoParamZDC* mRopt = nullptr; - int mNBCAHead = 0; /// when storing triggered BC, store also mNBCAHead BCs - uint32_t mTriggerMask = 0; /// Mask of triggering channels - const RecoConfigZDC* mRecoConfigZDC = nullptr; /// CCDB configuration parameters + + void setStat(TH1* h); + void setModuleLabel(TH1* h); + int32_t mVerbosity = DbgMinimal; - std::unique_ptr mDbg = nullptr; /// Debug output file - std::unique_ptr mTDbg = nullptr; /// Debug tree - gsl::span mOrbitData; /// Reconstructed data - gsl::span mBCData; /// BC info - gsl::span mChData; /// Payload - std::vector mReco; /// Reconstructed data - std::map mOrbit; /// Information about orbit - float mOffset[NChannels]; /// Offset in current orbit - uint32_t mOffsetOrbit = 0xffffffff; /// Current orbit - uint8_t mSource[NChannels]; /// Source of pedestal - static constexpr int mNSB = TSN * NTimeBinsPerBC; /// Total number of interpolated points per bunch crossing - RecEventAux mRec; /// Debug reconstruction event + uint32_t mTriggerMask = 0; /// Mask of triggering channels + uint32_t mTDCMask[NTDCChannels] = {0}; /// Identify TDC channels in trigger pattern + uint32_t mChMask[NChannels] = {0}; /// Identify all channels in readout pattern + + std::unique_ptr mTransmitted = nullptr; + std::unique_ptr mFired = nullptr; + std::unique_ptr mBaseline[NChannels] = {nullptr}; + std::unique_ptr mCounts[NChannels] = {nullptr}; + std::unique_ptr mSignalTH[NChannels] = {nullptr}; + std::unique_ptr mBunchH[NChannels] = {nullptr}; // Bunch pattern Hit + int mNBC = 0; - int mNLonely = 0; - int mLonely[o2::constants::lhc::LHCMaxBunches] = {0}; - int mLonelyTrig[o2::constants::lhc::LHCMaxBunches] = {0}; - uint32_t mMissingPed[NChannels] = {0}; - constexpr static uint16_t mMask[NTimeBinsPerBC] = {0x0001, 0x002, 0x004, 0x008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800}; - // Configuration of interpolation for current TDC - int mNbun; // Number of adjacent bunches - int mNsam; // Number of acquired samples - int mNtot; // Total number of points in the interpolated arrays - int mIlast; // Index of last acquired sample - int mNint; // Total points in the interpolation region (-1) }; } // namespace zdc } // namespace o2 diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index 2d8bdb3544858..577d3242bbbf1 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -10,7 +10,14 @@ // or submit itself to any jurisdiction. #include +#include +#include +#include +#include +#include +#include #include "Framework/Logger.h" +#include "CommonConstants/LHCConstants.h" #include "ZDCReconstruction/DigiParser.h" #include "ZDCReconstruction/RecoParamZDC.h" @@ -19,7 +26,7 @@ namespace o2 namespace zdc { -void DigiReco::init() +void DigiParser::init() { LOG(info) << "Initialization of ZDC DigiParser"; if (!mModuleConfig) { @@ -28,462 +35,240 @@ void DigiReco::init() } mTriggerMask = mModuleConfig->getTriggerMask(); -} // init - -void DigiReco::eor() -{ - if (mTreeDbg) { - LOG(info) << "o2::zdc::DigiReco: closing debug output"; - mTDbg->Write(); - mTDbg.reset(); - mDbg->Close(); - mDbg.reset(); - } - ZDCTDCDataErr::print(); + // Update reconstruction parameters + o2::zdc::RecoParamZDC& ropt = const_cast(RecoParamZDC::Instance()); + ropt.print(); + mRopt = (o2::zdc::RecoParamZDC*)&ropt; - if (mNLonely > 0) { - LOG(warn) << "Detected " << mNLonely << " lonely bunches"; - for (int ib = 0; ib < o2::constants::lhc::LHCMaxBunches; ib++) { - if (mLonely[ib]) { - LOGF(warn, "lonely bunch %4d #times=%u #trig=%u", ib, mLonely[ib], mLonelyTrig[ib]); - } - } - } + // Fill maps channel maps for integration for (int ich = 0; ich < NChannels; ich++) { - if (mMissingPed[ich] > 0) { - LOGF(error, "Missing pedestal for ch %2d %s: %u", ich, ChannelNames[ich], mMissingPed[ich]); - } - } -} - -int DigiReco::process(const gsl::span& orbitdata, const gsl::span& bcdata, const gsl::span& chdata) -{ -#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG - LOG(info) << "________________________________________________________________________________"; - LOG(info) << __func__; -#endif - // We assume that vectors contain data from a full time frame - mOrbitData = orbitdata; - mBCData = bcdata; - mChData = chdata; - mInError = false; - - // Initialization of lookup structure for pedestals - mOrbit.clear(); - int norb = mOrbitData.size(); - if (mVerbosity >= DbgFull) { - LOG(info) << "Dump of pedestal data lookup table"; - } - // TODO: send scalers to aggregator - uint32_t scaler[NChannels] = {0}; - for (int iorb = 0; iorb < norb; iorb++) { - mOrbit[mOrbitData[iorb].ir.orbit] = iorb; - if (mVerbosity >= DbgFull) { - LOG(info) << "mOrbitData[" << mOrbitData[iorb].ir.orbit << "] = " << iorb; - } - // TODO: add only if orbit is good. Here we check only the individual scaler values - for (int ich = 0; ich < NChannels; ich++) { - if (mOrbitData[iorb].scaler[ich] <= o2::constants::lhc::LHCMaxBunches) { - scaler[ich] += mOrbitData[iorb].scaler[ich]; + // If the reconstruction parameters were not manually set + if (ropt.amod[ich] < 0 || ropt.ach[ich] < 0) { + for (int im = 0; im < NModules; im++) { + for (uint32_t ic = 0; ic < NChPerModule; ic++) { + if (mModuleConfig->modules[im].channelID[ic] == ich && mModuleConfig->modules[im].readChannel[ic]) { + ropt.amod[ich] = im; + ropt.ach[ich] = ic; + // Fill mask to identify all channels + mChMask[ich] = (0x1 << (4 * im + ic)); + goto next_ich; + } + } } + } else { + // Fill mask to identify all channels + mChMask[ich] = (0x1 << (4 * ropt.amod[ich] + ropt.ach[ich])); } - } - if (mVerbosity > DbgMinimal) { - for (int ich = 0; ich < NChannels; ich++) { - LOG(info) << ChannelNames[ich] << " cnt: " << scaler[ich]; + next_ich:; + if (mVerbosity > DbgZero) { + LOG(info) << "Channel " << ich << "(" << ChannelNames[ich] << ") mod " << ropt.amod[ich] << " ch " << ropt.ach[ich]; } } - mNBC = mBCData.size(); - mReco.clear(); - mReco.resize(mNBC); - // Initialization of reco structure - for (int ibc = 0; ibc < mNBC; ibc++) { - auto& bcr = mReco[ibc]; -#ifdef O2_ZDC_TDC_C_ARRAY - for (int itdc = 0; itdc < NTDCChannels; itdc++) { - for (int i = 0; i < MaxTDCValues; i++) { - bcr.tdcVal[itdc][i] = kMinShort; - bcr.tdcAmp[itdc][i] = kMinShort; + // Fill maps to decode the pattern of channels with hit + for (int itdc = 0; itdc < NTDCChannels; itdc++) { + // If the reconstruction parameters were not manually set + if (ropt.tmod[itdc] < 0 || ropt.tch[itdc] < 0) { + int isig = TDCSignal[itdc]; + for (int im = 0; im < NModules; im++) { + for (uint32_t ic = 0; ic < NChPerModule; ic++) { + if (mModuleConfig->modules[im].channelID[ic] == isig && mModuleConfig->modules[im].readChannel[ic]) { + // ropt.updateFromString(TString::Format("RecoParamZDC.tmod[%d]=%d;",itdc,im)); + // ropt.updateFromString(TString::Format("RecoParamZDC.tch[%d]=%d;",itdc,ic)); + ropt.tmod[itdc] = im; + ropt.tch[itdc] = ic; + // Fill mask to identify TDC channels + mTDCMask[itdc] = (0x1 << (4 * im + ic)); + goto next_itdc; + } + } } + } else { + mTDCMask[itdc] = (0x1 << (4 * ropt.tmod[itdc] + ropt.tch[itdc])); } -#endif - auto& bcd = mBCData[ibc]; - bcr.ir = bcd.ir; - int chEnt = bcd.ref.getFirstEntry(); - for (int ic = 0; ic < bcd.ref.getEntries(); ic++) { - auto& chd = mChData[chEnt]; - if (chd.id > IdDummy && chd.id < NChannels) { - bcr.ref[chd.id] = chEnt; - } - chEnt++; + next_itdc:; + if (mVerbosity > DbgZero) { + LOG(info) << "TDC " << itdc << "(" << ChannelNames[TDCSignal[itdc]] << ")" + << " mod " << ropt.tmod[itdc] << " ch " << ropt.tch[itdc]; } } - // Probably this is not necessary - // for(int isig=0; isig("ht", "Transmitted channels", NChannels, -0.5, NChannels - 0.5); } - - // Low pass filtering - if (mLowPassFilter) { - // N.B. At the moment low pass filtering is performed only on TDC - // signals and not on the rest of the signals - lowPassFilter(); - } else { - // Copy samples - for (int itdc = 0; itdc < NTDCChannels; itdc++) { - auto isig = TDCSignal[itdc]; - for (int ibc = 0; ibc < mNBC; ibc++) { - auto ref_c = mReco[ibc].ref[isig]; - if (ref_c != ZDCRefInitVal) { - for (int is = 0; is < NTimeBinsPerBC; is++) { - mReco[ibc].data[isig][is] = mChData[ref_c].data[is]; - } - } - } - } + if (mFired == nullptr) { + mFired = std::make_unique("hfired", "Fired channels", NChannels, -0.5, NChannels - 0.5); } - - if (mFullInterpolation) { - // Copy remaining channels - for (int isig = 0; isig < NChannels; isig++) { - int isig_tdc = TDCSignal[SignalTDC[isig]]; - if (isig == isig_tdc) { - // Already copied - continue; - } - for (int ibc = 0; ibc < mNBC; ibc++) { - auto ref_c = mReco[ibc].ref[isig]; - if (ref_c != ZDCRefInitVal) { - for (int is = 0; is < NTimeBinsPerBC; is++) { - mReco[ibc].data[isig][is] = mChData[ref_c].data[is]; - } - } - } + for (uint32_t ich = 0; ich < NChannels; ich++) { + if (mBaseline[ich] == nullptr) { + TString hname = TString::Format("hp_%s", ChannelNames[ich].data()); + TString htit = TString::Format("Baseline %s;Average orbit baseline", ChannelNames[ich].data()); + mBaseline[ich] = std::make_unique(hname, htit, 65536, -32768.5, 32767.5); + } + if (mCounts[ich] == nullptr) { + TString hname = TString::Format("hc_%s", ChannelNames[ich].data()); + TString htit = TString::Format("Counts %s; Orbit hits", ChannelNames[ich].data()); + mCounts[ich] = std::make_unique(hname, htit, o2::constants::lhc::LHCMaxBunches + 1, -0.5, o2::constants::lhc::LHCMaxBunches + 0.5); + } + if (mSignalTH[ich] == nullptr) { + TString hname = TString::Format("hsth_%s", ChannelNames[ich].data()); + TString htit = TString::Format("Signal %s AUTOT & Hit; Sample; ADC", ChannelNames[ich].data()); + mSignalTH[ich] = std::make_unique(hname, htit, 2 * NTimeBinsPerBC, -0.5 - NTimeBinsPerBC, NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); + } + if (mBunchH[ich] == nullptr) { + TString hname = TString::Format("hbh_%s", ChannelNames[ich].data()); + TString htit = TString::Format("Bunch %s AUTOT Hit; Sample; ADC", ChannelNames[ich].data()); + mBunchH[ich] = std::make_unique(hname, htit, 100, -0.5, 99.5, 36, -35.5, 0.5); } } +} // init - // Find consecutive bunch crossings by taking into account just the presence - // of bunch crossing data and then perform signal interpolation in the identified ranges. - // With this definition of "consecutive" bunch crossings gaps in the sample data - // may be present, therefore in the reconstruction method we take into account for signals - // that do not span the entire range - int seq_beg = 0; - int seq_end = 0; - if (mVerbosity > DbgMinimal) { - LOG(info) << "Processing ZDC reconstruction for " << mNBC << " bunch crossings"; +void DigiParser::eor() +{ + TFile* f = new TFile("ZDCDumpRaw.root", "recreate"); + if (f->IsZombie()) { + LOG(fatal) << "Cannot write to file " << f->GetName(); + return; + } + for (uint32_t i = 0; i < NChannels; i++) { + setStat(mBunchH[i].get()); + mBunchH[i]->Write(); + } + for (uint32_t i = 0; i < NChannels; i++) { + setStat(mBaseline[i].get()); + mBaseline[i]->Write(); + } + for (uint32_t i = 0; i < NChannels; i++) { + setStat(mCounts[i].get()); + mCounts[i]->Write(); } + mTransmitted->Write(); + mFired->Write(); + f->Close(); +} - // TDC reconstruction - for (int ibc = 0; ibc < mNBC; ibc++) { - auto& ir = mBCData[seq_end].ir; - auto bcd = mBCData[ibc].ir.differenceInBC(ir); - if (bcd < 0) { - LOG(error) << "Bunch order error in TDC reconstruction"; - for (int ibcdump = 0; ibcdump < mNBC; ibcdump++) { - LOG(error) << "mBCData[" << ibcdump << "] @ " << mBCData[ibcdump].ir.orbit << "." << mBCData[ibcdump].ir.bc; - } - 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; - return __LINE__; - } else if (bcd > 1) { - // Detected a gap - int rval = reconstructTDC(seq_beg, seq_end); - if (rval) { - return rval; - } +int DigiParser::process(const gsl::span& orbitdata, const gsl::span& bcdata, const gsl::span& chdata) +{ + // We assume that vectors contain data from a full time frame + int norb = orbitdata.size(); - seq_beg = ibc; - seq_end = ibc; - } else if (ibc == (mNBC - 1)) { - // Last bunch - seq_end = ibc; - int rval = reconstructTDC(seq_beg, seq_end); - if (rval) { - return rval; + uint32_t scaler[NChannels] = {0}; + for (int iorb = 0; iorb < norb; iorb++) { + for (int ich = 0; ich < NChannels; ich++) { + if (orbitdata[iorb].scaler[ich] <= o2::constants::lhc::LHCMaxBunches) { + scaler[ich] += orbitdata[iorb].scaler[ich]; + mCounts[ich]->Fill(orbitdata[iorb].scaler[ich]); + auto myped = float(orbitdata[iorb].data[ich]) * mModuleConfig->baselineFactor; + if (myped >= ADCMin && myped <= ADCMax) { + // Pedestal information is present for this channel + mBaseline[ich]->Fill(myped); + } + } else { + LOG(warn) << "Corrupted scaler data for orbit " << orbitdata[iorb].ir.orbit; } - - seq_beg = mNBC; - seq_end = mNBC; - } else { - // Look for another bunch - seq_end = ibc; } -#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG - // Here in order to avoid mixing information - mBCData[ibc].print(mTriggerMask); -#endif } - // Apply pile-up correction for TDCs to get corrected TDC amplitudes and values - correctTDCPile(); + mNBC = bcdata.size(); + std::vector> chRef; /// Cache of references + chRef.resize(mNBC); - // ADC reconstruction - seq_beg = 0; - seq_end = 0; + // Assign data references for (int ibc = 0; ibc < mNBC; ibc++) { - auto& ir = mBCData[seq_end].ir; - auto bcd = mBCData[ibc].ir.differenceInBC(ir); - if (bcd < 0) { - LOG(error) << "Bunch order error in ADC reconstruction"; - for (int ibcdump = 0; ibcdump < mNBC; ibcdump++) { - LOG(error) << "mBCData[" << ibcdump << "] @ " << mBCData[ibcdump].ir.orbit << "." << mBCData[ibcdump].ir.bc; - } - 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; - return __LINE__; - } else if (bcd > 1) { - // Detected a gap - int rval = reconstruct(seq_beg, seq_end); - if (rval != 0) { - return rval; - } - seq_beg = ibc; - seq_end = ibc; - } else if (ibc == (mNBC - 1)) { - // Last bunch - seq_end = ibc; - int rval = reconstruct(seq_beg, seq_end); - if (rval != 0) { - return rval; - } - seq_beg = mNBC; - seq_end = mNBC; - } else { - // Look for another bunch - seq_end = ibc; - } - } - return 0; -} // process - -int DigiReco::reconstruct(int ibeg, int iend) -{ -#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG - LOG(info) << "________________________________________________________________________________"; - LOG(info) << __func__ << "(" << ibeg << ", " << iend << "): " << mReco[ibeg].ir.orbit << "." << mReco[ibeg].ir.bc << " - " << mReco[iend].ir.orbit << "." << mReco[iend].ir.bc; -#endif - // Process consecutive BCs - if (ibeg == iend) { - mNLonely++; - mLonely[mReco[ibeg].ir.bc]++; - if (mBCData[ibeg].triggers != 0x0) { - mLonelyTrig[mReco[ibeg].ir.bc]++; + auto& bcd = bcdata[ibc]; + int chEnt = bcd.ref.getFirstEntry(); + for (int ich = 0; ich < NChannels; ich++) { + chRef[ibc][ich] = ZDCRefInitVal; } - // Cannot reconstruct lonely bunch - // LOG(info) << "Lonely bunch " << mReco[ibeg].ir.orbit << "." << mReco[ibeg].ir.bc; - return 0; - } -#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG - for (int ibun = ibeg; ibun <= iend; ibun++) { - printf("%d CH Mask: 0x%08x TDC data for:", ibun, mBCData[ibun].channels); - for (int itdc = 0; itdc < NTDCChannels; itdc++) { - if (mBCData[ibun].channels & mTDCMask[itdc]) { - printf(" %s", ChannelNames[TDCSignal[itdc]].data()); - } else { - printf(" "); + for (int ic = 0; ic < bcd.ref.getEntries(); ic++) { + auto& chd = chdata[chEnt]; + if (chd.id > IdDummy && chd.id < NChannels) { + chRef[ibc][chd.id] = chEnt; } + chEnt++; } - printf("\n"); } -#endif - - // After pile-up correction, find signals around main-main that satisfy condition on TDC - findSignals(ibeg, iend); - // For each calorimeter that has detects a collision at the time of main-main - // collisions we reconstruct integrated charges and fill output tree - for (int ich = 0; ich < NChannels; ich++) { - // We consder the longest sequence of acquired bunches that can be readout by - // the acquisition in case of isolated events (filling scheme with sigle bunches) - uint32_t ref[NBCReadOut] = {ZDCRefInitVal, ZDCRefInitVal, ZDCRefInitVal, ZDCRefInitVal}; - // Flags to investigate pile-up - bool hasFired[NBCReadOut] = {0}; // Channel has a TDC fired - bool hasHit[NBCReadOut] = {0}; // Channel has hit - bool hasAuto0[NBCReadOut] = {0}; // Module has Auto_0 trigger bit - bool hasAutoM[NBCReadOut] = {0}; // Module has Auto_m trigger bit - // Initialize info about previous bunches - for (int ibp = 1; ibp < 4; ibp++) { - int ibun = ibeg - ibp; - // For the time being, we cannot access previous time frame (ibun<0) - if (ibun < 0) { - break; - } - auto bcd = mBCData[ibeg].ir.differenceInBC(mBCData[ibun].ir); - if (bcd < 1) { - 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; - return __LINE__; - } - if (bcd > 3) { - break; - } - // Assignment is done taking into account bunch crossing difference - ref[bcd] = mReco[ibun].ref[ich]; - // If channel has no waverform data cannot have a hit or trigger bit assigned - // because all channels of a module are acquired if trigger condition is - // satisfied - if (ref[bcd] == ZDCRefInitVal) { - continue; - } - // This condition is not comprehensive of all pile-up sources - // chfired: Fired TDC condition related to channel (e.g. AND of TC and SUM @ main-main) - hasFired[bcd] = mReco[ibun].chfired[ich]; - // Information from hardware autotrigger is not restricted to hits in main-main - // but it may extend outside the correct bunch for signals near the bunch edges - // hasHit refers to a single channel since it is derived from ChannelDataV0::Hit - hasHit[bcd] = mBCData[ibun].triggers & mChMask[ich]; - // hasAuto0 and hasAutoM are derived from autotrigger decisions and therefore - // refer to a module (max 4 channels) and not to a single channel - ModuleTriggerMapData mt; - mt.w = mBCData[ibun].moduleTriggers[mRopt->amod[ich]]; - hasAuto0[bcd] = mt.f.Auto_0; - hasAutoM[bcd] = mt.f.Auto_m; -#ifdef ALICEO2_ZDC_DIGI_RECO_DEBUG - printf("%2d %s bcd = %d ibun = %d ibeg = %d ref = %3u %s %s %s\n", - ich, ChannelNames[ich].data(), bcd, ibun, ibeg, ref[bcd], - hasHit[bcd] ? "H" : "-", hasAuto0[bcd] ? "A0" : "--", hasAutoM[bcd] ? "AM" : "--"); -#endif - } - // Analyze all bunches - for (int ibun = ibeg; ibun <= iend; ibun++) { - updateOffsets(ibun); // Get Orbit pedestals - auto& rec = mReco[ibun]; - // Check if the corresponding TDC is fired - ref[0] = mReco[ibun].ref[ich]; - hasHit[0] = mBCData[ibun].triggers & mChMask[ich]; - ModuleTriggerMapData mt; - mt.w = mBCData[ibun].moduleTriggers[mRopt->amod[ich]]; - hasAuto0[0] = mt.f.Auto_0; - hasAutoM[0] = mt.f.Auto_m; - if (rec.chfired[ich]) { - // Check if channel data are present in payload - if (ref[0] < ZDCRefInitVal) { - // Energy reconstruction - // Compute event by event pedestal - bool hasEvPed = false; - float evPed = 0; - if (ibun > ibeg) { - auto ref_m = ref[1]; - if (mRopt->beg_ped_int[ich] >= 0 || ref_m < ZDCRefInitVal) { - for (int is = mRopt->beg_ped_int[ich]; is <= mRopt->end_ped_int[ich]; is++) { - if (is < 0) { - // Sample is in previous BC - evPed += float(mChData[ref_m].data[is + NTimeBinsPerBC]); - } else { - // Sample is in current BC - evPed += float(mChData[ref[0]].data[is]); - } + for (int ibc = 0; ibc < mNBC; ibc++) { + auto& ir = bcdata[ibc].ir; + // Check previous, current and next bunch crossings + for (int ibn = -1; ibn < 4; ibn++) { + int ibt = ibc + ibn; + if (ibt >= 0) { // Check backward and current bunch + if (ibt < mNBC) { // Check forward bunches + auto bcd = bcdata[ibt].ir.differenceInBC(ir); + if (bcd == 0) { + // Fill bunch map + for (uint32_t isig = 0; isig < NChannels; isig++) { + if (bcdata[ibc].triggers & mChMask[isig] != 0) { + double bc_d = uint32_t(ir.bc / 100); + double bc_m = uint32_t(ir.bc % 100); + mBunchH[isig]->Fill(bc_m, -bc_d); } - evPed /= float(mRopt->end_ped_int[ich] - mRopt->beg_ped_int[ich] + 1); - hasEvPed = true; } } - // Pile-up detection using trigger information allows to identify - // the presence of a signal in previous bunch and is module-wise - - // Detection of pile-up from previous bunch by comparing event pedestal with reference - // (reference can be orbit or QC). If pile-up is detected we use orbit pedestal - // instead of event pedestal - // TODO: pedestal event could have a TM.. - if (hasEvPed && (mSource[ich] == PedOr || mSource[ich] == PedQC)) { - auto pedref = mOffset[ich]; - if (evPed > pedref && (evPed - pedref) > mRopt->ped_thr_hi[ich]) { - // Anomalous offset (put a warning but use event pedestal) - rec.offPed[ich] = true; - } else if (evPed < pedref && (pedref - evPed) > mRopt->ped_thr_lo[ich]) { - // Possible presence of pile-up (will need to use orbit pedestal) - rec.pilePed[ich] = true; - } - } - float myPed = std::numeric_limits::infinity(); - // TODO: - if (hasEvPed && rec.pilePed[ich] == false) { - myPed = evPed; - rec.adcPedEv[ich] = true; - } else if (mSource[ich] == PedOr) { - myPed = mOffset[ich]; - rec.adcPedOr[ich] = true; - } else if (mSource[ich] == PedQC) { - myPed = mOffset[ich]; - rec.adcPedQC[ich] = true; - } else { - rec.adcPedMissing[ich] = true; - } - if (myPed < std::numeric_limits::infinity()) { - float sum = 0; - for (int is = mRopt->beg_int[ich]; is <= mRopt->end_int[ich]; is++) { - // TODO: pile-up correction - // TODO: manage signal positioned across boundary - sum += (myPed - float(mChData[ref[0]].data[is])); + if (bcd == ibn) { + for (uint32_t isig = 0; isig < NChannels; isig++) { + if (bcdata[ibt].triggers & mChMask[isig] != 0) { + // Fill waveform + auto ref = chRef[ibc][isig]; + if (ref != ZDCRefInitVal) { + for (int is = 0; is < NTimeBinsPerBC; is++) { + mSignalTH[isig]->Fill(-ibn * NTimeBinsPerBC + is, chdata[ref].data[is]); + } + } + } } - rec.ezdc[ich] = (sum - mRopt->adc_offset[ich]) * mRopt->energy_calib[ich]; - } else { - LOGF(warn, "%d.%-4d CH %2d %s missing pedestal", rec.ir.orbit, rec.ir.bc, ich, ChannelNames[ich].data()); - } - } else { - // This could arise from memory corruption or in the case when TDC bits are forced to 1 - // due to a broken channel. For example Sum is broken and sum TDC is forced to 1 - // Take a very small signal that triggers on one module and not the other - // 1) module 0 triggered by ZNATC is autotriggered - // 2) module 1 triggered by ZNATC is not triggered -> Sum is missing - // 3) sum TDC is forced to 1 and therefore the TDC is fired even if data are not present - // 4) you get this error flag in reconstruction - // This should happen only in case of hardware fault and signals near threshold - // This should be mitigated by having a software threshold higher than the hardware one - rec.adcPedMissing[ich] = true; - if (mVerbosity >= DbgMedium) { - LOGF(warn, "%d.%-4d CH %2d %s ADC missing, TDC present", rec.ir.orbit, rec.ir.bc, ich, ChannelNames[ich].data()); } + }else{ + break; } } - // Shift bunches by 1 taking into account bunch crossing difference - // TODO - // This is a simple shift by 1 position - if (ibun != iend) { - for (int ibcr = NBCReadOut - 1; ibcr > 0; ibcr--) { - ref[ibcr] = ref[ibcr - 1]; - hasHit[ibcr] = hasHit[ibcr - 1]; - hasAuto0[ibcr] = hasAuto0[ibcr - 1]; - hasAutoM[ibcr] = hasAutoM[ibcr - 1]; - hasFired[ibcr] = hasFired[ibcr - 1]; - } - } - } // Loop on bunches - } // Loop on channels - if (mTreeDbg) { - for (int ibun = ibeg; ibun <= iend; ibun++) { - auto& rec = mReco[ibun]; - mRec = rec; - mTDbg->Fill(); } } return 0; -} // reconstruct +} // process + +void DigiParser::setStat(TH1* h) +{ + TString hn = h->GetName(); + h->Draw(); + gPad->Update(); + TPaveStats* st = (TPaveStats*)h->GetListOfFunctions()->FindObject("stats"); + st->SetFillStyle(1001); + st->SetBorderSize(1); + if (hn.BeginsWith("hp")) { + st->SetOptStat(111111); + st->SetX1NDC(0.1); + st->SetX2NDC(0.3); + st->SetY1NDC(0.640); + st->SetY2NDC(0.9); + } else if (hn.BeginsWith("hc")) { + st->SetOptStat(1111); + st->SetX1NDC(0.799); + st->SetX2NDC(0.999); + st->SetY1NDC(0.829); + st->SetY2NDC(0.999); + } else if (hn.BeginsWith("hs") || hn.BeginsWith("hb")) { + st->SetOptStat(11); + st->SetX1NDC(0.799); + st->SetX2NDC(0.9995); + st->SetY1NDC(0.904); + st->SetY2NDC(0.999); + } +} + +void DigiParser::setModuleLabel(TH1* h) +{ + for (uint32_t isig = 0; isig < NChannels; isig++) { + h->GetXaxis()->SetBinLabel(isig+1, ChannelNames[isig].data()); + } +} } // namespace zdc } // namespace o2 diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h index d0aa027a0d5ad..64e24116c5718 100644 --- a/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h @@ -23,6 +23,7 @@ #include "Framework/Task.h" #include #include "CommonUtils/NameConf.h" +#include "ZDCReconstruction/DigiParser.h" namespace o2 { @@ -42,7 +43,7 @@ class DigitParserSpec : public o2::framework::Task void endOfStream(o2::framework::EndOfStreamContext& ec) final; private: - //DigiReco mWorker; // Reconstruction object + DigiParser mWorker; // Reconstruction object int mVerbosity = 0; // Verbosity level during recostruction bool mInitialized = false; // Connect once to CCDB during initialization TStopwatch mTimer; diff --git a/Detectors/ZDC/workflow/src/DigitParserSpec.cxx b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx index fa88af0f8436a..e31b0be694cb4 100644 --- a/Detectors/ZDC/workflow/src/DigitParserSpec.cxx +++ b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx @@ -70,7 +70,7 @@ void DigitParserSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, if (mVerbosity > DbgZero) { config->print(); } - // mWorker.setModuleConfig(config); + mWorker.setModuleConfig(config); } } @@ -80,8 +80,8 @@ void DigitParserSpec::run(ProcessingContext& pc) LOG(info) << "DigitParserSpec::run initialization"; mInitialized = true; updateTimeDependentParams(pc); - // mWorker.setVerbosity(mVerbosity); - // mWorker.init(); + mWorker.setVerbosity(mVerbosity); + mWorker.init(); } auto cput = mTimer.CpuTime(); mTimer.Start(false); @@ -90,16 +90,16 @@ void DigitParserSpec::run(ProcessingContext& pc) auto chans = pc.inputs().get>("chan"); auto peds = pc.inputs().get>("peds"); -// int rval = mWorker.process(peds, bcdata, chans); -// if (rval != 0 || mWorker.inError()) { -// LOG(warning) << bcdata.size() << " BC " << chans.size() << " CH " << peds.size() << " OD -> processing ended in ERROR @ line " << rval; -// } + int rval = mWorker.process(peds, bcdata, chans); + if (rval != 0) { + LOG(warning) << bcdata.size() << " BC " << chans.size() << " CH " << peds.size() << " OD -> processing ended in ERROR @ line " << rval; + } mTimer.Stop(); } void DigitParserSpec::endOfStream(EndOfStreamContext& ec) { - // mWorker.eor(); + mWorker.eor(); LOGF(info, "ZDC digits parsing total time: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } From 4449bf028014c1a1b3f2fadb414fb3d9c496a3d7 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Fri, 18 Oct 2024 17:27:22 +0200 Subject: [PATCH 08/19] WIP --- .../include/ZDCReconstruction/DigiParser.h | 5 ++ .../ZDC/reconstruction/src/DigiParser.cxx | 68 +++++++++++++------ .../ZDC/workflow/src/DigitParserSpec.cxx | 3 +- Detectors/ZDC/workflow/src/ParserWorkflow.cxx | 4 +- .../ZDC/workflow/src/zdc-parser-workflow.cxx | 2 +- 5 files changed, 58 insertions(+), 24 deletions(-) diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h index 43550ee8df320..b22815a3d475f 100644 --- a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h @@ -54,6 +54,9 @@ class DigiParser { mVerbosity = v; } + void setOutput(std::string output){ + mOutput = output; + } int getVerbosity() const { return mVerbosity; } void eor(); @@ -68,6 +71,8 @@ class DigiParser void setModuleLabel(TH1* h); int32_t mVerbosity = DbgMinimal; + bool mRejectPileUp = true; + std::string mOutput = "ZDCDigiParser.root"; uint32_t mTriggerMask = 0; /// Mask of triggering channels uint32_t mTDCMask[NTDCChannels] = {0}; /// Identify TDC channels in trigger pattern uint32_t mChMask[NChannels] = {0}; /// Identify all channels in readout pattern diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index 577d3242bbbf1..1b59367a12478 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -118,11 +118,11 @@ void DigiParser::init() if (mSignalTH[ich] == nullptr) { TString hname = TString::Format("hsth_%s", ChannelNames[ich].data()); TString htit = TString::Format("Signal %s AUTOT & Hit; Sample; ADC", ChannelNames[ich].data()); - mSignalTH[ich] = std::make_unique(hname, htit, 2 * NTimeBinsPerBC, -0.5 - NTimeBinsPerBC, NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); + mSignalTH[ich] = std::make_unique(hname, htit, 5 * NTimeBinsPerBC, -0.5 - 3 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); } if (mBunchH[ich] == nullptr) { TString hname = TString::Format("hbh_%s", ChannelNames[ich].data()); - TString htit = TString::Format("Bunch %s AUTOT Hit; Sample; ADC", ChannelNames[ich].data()); + TString htit = TString::Format("Bunch %s AUTOT Hit; BC units; - BC hundreds", ChannelNames[ich].data()); mBunchH[ich] = std::make_unique(hname, htit, 100, -0.5, 99.5, 36, -35.5, 0.5); } } @@ -130,7 +130,7 @@ void DigiParser::init() void DigiParser::eor() { - TFile* f = new TFile("ZDCDumpRaw.root", "recreate"); + TFile* f = new TFile(mOutput.data(), "recreate"); if (f->IsZombie()) { LOG(fatal) << "Cannot write to file " << f->GetName(); return; @@ -147,7 +147,13 @@ void DigiParser::eor() setStat(mCounts[i].get()); mCounts[i]->Write(); } + for (uint32_t i = 0; i < NChannels; i++) { + setStat(mSignalTH[i].get()); + mSignalTH[i]->Write(); + } + setModuleLabel(mTransmitted.get()); mTransmitted->Write(); + setModuleLabel(mFired.get()); mFired->Write(); f->Close(); } @@ -189,31 +195,53 @@ int DigiParser::process(const gsl::span& orbitdata, co auto& chd = chdata[chEnt]; if (chd.id > IdDummy && chd.id < NChannels) { chRef[ibc][chd.id] = chEnt; + mTransmitted->Fill(chd.id); } chEnt++; } } - for (int ibc = 0; ibc < mNBC; ibc++) { - auto& ir = bcdata[ibc].ir; - // Check previous, current and next bunch crossings - for (int ibn = -1; ibn < 4; ibn++) { - int ibt = ibc + ibn; - if (ibt >= 0) { // Check backward and current bunch - if (ibt < mNBC) { // Check forward bunches - auto bcd = bcdata[ibt].ir.differenceInBC(ir); - if (bcd == 0) { - // Fill bunch map - for (uint32_t isig = 0; isig < NChannels; isig++) { + for (uint32_t isig = 0; isig < NChannels; isig++) { + for (int ibc = 0; ibc < mNBC; ibc++) { + auto& ir = bcdata[ibc].ir; + // Identify pile-up + if (mRejectPileUp) { + bool pile = false; + // Check previous bunches + for (int ibn = -1; ibn >= -4; ibn--) { + int ibt = ibc + ibn; + if (ibt >= 0) { // Check backward and current bunch + auto bcd = bcdata[ibt].ir.differenceInBC(ir); + if (bcd == ibn) { + if (bcdata[ibt].triggers & mChMask[isig] != 0) { + pile = true; + break; + } + } else { + break; + } + } + } + if (pile) { + continue; + } + } + // Check previous, current and next bunch crossings + for (int ibn = -1; ibn < 4; ibn++) { + int ibt = ibc + ibn; + if (ibt >= 0) { // Check backward and current bunch + if (ibt < mNBC) { // Check forward bunches + auto bcd = bcdata[ibt].ir.differenceInBC(ir); + if (bcd == 0) { + // Fill bunch map if (bcdata[ibc].triggers & mChMask[isig] != 0) { double bc_d = uint32_t(ir.bc / 100); double bc_m = uint32_t(ir.bc % 100); mBunchH[isig]->Fill(bc_m, -bc_d); + mFired->Fill(isig); } } - } - if (bcd == ibn) { - for (uint32_t isig = 0; isig < NChannels; isig++) { + if (bcd == ibn) { if (bcdata[ibt].triggers & mChMask[isig] != 0) { // Fill waveform auto ref = chRef[ibc][isig]; @@ -224,9 +252,9 @@ int DigiParser::process(const gsl::span& orbitdata, co } } } + } else { + break; } - }else{ - break; } } } @@ -266,7 +294,7 @@ void DigiParser::setStat(TH1* h) void DigiParser::setModuleLabel(TH1* h) { for (uint32_t isig = 0; isig < NChannels; isig++) { - h->GetXaxis()->SetBinLabel(isig+1, ChannelNames[isig].data()); + h->GetXaxis()->SetBinLabel(isig + 1, ChannelNames[isig].data()); } } diff --git a/Detectors/ZDC/workflow/src/DigitParserSpec.cxx b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx index e31b0be694cb4..c03f48987b3c5 100644 --- a/Detectors/ZDC/workflow/src/DigitParserSpec.cxx +++ b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx @@ -55,6 +55,7 @@ DigitParserSpec::DigitParserSpec(const int verbosity) : mVerbosity(verbosity) void DigitParserSpec::init(o2::framework::InitContext& ic) { + mWorker.setOutput(ic.options().get("parser-output")); } void DigitParserSpec::updateTimeDependentParams(ProcessingContext& pc) @@ -118,7 +119,7 @@ framework::DataProcessorSpec getDigitParserSpec(const int verbosity = 0) inputs, outputs, AlgorithmSpec{adaptFromTask(verbosity)}, - o2::framework::Options{}}; + o2::framework::Options{{"parser-output", o2::framework::VariantType::String, "ZDCDigiParser.root", {"Output file name"}}}}; } } // namespace zdc diff --git a/Detectors/ZDC/workflow/src/ParserWorkflow.cxx b/Detectors/ZDC/workflow/src/ParserWorkflow.cxx index f373a7dbea2db..bb8c193262627 100644 --- a/Detectors/ZDC/workflow/src/ParserWorkflow.cxx +++ b/Detectors/ZDC/workflow/src/ParserWorkflow.cxx @@ -13,6 +13,7 @@ #include "ZDCWorkflow/ParserWorkflow.h" #include "ZDCWorkflow/DigitReaderSpec.h" +#include "ZDCWorkflow/DigitParserSpec.h" namespace o2 { @@ -22,8 +23,7 @@ namespace zdc framework::WorkflowSpec getParserWorkflow(const int verbosity) { framework::WorkflowSpec specs; - specs.emplace_back(o2::zdc::getDigitReaderSpec(false)); -// specs.emplace_back(o2::zdc::getDigitRecoSpec(verbosity, enableDebugOut, enableZDCTDCCorr, enableZDCEnergyParam, enableZDCTowerParam, enableBaselineParam)); + specs.emplace_back(o2::zdc::getDigitParserSpec(verbosity)); return specs; } diff --git a/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx b/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx index 40299744cd3d5..0847b5434a5f4 100644 --- a/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx +++ b/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx @@ -49,7 +49,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) // Update the (declared) parameters if changed from the command line o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); - auto verbosity = configcontext.options().get("reco-verbosity"); + auto verbosity = configcontext.options().get("verbosity"); auto wf = o2::zdc::getParserWorkflow(verbosity); From 98be6fcd81a3f008d96542675796cd77fe15888e Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Fri, 18 Oct 2024 18:15:01 +0200 Subject: [PATCH 09/19] Debugging line shapes and hits directly from CTF --- .../include/ZDCReconstruction/DigiParser.h | 5 +++- .../ZDC/reconstruction/src/DigiParser.cxx | 24 ++++++++++++------- .../ZDC/workflow/src/DigitParserSpec.cxx | 4 +++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h index b22815a3d475f..7e9c6fd97b3cc 100644 --- a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h @@ -54,10 +54,13 @@ class DigiParser { mVerbosity = v; } + int getVerbosity() const { return mVerbosity; } void setOutput(std::string output){ mOutput = output; } - int getVerbosity() const { return mVerbosity; } + void setRejectPileUp(bool op = true){ + mRejectPileUp = op; + } void eor(); void setModuleConfig(const ModuleConfig* moduleConfig) { mModuleConfig = moduleConfig; }; diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index 1b59367a12478..8836852ac4556 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -118,7 +118,11 @@ void DigiParser::init() if (mSignalTH[ich] == nullptr) { TString hname = TString::Format("hsth_%s", ChannelNames[ich].data()); TString htit = TString::Format("Signal %s AUTOT & Hit; Sample; ADC", ChannelNames[ich].data()); - mSignalTH[ich] = std::make_unique(hname, htit, 5 * NTimeBinsPerBC, -0.5 - 3 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); + if(mRejectPileUp){ + mSignalTH[ich] = std::make_unique(hname, htit, 3 * NTimeBinsPerBC, -0.5 - 1 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); + }else{ + mSignalTH[ich] = std::make_unique(hname, htit, 5 * NTimeBinsPerBC, -0.5 - 3 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); + } } if (mBunchH[ich] == nullptr) { TString hname = TString::Format("hbh_%s", ChannelNames[ich].data()); @@ -196,6 +200,9 @@ int DigiParser::process(const gsl::span& orbitdata, co if (chd.id > IdDummy && chd.id < NChannels) { chRef[ibc][chd.id] = chEnt; mTransmitted->Fill(chd.id); + if(bcdata[ibc].triggers & mChMask[chd.id] != 0){ + mFired->Fill(chd.id); + } } chEnt++; } @@ -206,23 +213,24 @@ int DigiParser::process(const gsl::span& orbitdata, co auto& ir = bcdata[ibc].ir; // Identify pile-up if (mRejectPileUp) { - bool pile = false; + int nsig = 0; // Check previous bunches - for (int ibn = -1; ibn >= -4; ibn--) { + for (int ibn = -4; ibn < 5; ibn++) { int ibt = ibc + ibn; if (ibt >= 0) { // Check backward and current bunch + if(ibt < mNBC){ auto bcd = bcdata[ibt].ir.differenceInBC(ir); if (bcd == ibn) { if (bcdata[ibt].triggers & mChMask[isig] != 0) { - pile = true; - break; + nsig++; } - } else { - break; } + }else{ + break; + } } } - if (pile) { + if (nsig>1) { continue; } } diff --git a/Detectors/ZDC/workflow/src/DigitParserSpec.cxx b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx index c03f48987b3c5..b761de6d2d9ff 100644 --- a/Detectors/ZDC/workflow/src/DigitParserSpec.cxx +++ b/Detectors/ZDC/workflow/src/DigitParserSpec.cxx @@ -56,6 +56,7 @@ DigitParserSpec::DigitParserSpec(const int verbosity) : mVerbosity(verbosity) void DigitParserSpec::init(o2::framework::InitContext& ic) { mWorker.setOutput(ic.options().get("parser-output")); + mWorker.setRejectPileUp((ic.options().get("reject-pileup")) != 0); } void DigitParserSpec::updateTimeDependentParams(ProcessingContext& pc) @@ -119,7 +120,8 @@ framework::DataProcessorSpec getDigitParserSpec(const int verbosity = 0) inputs, outputs, AlgorithmSpec{adaptFromTask(verbosity)}, - o2::framework::Options{{"parser-output", o2::framework::VariantType::String, "ZDCDigiParser.root", {"Output file name"}}}}; + o2::framework::Options{{"parser-output", o2::framework::VariantType::String, "ZDCDigiParser.root", {"Output file name"}}, + {"reject-pileup", o2::framework::VariantType::Int, 1, {"Reject pile-up for signal shapes 0/1"}}}}; } } // namespace zdc From 83fcade72132ab50596c570305f327839993db68 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Fri, 18 Oct 2024 22:07:40 +0200 Subject: [PATCH 10/19] Fixes --- Detectors/ZDC/reconstruction/src/DigiParser.cxx | 2 ++ Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index 8836852ac4556..3ec02679c9b12 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -156,8 +156,10 @@ void DigiParser::eor() mSignalTH[i]->Write(); } setModuleLabel(mTransmitted.get()); + mTransmitted->SetMinimum(0); mTransmitted->Write(); setModuleLabel(mFired.get()); + mFired->SetMinimum(0); mFired->Write(); f->Close(); } diff --git a/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx b/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx index 0847b5434a5f4..19e31dfa48129 100644 --- a/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx +++ b/Detectors/ZDC/workflow/src/zdc-parser-workflow.cxx @@ -33,7 +33,7 @@ void customize(std::vector& policies) void customize(std::vector& workflowOptions) { // option allowing to set parameters - workflowOptions.push_back(ConfigParamSpec{"verbosity", VariantType::Int, 0, {"verbosity level"}}); + workflowOptions.push_back(ConfigParamSpec{"verbosity-level", VariantType::Int, 0, {"verbosity level"}}); std::string keyvaluehelp("Semicolon separated key=value strings ..."); workflowOptions.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {keyvaluehelp}}); o2::raw::HBFUtilsInitializer::addConfigOption(workflowOptions); @@ -49,7 +49,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) // Update the (declared) parameters if changed from the command line o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); - auto verbosity = configcontext.options().get("verbosity"); + auto verbosity = configcontext.options().get("verbosity-level"); auto wf = o2::zdc::getParserWorkflow(verbosity); From 4882cfcf5ea158e64c17bb4c6203a216040fbfc4 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Wed, 23 Oct 2024 08:47:21 +0200 Subject: [PATCH 11/19] Fix bug in hit checking --- .../include/ZDCReconstruction/DigiParser.h | 1 - .../ZDC/reconstruction/src/DigiParser.cxx | 38 +++---------------- 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h index 7e9c6fd97b3cc..db6b2b1a2cc7a 100644 --- a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h @@ -77,7 +77,6 @@ class DigiParser bool mRejectPileUp = true; std::string mOutput = "ZDCDigiParser.root"; uint32_t mTriggerMask = 0; /// Mask of triggering channels - uint32_t mTDCMask[NTDCChannels] = {0}; /// Identify TDC channels in trigger pattern uint32_t mChMask[NChannels] = {0}; /// Identify all channels in readout pattern std::unique_ptr mTransmitted = nullptr; diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index 3ec02679c9b12..a73b93e2899ca 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -62,35 +62,7 @@ void DigiParser::init() } next_ich:; if (mVerbosity > DbgZero) { - LOG(info) << "Channel " << ich << "(" << ChannelNames[ich] << ") mod " << ropt.amod[ich] << " ch " << ropt.ach[ich]; - } - } - - // Fill maps to decode the pattern of channels with hit - for (int itdc = 0; itdc < NTDCChannels; itdc++) { - // If the reconstruction parameters were not manually set - if (ropt.tmod[itdc] < 0 || ropt.tch[itdc] < 0) { - int isig = TDCSignal[itdc]; - for (int im = 0; im < NModules; im++) { - for (uint32_t ic = 0; ic < NChPerModule; ic++) { - if (mModuleConfig->modules[im].channelID[ic] == isig && mModuleConfig->modules[im].readChannel[ic]) { - // ropt.updateFromString(TString::Format("RecoParamZDC.tmod[%d]=%d;",itdc,im)); - // ropt.updateFromString(TString::Format("RecoParamZDC.tch[%d]=%d;",itdc,ic)); - ropt.tmod[itdc] = im; - ropt.tch[itdc] = ic; - // Fill mask to identify TDC channels - mTDCMask[itdc] = (0x1 << (4 * im + ic)); - goto next_itdc; - } - } - } - } else { - mTDCMask[itdc] = (0x1 << (4 * ropt.tmod[itdc] + ropt.tch[itdc])); - } - next_itdc:; - if (mVerbosity > DbgZero) { - LOG(info) << "TDC " << itdc << "(" << ChannelNames[TDCSignal[itdc]] << ")" - << " mod " << ropt.tmod[itdc] << " ch " << ropt.tch[itdc]; + LOG(info) << "Channel " << ich << "(" << ChannelNames[ich] << ") mod " << ropt.amod[ich] << " ch " << ropt.ach[ich] << " bit " << (4 * ropt.amod[ich] + ropt.ach[ich]); } } @@ -202,7 +174,7 @@ int DigiParser::process(const gsl::span& orbitdata, co if (chd.id > IdDummy && chd.id < NChannels) { chRef[ibc][chd.id] = chEnt; mTransmitted->Fill(chd.id); - if(bcdata[ibc].triggers & mChMask[chd.id] != 0){ + if((bcdata[ibc].triggers & mChMask[chd.id]) != 0){ mFired->Fill(chd.id); } } @@ -223,7 +195,7 @@ int DigiParser::process(const gsl::span& orbitdata, co if(ibt < mNBC){ auto bcd = bcdata[ibt].ir.differenceInBC(ir); if (bcd == ibn) { - if (bcdata[ibt].triggers & mChMask[isig] != 0) { + if ((bcdata[ibt].triggers & mChMask[isig]) != 0) { nsig++; } } @@ -244,7 +216,7 @@ int DigiParser::process(const gsl::span& orbitdata, co auto bcd = bcdata[ibt].ir.differenceInBC(ir); if (bcd == 0) { // Fill bunch map - if (bcdata[ibc].triggers & mChMask[isig] != 0) { + if ((bcdata[ibc].triggers & mChMask[isig]) != 0) { double bc_d = uint32_t(ir.bc / 100); double bc_m = uint32_t(ir.bc % 100); mBunchH[isig]->Fill(bc_m, -bc_d); @@ -252,7 +224,7 @@ int DigiParser::process(const gsl::span& orbitdata, co } } if (bcd == ibn) { - if (bcdata[ibt].triggers & mChMask[isig] != 0) { + if ((bcdata[ibt].triggers & mChMask[isig]) != 0) { // Fill waveform auto ref = chRef[ibc][isig]; if (ref != ZDCRefInitVal) { From 3b36d1fceaf53776dd8e7a67b1cc2fec7e8099c8 Mon Sep 17 00:00:00 2001 From: ALICE Builder Date: Wed, 23 Oct 2024 15:57:34 +0200 Subject: [PATCH 12/19] Please consider the following formatting changes (#89) --- .../calib/include/ZDCCalib/InterCalibConfig.h | 10 ++++---- Detectors/ZDC/calib/src/InterCalib.cxx | 10 ++++---- Detectors/ZDC/calib/src/InterCalibEPN.cxx | 12 +++++----- Detectors/ZDC/calib/src/WaveformCalibData.cxx | 2 +- Detectors/ZDC/calib/src/WaveformCalibEPN.cxx | 2 +- .../include/ZDCReconstruction/DigiParser.h | 14 ++++++----- .../ZDC/reconstruction/src/DigiParser.cxx | 24 +++++++++---------- .../include/ZDCWorkflow/DigitParserSpec.h | 6 ++--- Detectors/ZDC/workflow/src/RecoReaderSpec.cxx | 2 +- 9 files changed, 42 insertions(+), 40 deletions(-) diff --git a/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h b/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h index 74148b81e16aa..3bf1e488abb3e 100644 --- a/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h +++ b/Detectors/ZDC/calib/include/ZDCCalib/InterCalibConfig.h @@ -38,11 +38,11 @@ struct InterCalibConfig { // the same as for ZPA/ZPC with no cuts double xcut_ZPA = 0; double xcut_ZPC = 0; - double rms_cut_ZP = 0; // RMS of ZP centroid can go from 0 to 8.4 cm - double towerCutLow_ZPA[4] = { 0, 0, 0, 0}; // Applied to all ZP fits except ZPI - double towerCutLow_ZPC[4] = { 0, 0, 0, 0}; // Applied to all ZP fits except ZPI - double towerCutHigh_ZPA[4] = { std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity() }; // Applied to all ZP fits except ZPI - double towerCutHigh_ZPC[4] = { std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity() }; // Applied to all ZP fits except ZPI + double rms_cut_ZP = 0; // RMS of ZP centroid can go from 0 to 8.4 cm + double towerCutLow_ZPA[4] = {0, 0, 0, 0}; // Applied to all ZP fits except ZPI + double towerCutLow_ZPC[4] = {0, 0, 0, 0}; // Applied to all ZP fits except ZPI + double towerCutHigh_ZPA[4] = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; // Applied to all ZP fits except ZPI + double towerCutHigh_ZPC[4] = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; // Applied to all ZP fits except ZPI bool cross_check = false; int nb1[NH] = {0}; /// 1D histogram: number of bins diff --git a/Detectors/ZDC/calib/src/InterCalib.cxx b/Detectors/ZDC/calib/src/InterCalib.cxx index 1dff221bc2c22..9a949506f8b25 100644 --- a/Detectors/ZDC/calib/src/InterCalib.cxx +++ b/Detectors/ZDC/calib/src/InterCalib.cxx @@ -450,19 +450,19 @@ void InterCalib::cumulate(int ih, double tc, double t1, double t2, double t3, do if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->cutHigh[ih]) { return; } - if ((ih == HidZPA || ih == HidZPAX)){ - if(t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[3]){ + if ((ih == HidZPA || ih == HidZPAX)) { + if (t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[3]) { return; } - if(t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[3]){ + if (t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[3]) { return; } } if (ih == HidZPC || ih == HidZPCX) { - if(t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[3]){ + if (t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[3]) { return; } - if(t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[3]){ + if (t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[3]) { return; } } diff --git a/Detectors/ZDC/calib/src/InterCalibEPN.cxx b/Detectors/ZDC/calib/src/InterCalibEPN.cxx index b85da2cdaa3c6..1e0ff9587019a 100644 --- a/Detectors/ZDC/calib/src/InterCalibEPN.cxx +++ b/Detectors/ZDC/calib/src/InterCalibEPN.cxx @@ -106,7 +106,7 @@ int InterCalibEPN::process(const gsl::span& RecBC, float x, rms; ev.centroidZPA(x, rms); cumulate(HidZPA, ev.EZDC(IdZPAC), ev.EZDC(IdZPA1), ev.EZDC(IdZPA2), ev.EZDC(IdZPA3), ev.EZDC(IdZPA4), 1.); - if (x < -(mInterCalibConfig->xcut_ZPA) && rms >= mInterCalibConfig->rms_cut_ZP ) { + if (x < -(mInterCalibConfig->xcut_ZPA) && rms >= mInterCalibConfig->rms_cut_ZP) { cumulate(HidZPAX, ev.EZDC(IdZPAC), ev.EZDC(IdZPA1), ev.EZDC(IdZPA2), ev.EZDC(IdZPA3), ev.EZDC(IdZPA4), 1.); } } @@ -271,19 +271,19 @@ void InterCalibEPN::cumulate(int ih, double tc, double t1, double t2, double t3, if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->cutHigh[ih]) { return; } - if ((ih == HidZPA || ih == HidZPAX)){ - if(t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[4]){ + if ((ih == HidZPA || ih == HidZPAX)) { + if (t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[4]) { return; } - if(t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[4]){ + if (t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[4]) { return; } } if (ih == HidZPC || ih == HidZPCX) { - if(t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[4]){ + if (t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[4]) { return; } - if(t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[4]){ + if (t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[4]) { return; } } diff --git a/Detectors/ZDC/calib/src/WaveformCalibData.cxx b/Detectors/ZDC/calib/src/WaveformCalibData.cxx index 634ccd7ee9c1c..a326242e21433 100644 --- a/Detectors/ZDC/calib/src/WaveformCalibData.cxx +++ b/Detectors/ZDC/calib/src/WaveformCalibData.cxx @@ -196,7 +196,7 @@ int WaveformCalibData::dumpCalib(const std::string fn) LOG(error) << "Cannot create file: " << fn; return 1; } - f->WriteObjectAny((void*)this,o2::zdc::WaveformCalibData::Class(),"WaveformCalibData"); + f->WriteObjectAny((void*)this, o2::zdc::WaveformCalibData::Class(), "WaveformCalibData"); f->Close(); cwd->cd(); return 0; diff --git a/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx b/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx index b418046cfdae0..02e9bc15a933f 100644 --- a/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx +++ b/Detectors/ZDC/calib/src/WaveformCalibEPN.cxx @@ -133,7 +133,7 @@ int WaveformCalibEPN::endOfRun() mData.getEntries(is), mConfig->cutLow[is], mConfig->cutHigh[is], itdc, mConfig->cutTimeLow[itdc], mConfig->cutTimeHigh[itdc], mData.getFirstValid(is), mData.mPeak, mData.getLastValid(is)); - }else{ + } else { LOGF(info, "Waveform %2d %s with %10d events and cuts AMP:(%g:%g) TDC:%d:(%g:%g)", is, ChannelNames[is].data(), mData.getEntries(is), mConfig->cutLow[is], mConfig->cutHigh[is], itdc, mConfig->cutTimeLow[itdc], mConfig->cutTimeHigh[itdc]); diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h index db6b2b1a2cc7a..0fc3abb82e1c8 100644 --- a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h @@ -55,10 +55,12 @@ class DigiParser mVerbosity = v; } int getVerbosity() const { return mVerbosity; } - void setOutput(std::string output){ + void setOutput(std::string output) + { mOutput = output; } - void setRejectPileUp(bool op = true){ + void setRejectPileUp(bool op = true) + { mRejectPileUp = op; } void eor(); @@ -66,8 +68,8 @@ class DigiParser void setModuleConfig(const ModuleConfig* moduleConfig) { mModuleConfig = moduleConfig; }; const ModuleConfig* getModuleConfig() { return mModuleConfig; }; -private: - const ModuleConfig* mModuleConfig = nullptr; /// Trigger/readout configuration object + private: + const ModuleConfig* mModuleConfig = nullptr; /// Trigger/readout configuration object const RecoParamZDC* mRopt = nullptr; void setStat(TH1* h); @@ -76,8 +78,8 @@ class DigiParser int32_t mVerbosity = DbgMinimal; bool mRejectPileUp = true; std::string mOutput = "ZDCDigiParser.root"; - uint32_t mTriggerMask = 0; /// Mask of triggering channels - uint32_t mChMask[NChannels] = {0}; /// Identify all channels in readout pattern + uint32_t mTriggerMask = 0; /// Mask of triggering channels + uint32_t mChMask[NChannels] = {0}; /// Identify all channels in readout pattern std::unique_ptr mTransmitted = nullptr; std::unique_ptr mFired = nullptr; diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index a73b93e2899ca..cf556a80697f2 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -90,9 +90,9 @@ void DigiParser::init() if (mSignalTH[ich] == nullptr) { TString hname = TString::Format("hsth_%s", ChannelNames[ich].data()); TString htit = TString::Format("Signal %s AUTOT & Hit; Sample; ADC", ChannelNames[ich].data()); - if(mRejectPileUp){ + if (mRejectPileUp) { mSignalTH[ich] = std::make_unique(hname, htit, 3 * NTimeBinsPerBC, -0.5 - 1 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); - }else{ + } else { mSignalTH[ich] = std::make_unique(hname, htit, 5 * NTimeBinsPerBC, -0.5 - 3 * NTimeBinsPerBC, 2 * NTimeBinsPerBC - 0.5, ADCRange, ADCMin - 0.5, ADCMax + 0.5); } } @@ -174,7 +174,7 @@ int DigiParser::process(const gsl::span& orbitdata, co if (chd.id > IdDummy && chd.id < NChannels) { chRef[ibc][chd.id] = chEnt; mTransmitted->Fill(chd.id); - if((bcdata[ibc].triggers & mChMask[chd.id]) != 0){ + if ((bcdata[ibc].triggers & mChMask[chd.id]) != 0) { mFired->Fill(chd.id); } } @@ -192,19 +192,19 @@ int DigiParser::process(const gsl::span& orbitdata, co for (int ibn = -4; ibn < 5; ibn++) { int ibt = ibc + ibn; if (ibt >= 0) { // Check backward and current bunch - if(ibt < mNBC){ - auto bcd = bcdata[ibt].ir.differenceInBC(ir); - if (bcd == ibn) { - if ((bcdata[ibt].triggers & mChMask[isig]) != 0) { - nsig++; + if (ibt < mNBC) { + auto bcd = bcdata[ibt].ir.differenceInBC(ir); + if (bcd == ibn) { + if ((bcdata[ibt].triggers & mChMask[isig]) != 0) { + nsig++; + } } + } else { + break; } - }else{ - break; - } } } - if (nsig>1) { + if (nsig > 1) { continue; } } diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h index 64e24116c5718..e7e64b52862e7 100644 --- a/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/DigitParserSpec.h @@ -43,9 +43,9 @@ class DigitParserSpec : public o2::framework::Task void endOfStream(o2::framework::EndOfStreamContext& ec) final; private: - DigiParser mWorker; // Reconstruction object - int mVerbosity = 0; // Verbosity level during recostruction - bool mInitialized = false; // Connect once to CCDB during initialization + DigiParser mWorker; // Reconstruction object + int mVerbosity = 0; // Verbosity level during recostruction + bool mInitialized = false; // Connect once to CCDB during initialization TStopwatch mTimer; }; diff --git a/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx b/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx index 0d23527fcc857..33b2b59d8247b 100644 --- a/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx +++ b/Detectors/ZDC/workflow/src/RecoReaderSpec.cxx @@ -66,7 +66,7 @@ void RecoReader::run(ProcessingContext& pc) auto ent = mTree->GetReadEntry() + 1; assert(ent < mTree->GetEntries()); // this should not happen mTree->GetEntry(ent); - LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos " << WaveformData.size() << " Waveform chunks"; + LOG(info) << "ZDCRecoReader pushed " << RecBC.size() << " b.c. " << Energy.size() << " Energies " << TDCData.size() << " TDCs " << Info.size() << " Infos " << WaveformData.size() << " Waveform chunks"; pc.outputs().snapshot(Output{"ZDC", "BCREC", 0}, RecBC); pc.outputs().snapshot(Output{"ZDC", "ENERGY", 0}, Energy); pc.outputs().snapshot(Output{"ZDC", "TDCDATA", 0}, TDCData); From c7dbdb17eb5d4075f9e425db16515b1c1cf88b05 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Wed, 23 Oct 2024 17:02:42 +0200 Subject: [PATCH 13/19] Fix missing case --- Detectors/ZDC/reconstruction/src/DigiReco.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Detectors/ZDC/reconstruction/src/DigiReco.cxx b/Detectors/ZDC/reconstruction/src/DigiReco.cxx index 397e2aef63f1c..c9981f8aa4f15 100644 --- a/Detectors/ZDC/reconstruction/src/DigiReco.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiReco.cxx @@ -68,6 +68,9 @@ void DigiReco::init() } } } + }else{ + // Fill mask to identify TDC channels + mTDCMask[itdc] = (0x1 << (4 * ropt.tmod[itdc] + ropt.tch[itdc])); } next_itdc:; if (mVerbosity > DbgZero) { @@ -356,6 +359,9 @@ void DigiReco::init() } } } + } else { + // Fill mask to identify all channels + mChMask[ich] = (0x1 << (4 * ropt.amod[ich] + ropt.ach[ich])); } next_ich:; if (mVerbosity > DbgZero) { From 375c7b1c65c53a4ae195727c0469fc8d53b273bd Mon Sep 17 00:00:00 2001 From: ALICE Builder Date: Wed, 23 Oct 2024 17:04:11 +0200 Subject: [PATCH 14/19] Please consider the following formatting changes (#90) --- Detectors/ZDC/reconstruction/src/DigiReco.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ZDC/reconstruction/src/DigiReco.cxx b/Detectors/ZDC/reconstruction/src/DigiReco.cxx index c9981f8aa4f15..50a8ceeb13691 100644 --- a/Detectors/ZDC/reconstruction/src/DigiReco.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiReco.cxx @@ -68,7 +68,7 @@ void DigiReco::init() } } } - }else{ + } else { // Fill mask to identify TDC channels mTDCMask[itdc] = (0x1 << (4 * ropt.tmod[itdc] + ropt.tch[itdc])); } From f2910704332169c4f2ec89dc124bc24e15a32a91 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Sun, 17 Nov 2024 15:03:32 +0100 Subject: [PATCH 15/19] Small updates --- .../include/ZDCReconstruction/DigiParser.h | 3 +++ Detectors/ZDC/reconstruction/src/DigiParser.cxx | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h index 0fc3abb82e1c8..41e389403aa73 100644 --- a/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h +++ b/Detectors/ZDC/reconstruction/include/ZDCReconstruction/DigiParser.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "Framework/Logger.h" @@ -74,6 +75,7 @@ class DigiParser void setStat(TH1* h); void setModuleLabel(TH1* h); + void setModuleLabel(TAxis* ax); int32_t mVerbosity = DbgMinimal; bool mRejectPileUp = true; @@ -87,6 +89,7 @@ class DigiParser std::unique_ptr mCounts[NChannels] = {nullptr}; std::unique_ptr mSignalTH[NChannels] = {nullptr}; std::unique_ptr mBunchH[NChannels] = {nullptr}; // Bunch pattern Hit + std::unique_ptr mAlignment; int mNBC = 0; }; diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index cf556a80697f2..7b85faec3490e 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -76,6 +76,9 @@ void DigiParser::init() if (mFired == nullptr) { mFired = std::make_unique("hfired", "Fired channels", NChannels, -0.5, NChannels - 0.5); } + if (mAlignment == nullptr) { + mAlignment = std::make_unique("hmap", "Map of fired channels", o2::constants::lhc::LHCMaxBunches, -0.5, o2::constants::lhc::LHCMaxBunches-0.5, NChannels, -0.5, NChannels - 0.5); + } for (uint32_t ich = 0; ich < NChannels; ich++) { if (mBaseline[ich] == nullptr) { TString hname = TString::Format("hp_%s", ChannelNames[ich].data()); @@ -133,6 +136,9 @@ void DigiParser::eor() setModuleLabel(mFired.get()); mFired->SetMinimum(0); mFired->Write(); + setModuleLabel((mAlignment.get())->GetYaxis()); + mAlignment->SetMinimum(0); + mAlignment->Write(); f->Close(); } @@ -221,6 +227,7 @@ int DigiParser::process(const gsl::span& orbitdata, co double bc_m = uint32_t(ir.bc % 100); mBunchH[isig]->Fill(bc_m, -bc_d); mFired->Fill(isig); + mAlignment->Fill(ir.bc, isig); } } if (bcd == ibn) { @@ -280,5 +287,12 @@ void DigiParser::setModuleLabel(TH1* h) } } +void DigiParser::setModuleLabel(TAxis* ax) +{ + for (uint32_t isig = 0; isig < NChannels; isig++) { + ax->SetBinLabel(isig + 1, ChannelNames[isig].data()); + } +} + } // namespace zdc } // namespace o2 From d436097eb6330d94139ab971814efc93cbd65a91 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Sun, 17 Nov 2024 15:10:25 +0100 Subject: [PATCH 16/19] Comments --- Detectors/ZDC/calib/src/InterCalib.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Detectors/ZDC/calib/src/InterCalib.cxx b/Detectors/ZDC/calib/src/InterCalib.cxx index 9a949506f8b25..150bc36a22a63 100644 --- a/Detectors/ZDC/calib/src/InterCalib.cxx +++ b/Detectors/ZDC/calib/src/InterCalib.cxx @@ -496,6 +496,8 @@ void InterCalib::fcn(int& npar, double* gin, double& chi, double* par, int iflag chi += (i == 0 ? par[i] : -par[i]) * (j == 0 ? par[j] : -par[j]) * mAdd[i][j]; } } + // Following line modifies the chisquare computation to perform orthogonal + // least squares instead of ordinary least squares minimization chi = chi / (1 + par[1] * par[1] + par[2] * par[2] + par[3] * par[3] + par[4] * par[4]); } From 48edf2a867991781d39dedbde423fbb2157d4fd9 Mon Sep 17 00:00:00 2001 From: ALICE Builder Date: Tue, 3 Dec 2024 22:02:15 +0100 Subject: [PATCH 17/19] Please consider the following formatting changes (#91) --- Detectors/ZDC/reconstruction/src/DigiParser.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Detectors/ZDC/reconstruction/src/DigiParser.cxx b/Detectors/ZDC/reconstruction/src/DigiParser.cxx index 7b85faec3490e..1259c9e6e1150 100644 --- a/Detectors/ZDC/reconstruction/src/DigiParser.cxx +++ b/Detectors/ZDC/reconstruction/src/DigiParser.cxx @@ -77,7 +77,7 @@ void DigiParser::init() mFired = std::make_unique("hfired", "Fired channels", NChannels, -0.5, NChannels - 0.5); } if (mAlignment == nullptr) { - mAlignment = std::make_unique("hmap", "Map of fired channels", o2::constants::lhc::LHCMaxBunches, -0.5, o2::constants::lhc::LHCMaxBunches-0.5, NChannels, -0.5, NChannels - 0.5); + mAlignment = std::make_unique("hmap", "Map of fired channels", o2::constants::lhc::LHCMaxBunches, -0.5, o2::constants::lhc::LHCMaxBunches - 0.5, NChannels, -0.5, NChannels - 0.5); } for (uint32_t ich = 0; ich < NChannels; ich++) { if (mBaseline[ich] == nullptr) { From 9bb6f231385bb007b879af4e6c1dd24fa619ec51 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Fri, 6 Dec 2024 11:53:52 +0100 Subject: [PATCH 18/19] Fix compilation error --- Detectors/ZDC/calib/src/InterCalibEPN.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Detectors/ZDC/calib/src/InterCalibEPN.cxx b/Detectors/ZDC/calib/src/InterCalibEPN.cxx index 1e0ff9587019a..2f7fd5f26ebf9 100644 --- a/Detectors/ZDC/calib/src/InterCalibEPN.cxx +++ b/Detectors/ZDC/calib/src/InterCalibEPN.cxx @@ -272,18 +272,18 @@ void InterCalibEPN::cumulate(int ih, double tc, double t1, double t2, double t3, return; } if ((ih == HidZPA || ih == HidZPAX)) { - if (t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[4]) { + if (t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[3]) { return; } - if (t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[4]) { + if (t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[3]) { return; } } if (ih == HidZPC || ih == HidZPCX) { - if (t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[4]) { + if (t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[3]) { return; } - if (t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[4]) { + if (t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[3]) { return; } } From da7f23d542cf1b974d934ea74a41660f14272eb7 Mon Sep 17 00:00:00 2001 From: Pietro Cortese Date: Mon, 9 Dec 2024 11:40:29 +0100 Subject: [PATCH 19/19] Just to force new tests --- Detectors/ZDC/calib/src/InterCalib.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Detectors/ZDC/calib/src/InterCalib.cxx b/Detectors/ZDC/calib/src/InterCalib.cxx index 150bc36a22a63..f267be48761e5 100644 --- a/Detectors/ZDC/calib/src/InterCalib.cxx +++ b/Detectors/ZDC/calib/src/InterCalib.cxx @@ -496,8 +496,8 @@ void InterCalib::fcn(int& npar, double* gin, double& chi, double* par, int iflag chi += (i == 0 ? par[i] : -par[i]) * (j == 0 ? par[j] : -par[j]) * mAdd[i][j]; } } - // Following line modifies the chisquare computation to perform orthogonal - // least squares instead of ordinary least squares minimization + // Following line modifies the chisquare computation (sum of squares of residuals) + // to perform orthogonal least squares instead of ordinary least squares minimization chi = chi / (1 + par[1] * par[1] + par[2] * par[2] + par[3] * par[3] + par[4] * par[4]); }