17#include <TDirectory.h>
19#include <TPaveStats.h>
32std::mutex InterCalib::mMtx;
36 if (mInterCalibConfig ==
nullptr) {
37 LOG(fatal) <<
"o2::zdc::InterCalib: missing configuration object";
44 if (opt.debugOutput ==
true) {
49 auto* cfg = mInterCalibConfig;
52 for(
int ih=0; ih<
NH; ih++){
56 mHUnc[
NH+ih] =
nullptr;
69 const gsl::span<const o2::zdc::ZDCEnergy>& Energy,
70 const gsl::span<const o2::zdc::ZDCTDCData>& TDCData,
71 const gsl::span<const uint16_t>& Info)
77 LOG(info) <<
"o2::zdc::InterCalib processing " << RecBC.size() <<
" b.c.";
80 ev.
init(RecBC, Energy, TDCData, Info);
84 for (uint16_t info : decodedInfo) {
85 uint8_t ch = (info >> 10) & 0x1f;
86 uint16_t code = info & 0x03ff;
131 LOGF(info,
"Computing intercalibration coefficients");
133 if (mSaveDebugHistos) {
137 for (
int ih = 0; ih <
NH; ih++) {
139 if (!mInterCalibConfig->
enabled[ih]) {
140 LOGF(info,
"DISABLED processing of RUN3 data for ih = %d: %s", ih,
InterCalibData::DN[ih]);
142 }
else if (mData.
mSum[ih][5][5] >= mInterCalibConfig->
min_e[ih]) {
145 LOGF(error,
"FAILED processing RUN3 data for ih = %d: %s", ih,
InterCalibData::DN[ih]);
152 LOGF(info,
"FAILED processing RUN3 data for ih = %d: %s: TOO FEW EVENTS: %g", ih,
InterCalibData::DN[ih], mData.
mSum[ih][5][5]);
162 std::map<std::string, std::string> md;
163 md[
"config"] = mInterCalibConfig->
desc;
166 if (starting >= 10000) {
167 starting = starting - 10000;
169 uint64_t stopping = mData.
mCTimeEnd + 10000;
182void InterCalib::assign(
int ih,
bool ismod)
198 }
else if (ih == 1) {
201 }
else if (ih == 2) {
204 }
else if (ih == 3) {
207 }
else if (ih == 4) {
210 }
else if (ih == 5) {
213 LOG(warn) <<
"InterCalib::assign is not implemented for coefficient ih = " << ih;
215 }
else if (ih == 6) {
218 LOG(warn) <<
"InterCalib::assign is not implemented for coefficient ih = " << ih;
220 }
else if (ih == 7 || ih == 8) {
224 }
else if (ih == 8) {
239 LOG(fatal) <<
"InterCalib::assign accessing not existing ih = " << ih;
241 for (
int iid = 0; iid < nid; iid++) {
247 val =
val * mPar[ih][iid + 1];
252 }
else if (mVerbosity >
DbgZero) {
276 THnSparse* hs = (THnSparse*)gROOT->FindObject(hname);
278 LOGF(error,
"Not found: %s\n", hname);
281 if (!hs->InheritsFrom(THnSparse::Class())) {
282 LOGF(error,
"Not a THnSparse: %s\n", hname);
291 if (hn.EqualTo(
"hZNA")) {
293 }
else if (hn.EqualTo(
"hZPA")) {
295 }
else if (hn.EqualTo(
"hZNC")) {
297 }
else if (hn.EqualTo(
"hZPC")) {
299 }
else if (hn.EqualTo(
"hZEM")) {
301 }
else if (hn.EqualTo(
"hZNI")) {
303 }
else if (hn.EqualTo(
"hZPI")) {
305 }
else if (hn.EqualTo(
"hZPAX")) {
307 }
else if (hn.EqualTo(
"hZPCX")) {
310 LOGF(error,
"Not recognized histogram name: %s\n", hname);
314 const int32_t dim = 6;
317 int64_t nb = hs->GetNbins();
319 LOGF(info,
"Histogram %s has %ld bins\n", hname, nb);
320 double cutl = mInterCalibConfig->
cutLow[ih];
321 double cuth = mInterCalibConfig->
cutHigh[ih];
323 for (int64_t
i = 0;
i < nb;
i++) {
324 double cont = hs->GetBinContent(
i,
bins);
328 for (int32_t d = 0; d < dim; ++d) {
329 x[d] = hs->GetAxis(d)->GetBinCenter(
bins[d]);
331 if (TMath::Nint(
x[5] - ic) == 0 &&
x[0] > cutl &&
x[0] < cuth) {
339 LOGF(error,
"FAILED processing RUN2 data for %s ih = %d\n", hname, ih);
341 LOGF(info,
"Processed RUN2 data for %s ih = %d\n", hname, ih);
344 LOGF(info,
"Trigger class selection %d and %d bins %g events and cuts (%g:%g): %ld\n", ic, nn, contt, cutl, cuth);
350 auto* cfg = mInterCalibConfig;
352 if(ih == 0){ mHCorr[ih] = std::make_unique<TH1F>(
"hZNASc",
"ZNA sum corr",cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]); }
353 if(ih == 1){ mHCorr[ih] = std::make_unique<TH1F>(
"hZPASc",
"ZPA sum corr",cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]); }
354 if(ih == 2){ mHCorr[ih] = std::make_unique<TH1F>(
"hZNCSc",
"ZNC sum corr",cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]); }
355 if(ih == 3){ mHCorr[ih] = std::make_unique<TH1F>(
"hZPCSc",
"ZPC sum corr",cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]); }
356 if(ih == 4){ mHCorr[ih] = std::make_unique<TH1F>(
"hZEM2c",
"ZEM2" ,cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]); }
357 if(ih == 0){ mCCorr[ih] = std::make_unique<TH2F>(
"cZNAc",
"ZNA;TC;SUM corr",cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih],cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih]); }
358 if(ih == 1){ mCCorr[ih] = std::make_unique<TH2F>(
"cZPAc",
"ZPA;TC;SUM corr",cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih],cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih]); }
359 if(ih == 2){ mCCorr[ih] = std::make_unique<TH2F>(
"cZNCc",
"ZNC;TC;SUM corr",cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih],cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih]); }
360 if(ih == 3){ mCCorr[ih] = std::make_unique<TH2F>(
"cZPCc",
"ZPC;TC;SUM corr",cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih],cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih]); }
361 if(ih == 4){ mCCorr[ih] = std::make_unique<TH2F>(
"cZEMc",
"ZEM;ZEM1;ZEM2 corr",cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih],cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih]); }
363 const int32_t dim = 6;
366 int64_t nb = hs->GetNbins();
367 double cutl = cfg->cutLow[ih];
368 double cuth = cfg->cutHigh[ih];
369 double c1 = mPar[ih][1];
370 double c2 = mPar[ih][2];
371 double c3 = mPar[ih][3];
372 double c4 = mPar[ih][4];
373 double of = mPar[ih][5];
374 for (int64_t
i = 0;
i < nb;
i++) {
375 double cont = hs->GetBinContent(
i,
bins);
379 for (int32_t d = 0; d < dim; ++d) {
380 x[d] = hs->GetAxis(d)->GetBinCenter(
bins[d]);
382 if (TMath::Nint(
x[5] - ic) == 0 &&
x[0] > cutl &&
x[0] < cuth) {
383 double sumquad =
c1 *
x[1] +
c2 *
x[2] + c3 *
x[3] + c4 *
x[4] +
of;
384 mHCorr[ih]->Fill(sumquad, cont);
385 mCCorr[ih]->Fill(
x[0], sumquad, cont);
394 if (ih >= 0 && ih <
NH) {
398 for (int32_t ii = ihstart; ii < ihstop; ii++) {
399 for (int32_t
i = 0;
i <
NPAR;
i++) {
400 for (int32_t
j = 0;
j <
NPAR;
j++) {
428 if (ih >= 0 && ih < nh) {
431 LOG(error) <<
"InterCalib::add: unsupported FlatHisto1D " << ih;
443 LOG(error) <<
"InterCalib::add: unsupported FlatHisto2D " << ih;
449 constexpr double minfty = -std::numeric_limits<double>::infinity();
450 if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->
cutHigh[ih]) {
454 if (t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[3]) {
462 if (t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[3]) {
469 double val[
NPAR] = {tc,
t1, t2, t3, t4, 1};
470 if (tc > minfty &&
t1 > minfty && t2 > minfty && t3 > minfty && t4 > minfty) {
471 for (int32_t
i = 0;
i <
NPAR;
i++) {
472 for (int32_t
j =
i;
j <
NPAR;
j++) {
481 mHUnc[ih]->fill(sumquad,
w);
483 if (mHUnc[ih +
NH]) {
484 mHUnc[ih +
NH]->fill(
val[0]);
486 mCUnc[ih]->fill(
val[0], sumquad,
w);
494 for (int32_t
i = 0;
i <
NPAR;
i++) {
495 for (int32_t
j = 0;
j <
NPAR;
j++) {
496 chi += (
i == 0 ? par[
i] : -par[
i]) * (
j == 0 ? par[
j] : -par[
j]) *
mAdd[
i][
j];
501 chi = chi / (1 + par[1] * par[1] + par[2] * par[2] + par[3] * par[3] + par[4] * par[4]);
509 for (int32_t
i = 0;
i <
NPAR;
i++) {
510 for (int32_t
j = 0;
j <
NPAR;
j++) {
520 double l_bnd = mInterCalibConfig->
l_bnd[ih];
521 double u_bnd = mInterCalibConfig->
u_bnd[ih];
524 mMn[ih] = std::make_unique<TMinuit>(
NPAR);
525 mMn[ih]->SetFCN(
fcn);
528 mMn[ih]->mnparm(0,
"c0", 1., 0., 1., 1., ierflg);
534 mMn[ih]->mnparm(1,
"c1",
start, step, l_bnd, u_bnd, ierflg);
546 mMn[ih]->mnparm(2,
"c2",
start, step, l_bnd, u_bnd, ierflg);
549 mMn[ih]->mnparm(3,
"c3",
start, step, l_bnd, u_bnd, ierflg);
550 mMn[ih]->mnparm(4,
"c4",
start, step, l_bnd, u_bnd, ierflg);
553 l_bnd = mInterCalibConfig->
l_bnd_o[ih];
554 u_bnd = mInterCalibConfig->
u_bnd_o[ih];
556 step = mInterCalibConfig->
step_o[ih];
557 mMn[ih]->mnparm(5,
"offset",
start, step, l_bnd, u_bnd, ierflg);
558 mMn[ih]->mnexcm(
"MIGRAD", arglist, 0, ierflg);
559 for (Int_t
i = 0;
i <
NPAR;
i++) {
560 mMn[ih]->GetParameter(
i, mPar[ih][
i], mErr[ih][
i]);
563 if (ih == 1 || ih == 3 || ih == 7 || ih == 8) {
564 for (
int iretry = 0; iretry < 2; iretry++) {
566 const char* parn[5] = {
"c0fix",
"c1fix",
"c2fix",
"c3fix",
"c4fix"};
567 l_bnd = mInterCalibConfig->
l_bnd[ih];
568 u_bnd = mInterCalibConfig->
u_bnd[ih];
569 for (
int i = 1;
i <= 4;
i++) {
570 if (TMath::Abs(mPar[ih][
i] - l_bnd) < 1e-2 || TMath::Abs(mPar[ih][
i] - u_bnd) < 1e-2) {
572 LOG(warn) <<
"ih=" << ih <<
" par " <<
i <<
" too close to boundaries";
573 if (ih == 1 || ih == 7) {
575 mMn[ih]->mnparm(
i, parn[
i], mInterCalibConfig->
start[ih], 0, l_bnd, u_bnd, ierflg);
576 }
else if (ih == 3 || ih == 8) {
578 mMn[ih]->mnparm(
i, parn[
i], mInterCalibConfig->
start[ih], 0, l_bnd, u_bnd, ierflg);
580 LOG(fatal) <<
"ERROR on InterCalib minimization ih=" << ih;
585 LOG(warn) <<
"Retry minimization on ih=" << ih;
586 mMn[ih]->mnexcm(
"MIGRAD", arglist, 0, ierflg);
587 for (Int_t
i = 0;
i <
NPAR;
i++) {
588 mMn[ih]->GetParameter(
i, mPar[ih][
i], mErr[ih][
i]);
602 TDirectory* cwd = gDirectory;
603 TFile*
f =
new TFile(fn.data(),
"recreate");
605 LOG(error) <<
"Cannot create file: " << fn;
608 for (int32_t ih = 0; ih < (2 *
NH); ih++) {
612 p->Write(
"", TObject::kOverwrite);
615 for (int32_t ih = 0; ih <
NH; ih++) {
619 p->Write(
"", TObject::kOverwrite);
623 for (int32_t ih = 0; ih <
NH; ih++) {
625 mHCorr[ih]->Write(
"", TObject::kOverwrite);
628 for (int32_t ih = 0; ih <
NH; ih++) {
630 mCCorr[ih]->Write(
"", TObject::kOverwrite);
634 const char* mntit[
NH] = {
"mZNA",
"mZPA",
"mZNC",
"mZPC",
"mZEM",
"mZNI",
"mZPI",
"mZPAX",
"mZPCX"};
635 for (int32_t ih = 0; ih <
NH; ih++) {
637 mMn[ih]->Write(mntit[ih], TObject::kOverwrite);
ZDC calibration common parameters.
bool const GPUTPCGMMerger::trackCluster * c1
bool const GPUTPCGMMerger::trackCluster const clcomparestruct * c2
Intercalibration intermediate data.
static std::string generateFileName(const std::string &inp)
void setStartValidityTimestamp(long start)
void setFileName(const std::string &nm)
void setPath(const std::string &path)
void setEndValidityTimestamp(long end)
void setObjectType(const std::string &tp)
void setMetaData(const std::map< std::string, std::string > &md)
static const CalibParamZDC & Instance()
static constexpr int HidZEM
void replay(int ih, THnSparse *hs, int ic)
static constexpr int HidZNA
static double mAdd[NPAR][NPAR]
void cumulate(int ih, double tc, double t1, double t2, double t3, double t4, double w)
static void fcn(int &npar, double *gin, double &chi, double *par, int iflag)
Temporary copy of cumulated sums.
static constexpr int HidZPI
void setSaveDebugHistos()
static constexpr const char * mHUncT[2 *NH]
void add(int ih, o2::dataformats::FlatHisto1D< float > &h1)
int saveDebugHistos(const std::string fn="ZDCInterCalib.root")
static constexpr const char * mHUncN[2 *NH]
static constexpr int NPAR
static constexpr int HidZPC
static constexpr int HidZNI
static constexpr int HidZNC
static constexpr int HidZPA
static constexpr int HidZPAX
int process(const gsl::span< const o2::zdc::BCRecData > &bcrec, const gsl::span< const o2::zdc::ZDCEnergy > &energy, const gsl::span< const o2::zdc::ZDCTDCData > &tdc, const gsl::span< const uint16_t > &info)
static constexpr int HidZPCX
static constexpr const char * mCUncT[NH]
static constexpr const char * mCUncN[NH]
GLubyte GLubyte GLubyte GLubyte w
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Defining PrimaryVertex explicitly as messageable.
constexpr uint32_t MaskZNA
constexpr uint32_t MaskZNC
constexpr uint32_t MaskZEM
constexpr uint32_t MaskZPA
const std::string CCDBPathTowerCalib
constexpr std::string_view ChannelNames[]
constexpr uint32_t MaskZPC
uint16_t bc
bunch crossing ID of interaction
static std::string getClassName(const T &obj)
get the class name of the object
double towerCutHigh_ZPA[4]
bool enabled[NH]
ZNA, ZPA, ZNC, ZPC, ZEM, ZNI, ZPI, ZPAX, ZPCX.
double towerCutHigh_ZPC[4]
double mSum[NH][NPAR][NPAR]
ZNA, ZPA, ZNC, ZPC, ZEM, ZNI, ZPI, ZPAX, ZPCX.
static constexpr int NH
Dimension of matrix (1 + 4 coefficients + offset)
uint64_t mCTimeEnd
Time of processed time frame.
static constexpr const char * DN[NH]
Time of processed time frame.
uint64_t mCTimeBeg
Cumulated sums.
BCRecData mCurB
End of sequence.
float EZDC(uint8_t ich) const
uint32_t ezdcDecoded
pattern of channels acquired
void init(const std::vector< o2::zdc::BCRecData > *RecBC, const std::vector< o2::zdc::ZDCEnergy > *Energy, const std::vector< o2::zdc::ZDCTDCData > *TDCData, const std::vector< uint16_t > *Info)
Trigger mask for printout.
const std::vector< uint16_t > & getDecodedInfo()
float getTowerCalib(uint32_t ich) const
void setTowerCalib(uint32_t ich, float val, bool ismodified=true)
std::array< bool, NChannels > modified
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"