Project
Loading...
Searching...
No Matches
InterCalib.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <TROOT.h>
13#include <TFile.h>
14#include <TPad.h>
15#include <TString.h>
16#include <TStyle.h>
17#include <TDirectory.h>
19#include <TPaveStats.h>
20#include <TAxis.h>
23#include "ZDCCalib/InterCalib.h"
26#include "Framework/Logger.h"
27#include "CCDB/CcdbApi.h"
28
29using namespace o2::zdc;
30
32std::mutex InterCalib::mMtx;
33
35{
36 if (mInterCalibConfig == nullptr) {
37 LOG(fatal) << "o2::zdc::InterCalib: missing configuration object";
38 return -1;
39 }
40
41 // Inspect calibration parameters
42 const auto& opt = CalibParamZDC::Instance();
43 opt.print();
44 if (opt.debugOutput == true) {
46 }
47
48 clear();
49 auto* cfg = mInterCalibConfig;
50
51 // clang-format off
52 for(int ih=0; ih<NH; ih++){
53 if(ih == HidZNI || ih == HidZPI){
54 // Avoid duplication
55 mHUnc[ih] = nullptr;
56 mHUnc[NH+ih] = nullptr;
57 }else{
58 mHUnc[ih] = new o2::dataformats::FlatHisto1D<float>(cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]);
59 mHUnc[NH+ih] = new o2::dataformats::FlatHisto1D<float>(cfg->nb1[ih],cfg->amin1[ih],cfg->amax1[ih]);
60 }
61 mCUnc[ih] = new o2::dataformats::FlatHisto2D<float>(cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih],cfg->nb2[ih],cfg->amin2[ih],cfg->amax2[ih]);
62 }
63 // clang-format on
64 mInitDone = true;
65 return 0;
66}
67
68int InterCalib::process(const gsl::span<const o2::zdc::BCRecData>& RecBC,
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)
72{
73 if (!mInitDone) {
74 init();
75 }
76 if (mVerbosity > DbgMinimal) {
77 LOG(info) << "o2::zdc::InterCalib processing " << RecBC.size() << " b.c.";
78 }
80 ev.init(RecBC, Energy, TDCData, Info);
81 while (ev.next()) {
82 if (ev.getNInfo() > 0) {
83 auto& decodedInfo = ev.getDecodedInfo();
84 for (uint16_t info : decodedInfo) {
85 uint8_t ch = (info >> 10) & 0x1f;
86 uint16_t code = info & 0x03ff;
87 // hmsg->Fill(ch, code);
88 }
89 if (mVerbosity > DbgMinimal) {
90 ev.print();
91 }
92 // Need clean data (no messages)
93 // We are sure there is no pile-up in any channel (too restrictive?)
94 continue;
95 }
96 if (ev.getNEnergy() > 0 && ev.mCurB.triggers == 0) {
97 LOGF(info, "%9u.%04u Untriggered bunch", ev.mCurB.ir.orbit, ev.mCurB.ir.bc);
98 // Skip!
99 continue;
100 }
101 if ((ev.ezdcDecoded & MaskZNA) == MaskZNA) {
102 cumulate(HidZNA, ev.EZDC(IdZNAC), ev.EZDC(IdZNA1), ev.EZDC(IdZNA2), ev.EZDC(IdZNA3), ev.EZDC(IdZNA4), 1.);
103 }
104 if ((ev.ezdcDecoded & MaskZPA) == MaskZPA) {
105 cumulate(HidZPA, ev.EZDC(IdZPAC), ev.EZDC(IdZPA1), ev.EZDC(IdZPA2), ev.EZDC(IdZPA3), ev.EZDC(IdZPA4), 1.);
106 }
107 if ((ev.ezdcDecoded & MaskZNC) == MaskZNC) {
108 cumulate(HidZNC, ev.EZDC(IdZNCC), ev.EZDC(IdZNC1), ev.EZDC(IdZNC2), ev.EZDC(IdZNC3), ev.EZDC(IdZNC4), 1.);
109 }
110 if ((ev.ezdcDecoded & MaskZPC) == MaskZPC) {
111 cumulate(HidZPC, ev.EZDC(IdZPCC), ev.EZDC(IdZPC1), ev.EZDC(IdZPC2), ev.EZDC(IdZPC3), ev.EZDC(IdZPC4), 1.);
112 }
113 if ((ev.ezdcDecoded & MaskZEM) == MaskZEM) {
114 cumulate(HidZEM, ev.EZDC(IdZEM1), ev.EZDC(IdZEM2), 0., 0., 0., 1.);
115 }
116 if ((ev.ezdcDecoded & MaskZNA) == MaskZNA && (ev.ezdcDecoded & MaskZNC) == MaskZNC) {
117 cumulate(HidZNI, ev.EZDC(IdZNAC), ev.EZDC(IdZNCC), 0., 0., 0., 1.);
118 }
119 if ((ev.ezdcDecoded & MaskZPA) == MaskZPA && (ev.ezdcDecoded & MaskZPC) == MaskZPC) {
120 cumulate(HidZPI, ev.EZDC(IdZPAC), ev.EZDC(IdZPCC), 0., 0., 0., 1.);
121 }
122 }
123 return 0;
124}
125
126//______________________________________________________________________________
127// Update calibration coefficients
129{
130 if (mVerbosity > DbgZero) {
131 LOGF(info, "Computing intercalibration coefficients");
132 }
133 if (mSaveDebugHistos) {
135 }
136
137 for (int ih = 0; ih < NH; ih++) {
138 LOGF(info, "%s %g events and cuts (%g:%g)", InterCalibData::DN[ih], mData.mSum[ih][5][5], mInterCalibConfig->cutLow[ih], mInterCalibConfig->cutHigh[ih]);
139 if (!mInterCalibConfig->enabled[ih]) {
140 LOGF(info, "DISABLED processing of RUN3 data for ih = %d: %s", ih, InterCalibData::DN[ih]);
141 assign(ih, false);
142 } else if (mData.mSum[ih][5][5] >= mInterCalibConfig->min_e[ih]) {
143 int ierr = mini(ih);
144 if (ierr) {
145 LOGF(error, "FAILED processing RUN3 data for ih = %d: %s", ih, InterCalibData::DN[ih]);
146 assign(ih, false);
147 } else {
148 LOGF(info, "Processed RUN3 data for ih = %d: %s", ih, InterCalibData::DN[ih]);
149 assign(ih, true);
150 }
151 } else {
152 LOGF(info, "FAILED processing RUN3 data for ih = %d: %s: TOO FEW EVENTS: %g", ih, InterCalibData::DN[ih], mData.mSum[ih][5][5]);
153 assign(ih, false);
154 }
155 }
156
157 auto clName = o2::utils::MemFileHelper::getClassName(mTowerParamUpd);
158 mInfo.setObjectType(clName);
159 auto flName = o2::ccdb::CcdbApi::generateFileName(clName);
160 mInfo.setFileName(flName);
162 std::map<std::string, std::string> md;
163 md["config"] = mInterCalibConfig->desc;
164 mInfo.setMetaData(md);
165 uint64_t starting = mData.mCTimeBeg;
166 if (starting >= 10000) {
167 starting = starting - 10000; // start 10 seconds before
168 }
169 uint64_t stopping = mData.mCTimeEnd + 10000; // stop 10 seconds after
170 mInfo.setStartValidityTimestamp(starting);
171 mInfo.setEndValidityTimestamp(stopping);
172 mInfo.setAdjustableEOV();
173
174 return 0;
175}
176
177//______________________________________________________________________________
178// Update calibration object for the five detectors
179// ismod=false if it was not possible to update the calibration coefficients
180// due to low statistics or minimization error
181// ismod=true if the calibration was updated
182void InterCalib::assign(int ih, bool ismod)
183{
184 int id_0[4] = {IdZNA1, IdZNA2, IdZNA3, IdZNA4};
185 int id_1[4] = {IdZPA1, IdZPA2, IdZPA3, IdZPA4};
186 int id_2[4] = {IdZNC1, IdZNC2, IdZNC3, IdZNC4};
187 int id_3[4] = {IdZPC1, IdZPC2, IdZPC3, IdZPC4};
188 int id_4[1] = {IdZEM2};
189 int id_5[1] = {IdZNCC};
190 int id_6[1] = {IdZPCC};
191 int id_7[4] = {IdZPA1, IdZPA2, IdZPA3, IdZPA4};
192 int id_8[4] = {IdZPC1, IdZPC2, IdZPC3, IdZPC4};
193 int nid = 0;
194 int* id = nullptr;
195 if (ih == 0) {
196 nid = 4;
197 id = id_0;
198 } else if (ih == 1) {
199 nid = 4;
200 id = id_1;
201 } else if (ih == 2) {
202 nid = 4;
203 id = id_2;
204 } else if (ih == 3) {
205 nid = 4;
206 id = id_3;
207 } else if (ih == 4) {
208 nid = 1;
209 id = id_4;
210 } else if (ih == 5) {
211 nid = 1;
212 id = id_5;
213 LOG(warn) << "InterCalib::assign is not implemented for coefficient ih = " << ih;
214 return;
215 } else if (ih == 6) {
216 nid = 1;
217 id = id_6;
218 LOG(warn) << "InterCalib::assign is not implemented for coefficient ih = " << ih;
219 return;
220 } else if (ih == 7 || ih == 8) {
221 nid = 4;
222 if (ih == 7) {
223 id = id_7;
224 } else if (ih == 8) {
225 id = id_8;
226 }
227 // LOG(warn) << "InterCalib::assign MANUAL ASSIGNMENT for ih = " << ih;
228 // if (mVerbosity > DbgZero) {
229 // for (int iid = 0; iid < nid; iid++) {
230 // auto ich = id[iid];
231 // auto oldval = mTowerParam->getTowerCalib(ich);
232 // auto val = oldval;
233 // val = val * mPar[ih][iid + 1];
234 // LOGF(info, "%s MANUAL UPDATING %8.6f -> %8.6f", ChannelNames[ich].data(), oldval, val);
235 // }
236 // }
237 // return;
238 } else {
239 LOG(fatal) << "InterCalib::assign accessing not existing ih = " << ih;
240 }
241 for (int iid = 0; iid < nid; iid++) {
242 auto ich = id[iid];
243 auto oldval = mTowerParam->getTowerCalib(ich);
244 if (ismod == true) {
245 auto val = oldval;
246 if (oldval > 0) {
247 val = val * mPar[ih][iid + 1];
248 }
249 if (mTowerParamUpd.modified[ich]) {
250 LOGF(warn, "%s OVERWRITING MODIFIED PARAMETER %8.6f", ChannelNames[ich].data(), mTowerParamUpd.getTowerCalib(ich));
251 LOGF(info, "%s updated %8.6f -> %8.6f", ChannelNames[ich].data(), oldval, val);
252 } else if (mVerbosity > DbgZero) {
253 LOGF(info, "%s updated %8.6f -> %8.6f", ChannelNames[ich].data(), oldval, val);
254 }
255 mTowerParamUpd.setTowerCalib(ich, val, true);
256 } else {
257 // Check if another fit has already modified the parameters
258 if (mTowerParamUpd.modified[ich]) {
259 LOGF(warn, "%s NOT OVERWRITING MODIFIED PARAMETER %8.6f", ChannelNames[ich].data(), mTowerParamUpd.getTowerCalib(ich));
260 } else {
261 if (mVerbosity > DbgZero) {
262 LOGF(info, "%s NOT CHANGED %8.6f", ChannelNames[ich].data(), oldval);
263 }
264 mTowerParamUpd.setTowerCalib(ich, oldval, false);
265 }
266 }
267 }
268}
269
270int InterCalib::process(const char* hname, int ic)
271{
272 // Run 2 ZDC calibration is based on multi-dimensional histograms
273 // with dimensions:
274 // TC, T1, T2, T3, T4, Trigger
275 // ic is the number of the selected trigger class
276 THnSparse* hs = (THnSparse*)gROOT->FindObject(hname);
277 if (hs == nullptr) {
278 LOGF(error, "Not found: %s\n", hname);
279 return -1;
280 }
281 if (!hs->InheritsFrom(THnSparse::Class())) {
282 LOGF(error, "Not a THnSparse: %s\n", hname);
283 hs->IsA()->Print();
284 return -1;
285 }
286 if (!mInitDone) {
287 init();
288 }
289 TString hn = hname;
290 int ih = -1;
291 if (hn.EqualTo("hZNA")) {
292 ih = HidZNA;
293 } else if (hn.EqualTo("hZPA")) {
294 ih = HidZPA;
295 } else if (hn.EqualTo("hZNC")) {
296 ih = HidZNC;
297 } else if (hn.EqualTo("hZPC")) {
298 ih = HidZPC;
299 } else if (hn.EqualTo("hZEM")) {
300 ih = HidZEM;
301 } else if (hn.EqualTo("hZNI")) {
302 ih = HidZNI;
303 } else if (hn.EqualTo("hZPI")) {
304 ih = HidZPI;
305 } else if (hn.EqualTo("hZPAX")) {
306 ih = HidZPAX;
307 } else if (hn.EqualTo("hZPCX")) {
308 ih = HidZPCX;
309 } else {
310 LOGF(error, "Not recognized histogram name: %s\n", hname);
311 return -1;
312 }
313 clear(ih);
314 const int32_t dim = 6;
315 double x[dim];
316 int32_t bins[dim];
317 int64_t nb = hs->GetNbins();
318 int64_t nn = 0;
319 LOGF(info, "Histogram %s has %ld bins\n", hname, nb);
320 double cutl = mInterCalibConfig->cutLow[ih];
321 double cuth = mInterCalibConfig->cutHigh[ih];
322 double contt = 0;
323 for (int64_t i = 0; i < nb; i++) {
324 double cont = hs->GetBinContent(i, bins);
325 if (cont <= 0) {
326 continue;
327 }
328 for (int32_t d = 0; d < dim; ++d) {
329 x[d] = hs->GetAxis(d)->GetBinCenter(bins[d]);
330 }
331 if (TMath::Nint(x[5] - ic) == 0 && x[0] > cutl && x[0] < cuth) {
332 nn++;
333 contt += cont;
334 cumulate(ih, x[0], x[1], x[2], x[3], x[4], cont);
335 }
336 }
337 int ierr = mini(ih);
338 if (ierr) {
339 LOGF(error, "FAILED processing RUN2 data for %s ih = %d\n", hname, ih);
340 } else {
341 LOGF(info, "Processed RUN2 data for %s ih = %d\n", hname, ih);
342 replay(ih, hs, ic);
343 }
344 LOGF(info, "Trigger class selection %d and %d bins %g events and cuts (%g:%g): %ld\n", ic, nn, contt, cutl, cuth);
345 return 0;
346}
347
348void InterCalib::replay(int ih, THnSparse* hs, int ic)
349{
350 auto* cfg = mInterCalibConfig;
351 // clang-format off
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]); }
362 // clang-format on
363 const int32_t dim = 6;
364 double x[dim];
365 int32_t bins[dim];
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);
376 if (cont <= 0) {
377 continue;
378 }
379 for (int32_t d = 0; d < dim; ++d) {
380 x[d] = hs->GetAxis(d)->GetBinCenter(bins[d]);
381 }
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);
386 }
387 }
388}
389
391{
392 int ihstart = 0;
393 int ihstop = NH;
394 if (ih >= 0 && ih < NH) {
395 ihstart = ih;
396 ihstop = ih + 1;
397 }
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++) {
401 mData.mSum[ii][i][j] = 0;
402 }
403 }
404 if (mHUnc[ii]) {
405 mHUnc[ii]->clear();
406 }
407 if (mCUnc[ii]) {
408 mCUnc[ii]->clear();
409 }
410 }
411}
412
414{
415 if (!mInitDone) {
416 init();
417 }
418 mData += data;
419 return 0;
420}
421
423{
424 if (!mInitDone) {
425 init();
426 }
427 constexpr int nh = 2 * InterCalibData::NH;
428 if (ih >= 0 && ih < nh) {
429 mHUnc[ih]->add(h1);
430 } else {
431 LOG(error) << "InterCalib::add: unsupported FlatHisto1D " << ih;
432 }
433}
434
436{
437 if (!mInitDone) {
438 init();
439 }
440 if (ih >= 0 && ih < InterCalibData::NH) {
441 mCUnc[ih]->add(h2);
442 } else {
443 LOG(error) << "InterCalib::add: unsupported FlatHisto2D " << ih;
444 }
445}
446
447void InterCalib::cumulate(int ih, double tc, double t1, double t2, double t3, double t4, double w = 1)
448{
449 constexpr double minfty = -std::numeric_limits<double>::infinity();
450 if (tc < mInterCalibConfig->cutLow[ih] || tc > mInterCalibConfig->cutHigh[ih]) {
451 return;
452 }
453 if ((ih == HidZPA || ih == HidZPAX)) {
454 if (t1 < mInterCalibConfig->towerCutLow_ZPA[0] || t2 < mInterCalibConfig->towerCutLow_ZPA[1] || t3 < mInterCalibConfig->towerCutLow_ZPA[2] || t4 < mInterCalibConfig->towerCutLow_ZPA[3]) {
455 return;
456 }
457 if (t1 > mInterCalibConfig->towerCutHigh_ZPA[0] || t2 > mInterCalibConfig->towerCutHigh_ZPA[1] || t3 > mInterCalibConfig->towerCutHigh_ZPA[2] || t4 > mInterCalibConfig->towerCutHigh_ZPA[3]) {
458 return;
459 }
460 }
461 if (ih == HidZPC || ih == HidZPCX) {
462 if (t1 < mInterCalibConfig->towerCutLow_ZPC[0] || t2 < mInterCalibConfig->towerCutLow_ZPC[1] || t3 < mInterCalibConfig->towerCutLow_ZPC[2] || t4 < mInterCalibConfig->towerCutLow_ZPC[3]) {
463 return;
464 }
465 if (t1 > mInterCalibConfig->towerCutHigh_ZPC[0] || t2 > mInterCalibConfig->towerCutHigh_ZPC[1] || t3 > mInterCalibConfig->towerCutHigh_ZPC[2] || t4 > mInterCalibConfig->towerCutHigh_ZPC[3]) {
466 return;
467 }
468 }
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++) {
473 mData.mSum[ih][i][j] += val[i] * val[j] * w;
474 }
475 }
476 }
477 // mData.mSum[ih][5][5] contains the number of analyzed events
478 double sumquad = val[1] + val[2] + val[3] + val[4];
479 // Avoid filling duplicate histograms
480 if (mHUnc[ih]) {
481 mHUnc[ih]->fill(sumquad, w);
482 }
483 if (mHUnc[ih + NH]) {
484 mHUnc[ih + NH]->fill(val[0]);
485 }
486 mCUnc[ih]->fill(val[0], sumquad, w);
487}
488
489//______________________________________________________________________________
490// Compute chi2 for minimization (static function)
491void InterCalib::fcn(int& npar, double* gin, double& chi, double* par, int iflag)
492{
493 chi = 0;
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];
497 }
498 }
499 // Following line modifies the chisquare computation (sum of squares of residuals)
500 // to perform orthogonal least squares instead of ordinary least squares minimization
501 chi = chi / (1 + par[1] * par[1] + par[2] * par[2] + par[3] * par[3] + par[4] * par[4]);
502}
503
505{
506 // Copy to static object and symmetrize matrix
507 // We use a static function and therefore we can do only one minimization at a time
508 mMtx.lock();
509 for (int32_t i = 0; i < NPAR; i++) {
510 for (int32_t j = 0; j < NPAR; j++) {
511 if (j < i) {
512 mAdd[i][j] = mData.mSum[ih][j][i];
513 } else {
514 mAdd[i][j] = mData.mSum[ih][i][j];
515 }
516 }
517 }
518 double arglist[10];
519 int ierflg = 0;
520 double l_bnd = mInterCalibConfig->l_bnd[ih];
521 double u_bnd = mInterCalibConfig->u_bnd[ih];
522 double start = mInterCalibConfig->start[ih];
523 double step = 0.1;
524 mMn[ih] = std::make_unique<TMinuit>(NPAR);
525 mMn[ih]->SetFCN(fcn);
526 // We introduce the calibration of the common PM in separate workflows
527 // Calibration cvoefficient is forced to and step is forced to zero
528 mMn[ih]->mnparm(0, "c0", 1., 0., 1., 1., ierflg);
529
530 // Special fit for proton calorimeters: fit least exposed towers
531 // starting from parameters of previous fit to all towers
532
533 // Tower 1
534 mMn[ih]->mnparm(1, "c1", start, step, l_bnd, u_bnd, ierflg);
535
536 // Tower 2
537 // Only two ZEM calorimeters: equalize response
538 // Equalize side A and C
539 if (ih == HidZEM || ih == HidZNI || ih == HidZPI) {
540 l_bnd = 0;
541 u_bnd = 0;
542 start = 0;
543 step = 0;
544 }
545
546 mMn[ih]->mnparm(2, "c2", start, step, l_bnd, u_bnd, ierflg);
547
548 // Towers 3 and 4
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);
551
552 // Offset
553 l_bnd = mInterCalibConfig->l_bnd_o[ih];
554 u_bnd = mInterCalibConfig->u_bnd_o[ih];
555 start = 0;
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]);
561 }
562 // Fallback in case fit fails on proton calorimeters
563 if (ih == 1 || ih == 3 || ih == 7 || ih == 8) {
564 for (int iretry = 0; iretry < 2; iretry++) {
565 bool retry = false;
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) {
571 retry = true;
572 LOG(warn) << "ih=" << ih << " par " << i << " too close to boundaries";
573 if (ih == 1 || ih == 7) {
574 // mMn[ih]->mnparm(i, parn[i], mTowerParam->tower_calib[IdZPAC + i], 0, l_bnd, u_bnd, ierflg);
575 mMn[ih]->mnparm(i, parn[i], mInterCalibConfig->start[ih], 0, l_bnd, u_bnd, ierflg);
576 } else if (ih == 3 || ih == 8) {
577 // mMn[ih]->mnparm(i, parn[i], mTowerParam->tower_calib[IdZPCC + i], 0, l_bnd, u_bnd, ierflg);
578 mMn[ih]->mnparm(i, parn[i], mInterCalibConfig->start[ih], 0, l_bnd, u_bnd, ierflg);
579 } else {
580 LOG(fatal) << "ERROR on InterCalib minimization ih=" << ih;
581 }
582 }
583 }
584 if (retry) {
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]);
589 }
590 if (ierflg == 0) {
591 break;
592 }
593 }
594 }
595 }
596 mMtx.unlock();
597 return ierflg;
598}
599
600int InterCalib::saveDebugHistos(const std::string fn)
601{
602 TDirectory* cwd = gDirectory;
603 TFile* f = new TFile(fn.data(), "recreate");
604 if (f->IsZombie()) {
605 LOG(error) << "Cannot create file: " << fn;
606 return 1;
607 }
608 for (int32_t ih = 0; ih < (2 * NH); ih++) {
609 if (mHUnc[ih]) {
610 auto p = mHUnc[ih]->createTH1F(InterCalib::mHUncN[ih]);
611 p->SetTitle(InterCalib::mHUncT[ih]);
612 p->Write("", TObject::kOverwrite);
613 }
614 }
615 for (int32_t ih = 0; ih < NH; ih++) {
616 if (mCUnc[ih]) {
617 auto p = mCUnc[ih]->createTH2F(InterCalib::mCUncN[ih]);
618 p->SetTitle(InterCalib::mCUncT[ih]);
619 p->Write("", TObject::kOverwrite);
620 }
621 }
622 // Only after replay of RUN2 data
623 for (int32_t ih = 0; ih < NH; ih++) {
624 if (mHCorr[ih]) {
625 mHCorr[ih]->Write("", TObject::kOverwrite);
626 }
627 }
628 for (int32_t ih = 0; ih < NH; ih++) {
629 if (mCCorr[ih]) {
630 mCCorr[ih]->Write("", TObject::kOverwrite);
631 }
632 }
633 // Minimization output
634 const char* mntit[NH] = {"mZNA", "mZPA", "mZNC", "mZPC", "mZEM", "mZNI", "mZPI", "mZPAX", "mZPCX"};
635 for (int32_t ih = 0; ih < NH; ih++) {
636 if (mMn[ih]) {
637 mMn[ih]->Write(mntit[ih], TObject::kOverwrite);
638 }
639 }
640 f->Close();
641 cwd->cd();
642 return 0;
643}
ZDC calibration common parameters.
const auto bins
Definition PID.cxx:49
int32_t i
bool const GPUTPCGMMerger::trackCluster * c1
bool const GPUTPCGMMerger::trackCluster const clcomparestruct * c2
Intercalibration intermediate data.
uint32_t j
Definition RawData.h:0
ZDC Energy calibration.
ZDC Tower calibration.
static std::string generateFileName(const std::string &inp)
Definition CcdbApi.cxx:798
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)
void clear(int ih=-1)
static constexpr int HidZEM
Definition InterCalib.h:45
void replay(int ih, THnSparse *hs, int ic)
static constexpr int HidZNA
Definition InterCalib.h:41
static double mAdd[NPAR][NPAR]
Definition InterCalib.h:68
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 NH
Definition InterCalib.h:50
static constexpr int HidZPI
Definition InterCalib.h:47
void setSaveDebugHistos()
Definition InterCalib.h:65
static constexpr const char * mHUncT[2 *NH]
Definition InterCalib.h:91
void add(int ih, o2::dataformats::FlatHisto1D< float > &h1)
int saveDebugHistos(const std::string fn="ZDCInterCalib.root")
static constexpr const char * mHUncN[2 *NH]
Definition InterCalib.h:89
static constexpr int NPAR
Definition InterCalib.h:51
static constexpr int HidZPC
Definition InterCalib.h:44
static constexpr int HidZNI
Definition InterCalib.h:46
static constexpr int HidZNC
Definition InterCalib.h:43
static constexpr int HidZPA
Definition InterCalib.h:42
static constexpr int HidZPAX
Definition InterCalib.h:48
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
Definition InterCalib.h:49
static constexpr const char * mCUncT[NH]
Definition InterCalib.h:94
static constexpr const char * mCUncN[NH]
Definition InterCalib.h:93
GLint GLenum GLint x
Definition glcorearb.h:403
GLdouble f
Definition glcorearb.h:310
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
GLuint start
Definition glcorearb.h:469
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition glcorearb.h:5034
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
constexpr int IdZPC4
constexpr int IdZPA2
constexpr int IdZNA3
constexpr int IdZNA1
constexpr int IdZPA1
constexpr int IdZNC2
constexpr int IdZEM1
constexpr uint32_t MaskZNA
Definition Constants.h:137
constexpr int IdZNCC
constexpr int IdZPAC
constexpr int IdZPC2
constexpr uint32_t MaskZNC
Definition Constants.h:142
constexpr int IdZPA4
constexpr int IdZNC1
constexpr int IdZNC3
constexpr int IdZPCC
constexpr int IdZPC1
constexpr int IdZPA3
constexpr int DbgMinimal
Definition Constants.h:208
constexpr int IdZNC4
constexpr int IdZEM2
constexpr uint32_t MaskZEM
Definition Constants.h:141
constexpr uint32_t MaskZPA
Definition Constants.h:139
constexpr int IdZNA2
constexpr int DbgZero
Definition Constants.h:207
const std::string CCDBPathTowerCalib
Definition Constants.h:225
constexpr int IdZPC3
constexpr int IdZNA4
constexpr int IdZNAC
constexpr std::string_view ChannelNames[]
Definition Constants.h:147
constexpr uint32_t MaskZPC
Definition Constants.h:144
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
static std::string getClassName(const T &obj)
get the class name of the object
uint32_t triggers
Definition BCRecData.h:34
o2::InteractionRecord ir
Definition BCRecData.h:32
bool enabled[NH]
ZNA, ZPA, ZNC, ZPC, ZEM, ZNI, ZPI, ZPAX, ZPCX.
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.
NElem getNEnergy() const
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()
NElem getNInfo() const
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"
vec clear()