ATLAS Offline Software
Loading...
Searching...
No Matches
CalibrateIBL.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5//======================================================================
6// PixelCalibIBL : Read calibration file, redo the fit.
7//
8// Note : this program only runs on IBL.
9//
10//
11// Mapping convention for FE in the calibration.
12//
13// ^
14// phi|
15// |
16// 336| sFE0 sFE1
17// |
18// 0+------------------------------>
19// 0 80 160
20// eta
21//======================================================================
22
25
26
27// ignore the "demonstrate Xcheck" lines unless necessary
28// #define DEMOXCHECK true
29
30#include "TFile.h"
31#include "TDirectory.h"
32#include "TDirectoryFile.h"
33#include "TKey.h"
34#include "TH2D.h"
35#include "TH2F.h"
36#include "TProfile.h"
37#include "TGraph.h"
38#include "TGraphErrors.h"
39#include "TMultiGraph.h"
40#include "TMath.h"
41#include "TF1.h"
42#include "TStyle.h"
43#include "TVectorT.h"
44#include "THStack.h"
45#include "TRandom3.h"
48#include <cmath>
49#include <fstream>
50#include <iostream>
51#include <iterator>
52#include <string>
53#include <sstream>
54#include <utility>
55#include <map>
56#include <array>
57
58using namespace std;
60
61// Lianyou: simplely capacitor charging curve
62double funcDisp(double *x, double *par)
63{
64 double ret = 9.9e10;
65 ret = par[0] * 0.1 * (1. - exp(-(x[0] - 1400.) * (x[0] - 1400.) / (1000. * par[1])) + par[2] * 0.0001 * sqrt(x[0]));
66 return ret;
67}
68
69double ChrgfromToT(float tot, double par[10])
70{
71 int lr = (tot <= 6. ? 0 : 5);
72 double chrg = 1400.;
73
74 double num = par[0 + lr] + tot * (par[1 + lr] + tot * (par[2 + lr] + tot * par[3 + lr]));
75 double denom = 1. + tot * par[4 + lr];
76 if (denom != 0.)
77 chrg = num / denom;
78
79 return chrg;
80}
81
82double ToTfromChrg(float chrg, double par[5])
83{
84 double tot = 0.;
85 double num = par[0] + chrg * (par[1] + chrg * (par[2] + chrg * par[3]));
86 double denom = 1. + chrg * par[4];
87 if (denom != 0.0)
88 tot = num / denom;
89 return tot;
90}
91
92double funcRation5(double *x, double *par)
93{
94 double ret = 9.9e10;
95 double num = par[0] + x[0] * (par[1] + x[0] * (par[2] + x[0] * par[3]));
96 double denom = 1. + x[0] * par[4];
97 if (denom != 0.0)
98 ret = num / denom;
99 return ret;
100}
101
102double funcDispConvoluted(double *x, double *par)
103{
104 double ret = 9.9e09;
105 ret = -par[0] * (x[0] - par[1]) + par[2];
106 return ret;
107}
108
109int iblCalib(const std::string& InDir, const std::string& THRscan, const std::string& scan, const std::string& scanLowCharge)
110{
111 // creating the object for the pixel mapping
112 PixelMapping pixmap(PathResolver::find_file("PixelCalibAlgs/mapping.csv", "DATAPATH"));
113
114 constexpr bool run3 = true; // new series of injection charges (22) and new format
115 const float badRDfracCut = 0.2; // Cut on the fraction of bad read out per frontend
116 float HDCshift = 2;
117
118 // Shall we try this later ?
119 constexpr int finerToT = 1; // smaller bin size for ToT if doing fit
120 constexpr bool moreFE = false;
121 constexpr int npsFEs = moreFE ? 8 : 2;
122
123 gStyle->SetOptFit(1100);
124
125#if defined(DEMOXCHECK)
126
127 std::cout << " DEMOXCHECK will run ... " << std::endl;
128
129 // For debugging a small area of pixels will print their readout and injection
130 int XcheckCharge[2] = {13, 14}, XcheckToT = 10;
131 int XcheckPhi[2] = {57, 63}, XcheckEta[2] = {23, 29};
132 TString XcheckModule = "LI_S11_A_M3_A6";
133
134 // fill some histograms for monitoring
135 int ToTfill = 3 * finerToT, CHRGfill = 3;
136 const int HDC = 2; // specifying output
137
138#endif
139
140 Double_t tmpRCf_H[4] = {0.868295, 0.67523, 0.732279, 0.678458}; // initial values from history calibration
141 Double_t tmpRCf_T[4] = {1.02844, 1.10788, 1.07204, 1.11015}; // initial values from history calibration
142 Double_t reverseCF_H[4], reverseCF_T[4];
143 for (int t = 0; t < 4; t++)
144 {
145 reverseCF_H[t] = tmpRCf_H[t];
146 reverseCF_T[t] = tmpRCf_T[t];
147 }
148
149 Double_t RDentries[33] = {0, 10494.8, 14605.6, 62952.6, 8663.57, 17320.2, 20417, 49508.9,
150 21646.8, 31503.9, 14955.6, 16290.7, 11617.5, 16461.2, 11980.5, 17210.5,
151 12773.7, 18574, 13930.9, 19777, 14629.4, 20619.5, 15191.6, 20883,
152 15411.1, 19198, 12097.4, 12109.7, 8881.96, 17235.1, 20802.3, 11265.8,
153 0.};
154
155 std::vector<int> reversedModules = {182, 211, 213, 229, 223, 231, 246, 280, 295, 350, 357, 360, 371, 403, 416, 423};
156
157 // outputs : something@somewhere as one like ...
158 TString Outdir = "./";
159 string spec = "ToTbin" + to_string(finerToT) + "_FrtEnd" + to_string(npsFEs) + "_";
160
161#if defined(DEMOXCHECK)
162 spec += "DEMOXCHECK_";
163#endif
164
165 TString StrFileName = spec + scan;
166 TString rootFileName = Outdir + "/TotChargeCalib_" + StrFileName + ".root";
167 TString logFileName = Outdir + "/ChargeCalib_" + StrFileName + ".log";
168 TString dbFileName = Outdir + "/ChargeCalib_" + StrFileName + ".TXT";
169 if (!run3)
170 {
171 rootFileName = Outdir + "/TotChargeCalib_run2_" + StrFileName + ".root";
172 logFileName = Outdir + "/ChargeCalib_run2_" + StrFileName + ".log";
173 dbFileName = Outdir + "/ChargeCalib_run2_" + StrFileName + ".TXT";
174 }
175
176 // fetch pictures from directory : ToT/ROD_L1_Sxx/LI_Sy_AC_Mz_ACk
177 ofstream logout(logFileName);
178 ofstream txtDB(dbFileName);
179
180 TString inThrFile = "";
181 TString inTotFile = "";
182 TString rodPath = "";
183 TString inTotFileAux = "";
184 TString rodPathAux = "";
185
186 std::cout << " Running IBL calibration analysis ... " << endl;
187
188 inThrFile = InDir + THRscan + ".root";
189 inTotFile = InDir + scan + ".root";
190 rodPath = inTotFile + ":/" + scan.substr(scan.find("_")+1);
191 inTotFileAux = InDir + scanLowCharge + ".root";
192 rodPathAux = inTotFileAux + ":/" + scanLowCharge.substr(scanLowCharge.find("_")+1);
193
194 // historical record for run2 fomat
195 if (!run3)
196 {
197 inThrFile = "calib2018/IBL/THR_SCAN_S000083686.root";
198 inTotFile = "calib2018/IBL/TOT_SCAN_S000083690.root";
199 rodPath = inTotFile + ":/S000083690";
200 }
201
202 // selecting Q threshold
203 int nrow = 336, ncol = 160; // y-axis, x-axis respectively
204
205 const Int_t numChrgs = 22;
206 Double_t IBLchrgs[numChrgs] = {1400., 1500., 1750., 2000., 2500., 3000., 3500., 4000., 5000., 6000., 8000., 10000.,
207 12000., 14000., 16000., 18000., 20000., 22000., 24000., 26000., 28000., 30000.};
208
209 constexpr Int_t nchargeIBL = (run3 ? 22 : 19); //run3 is constexpr
210
211 int skip = numChrgs - nchargeIBL;
212 Double_t chrgAbaciIBL[nchargeIBL], chargeErrArrIBL[nchargeIBL];
213 for (int c = 0; c < nchargeIBL; c++)
214 {
215 chrgAbaciIBL[c] = IBLchrgs[c + skip];
216 chargeErrArrIBL[c] = 0.;
217 }
218
219 Double_t chrgsbins[nchargeIBL + 1];
220 for (int c = 1; c < nchargeIBL; c++)
221 chrgsbins[c] = 0.5 * (chrgAbaciIBL[c - 1] + chrgAbaciIBL[c]);
222
223 chrgsbins[0] = chrgAbaciIBL[0] - 0.5 * (chrgAbaciIBL[1] - chrgAbaciIBL[0]);
224 chrgsbins[nchargeIBL] = chrgAbaciIBL[nchargeIBL - 1] + 0.5 * (chrgAbaciIBL[nchargeIBL - 1] - chrgAbaciIBL[nchargeIBL - 2]);
225
226 // please note extra +1 for ending bins.
227 constexpr Int_t nToTibl = 16 * finerToT + 1;
228
229 Double_t totAbaci[nToTibl], totbins[nToTibl + 1];
230
231 totbins[0] = -0.25;
232 totbins[1] = 0.5;
233 totAbaci[0] = 0.0;
234 totAbaci[1] = 1.;
235 for (int t = 2; t < nToTibl; t++)
236 {
237 totAbaci[t] = totAbaci[1] + (t - 1) / (1. * finerToT);
238 totbins[t] = 0.5 * (totAbaci[t] + totAbaci[t - 1]);
239 }
240 totbins[nToTibl] = totAbaci[nToTibl - 1] + 0.5 * (totbins[nToTibl - 1] - totbins[nToTibl - 2]);
241
242 Double_t totErrArr[nToTibl];
243 for (int t = 0; t < nToTibl; t++)
244 totErrArr[t] = 0.;
245
246#if defined(DEMOXCHECK)
247 for (int t = 0; t < nToTibl; t++)
248 logout << " totAbaci : " << t << " " << totbins[t] << " < " << totAbaci[t] << " > " << totbins[t + 1] << endl;
249
250 if (finerToT == 1)
251 {
252 for (int t = 1; t < nToTibl; t++)
253 {
254 RDentries[t] = RDentries[2 * t - 1] + RDentries[2 * t];
255 logout << " finer RDentries : " << t << " " << 2 * t - 1 << " " << 2 * t << " " << RDentries[t] << endl;
256 }
257 }
258#endif
259
260 map<string, map<string, map<string, float>>> pcdMap;
261
262 TFile roFile(rootFileName, "RECREATE");
263 TDirectory *roThrDir = roFile.mkdir("Threshold");
264 TDirectory *roTotDir = roFile.mkdir("ToT");
265
266 // ****************************** Threshold IBL ******************************
267
268 Double_t THR_avg[2][npsFEs], ThrSig_avg[2][npsFEs];
269 array<std::unique_ptr<TH2D> , npsFEs> h2_Thr{};
270 array<std::unique_ptr<TH2D> , npsFEs> h2_ThrSig{};
271
272 std::multimap<float, TString, std::greater<float>> badThr_Order;
273
274 for (int sfe = 0; sfe < npsFEs; sfe++)
275 {
276 stringstream ss;
277 ss << sfe;
278
279 string knowModule = "LI_S06_C_M1_C1";
280 string idx = "I" + ss.str();
281
282 pcdMap[knowModule][idx]["ThrNorm"] = -42.;
283 pcdMap[knowModule][idx]["ThrRmsNorm"] = -42.;
284 pcdMap[knowModule][idx]["ThrSigNorm"] = -42.;
285 pcdMap[knowModule][idx]["ThrLong"] = -42.;
286 pcdMap[knowModule][idx]["ThrRmsLong"] = -42.;
287 pcdMap[knowModule][idx]["ThrSigLong"] = -42.;
288
289 for (int nl = 0; nl < 2; nl++)
290 THR_avg[nl][sfe] = ThrSig_avg[nl][sfe] = -99.;
291
292 idx = "Threshold" + ss.str();
293 h2_Thr[sfe] = std::make_unique<TH2D>(idx.c_str(), " ", 2, 0, 2, 200, 0, 5000);
294 idx = "ThresholdSig" + ss.str();
295 h2_ThrSig[sfe] = std::make_unique<TH2D>(idx.c_str(), " ", 2, 0, 2, 200, 0, 500);
296 }
297
298 if (inThrFile.Length() > 0)
299 {
300 std::cout << endl
301 << "INFO =>> [IBL] threshold scan analysis..." << endl;
302
303 TFile riThrFile(inThrFile, "READ");
304 TString chi2HistName = "SCURVE_CHI2";
305 TString thrHistName = "SCURVE_MEAN";
306 TString sigHistName = "SCURVE_SIGMA";
307
308 std::unique_ptr<TH1F> h1dChi2 = std::make_unique<TH1F>("h1dChi2", "", 200, 0, 1);
309 std::unique_ptr<TH1F> h1dThr = std::make_unique<TH1F>("h1dThr" , "", 200, 0, 5000);
310 std::unique_ptr<TH1F> h1dSig = std::make_unique<TH1F>("h1dSig" , "", 200, 0, 500);
311
312 TDirectoryFile *scanDir = (TDirectoryFile *)((TKey *)riThrFile.GetListOfKeys()->First())->ReadObj();
313 TList *rodKeyList = (TList *)scanDir->GetListOfKeys();
314 TIter rodItr(rodKeyList);
315 TKey *rodKey;
316
317 while ((rodKey = (TKey *)rodItr()))
318 {
319 TString rodName(rodKey->GetName());
320 TDirectoryFile *rodDir = (TDirectoryFile *)rodKey->ReadObj();
321 TList *modKeyList = (TList *)rodDir->GetListOfKeys();
322 TIter modItr(modKeyList);
323 TKey *modKey;
324
325 TDirectory *dirRod = roThrDir->mkdir(rodName);
326
327 while ((modKey = (TKey *)modItr()))
328 {
329 TString modName(modKey->GetName());
330 string modStr(modKey->GetName());
331 TDirectory *dirMod = dirRod->mkdir(modName);
332
333 TString chi2HistDirPath = modName + "/" + chi2HistName + "/A0/B0";
334
335 TDirectory *chi2HistDir = (TDirectory *)rodDir->Get(chi2HistDirPath);
336 if (chi2HistDir == NULL)
337 {
338 cout << " Warning : NULL dir " << endl;
339 continue;
340 }
341
342 std::unique_ptr<TH2D> h2dChi2 (static_cast<TH2D*>(static_cast<TKey*>(chi2HistDir->GetListOfKeys()->First())->ReadObj()));
343 if (h2dChi2 == NULL)
344 {
345 cout << " Warning : NULL dir " << endl;
346 continue;
347 }
348 TString thrHistDirPath = modName + "/" + thrHistName + "/A0/B0";
349 TDirectoryFile *thrHistDir = (TDirectoryFile *)rodDir->Get(thrHistDirPath);
350 std::unique_ptr<TH2D> h2dThr(static_cast<TH2D*>(static_cast<TKey*>(thrHistDir->GetListOfKeys()->First())->ReadObj()));
351 TString sigHistDirPath = modName + "/" + sigHistName + "/A0/B0";
352
353 TDirectoryFile *sigHistDir = (TDirectoryFile *)rodDir->Get(sigHistDirPath);
354 std::unique_ptr<TH2D> h2dSig (static_cast<TH2D*>(static_cast<TKey*>(sigHistDir->GetListOfKeys()->First())->ReadObj()));
355
356 array<std::unique_ptr<TH1F>, npsFEs> h1_ThrNorm{};
357 array<std::unique_ptr<TH1F>, npsFEs> h1_ThrSigNorm{};
358 array<std::unique_ptr<TH1F>, npsFEs> h1_ThrLong{};
359 array<std::unique_ptr<TH1F>, npsFEs> h1_ThrSigLong{};
360 array<float, npsFEs> IlledThr{};
361
362 for (int sfe = 0; sfe < npsFEs; sfe++)
363 {
364 stringstream ss;
365 ss << sfe;
366
367 string hname = modStr + "ThrNorm" + ss.str();
368 h1_ThrNorm[sfe] = std::make_unique<TH1F>(hname.c_str(), "", 200, 0, 5000);
369 hname = modStr + "ThrSigNorm" + ss.str();
370 h1_ThrSigNorm[sfe] = std::make_unique<TH1F>(hname.c_str(), "", 200, 0, 500);
371 hname = modStr + "ThrLong" + ss.str();
372 h1_ThrLong[sfe] = std::make_unique<TH1F>(hname.c_str(), "", 200, 0, 5000);
373 hname = modStr + "ThrSigLong" + ss.str();
374 h1_ThrSigLong[sfe] = std::make_unique<TH1F>(hname.c_str(), "", 200, 0, 500);
375 }
376
377 for (int col = 1; col <= ncol; col++)
378 {
379 for (int row = 1; row <= nrow; row++)
380 {
381 float chi2 = h2dChi2->GetBinContent(col, row);
382 float thr = h2dThr->GetBinContent(col, row);
383 float sig = h2dSig->GetBinContent(col, row);
384
385 h1dChi2->Fill(chi2);
386 h1dThr->Fill(thr);
387 h1dSig->Fill(sig);
388 // Shall we measure/count the goodness of THR scan here ?
389 bool filled = true;
390 if (thr == 0 || thr > 10000 || sig == 0 || sig > 1000 || chi2 > 0.5 || chi2 <= 0)
391 {
392 filled = false;
393 }
394 int circ = -1;
395 if (filled)
396 {
397 if (col == 1 || col == ncol / 2 || col == ncol / 2 + 1 || col == ncol)
398 {
399 if (moreFE)
400 {
401 circ = (int)(row / 84.);
402 if (col > 80)
403 {
404 circ = 7 - circ;
405 }
406 }
407 else
408 {
409 if (col <= ncol / 2)
410 circ = 0;
411 else
412 circ = 1;
413 }
414
415 h1_ThrLong[circ]->Fill(thr);
416 h1_ThrSigLong[circ]->Fill(sig);
417 }
418 else
419 {
420 if (moreFE)
421 {
422 circ = (int)(row / 84.);
423 if (col > 80)
424 {
425 circ = 7 - circ;
426 }
427 }
428 else
429 {
430 if (col <= ncol / 2)
431 circ = 0;
432 else
433 circ = 1;
434 }
435
436 h1_ThrNorm[circ]->Fill(thr);
437 h1_ThrSigNorm[circ]->Fill(sig);
438 }
439 }
440 else
441 {
442 // Note: what is the intention? circ is -1 here
443 continue;
444 }
445 }
446 }
447 h2dSig.reset();
448 h2dThr.reset();
449 h2dChi2.reset();
450
451 for (int sfe = 0; sfe < npsFEs; sfe++)
452 {
453 stringstream ss;
454 ss << sfe;
455 string feName = "I" + ss.str();
456
457 float THRnorm = h1_ThrNorm[sfe]->GetMean();
458 bool valid = THRnorm > 100.;
459 pcdMap[modStr][feName]["ThrNorm"] = THRnorm;
460 pcdMap[modStr][feName]["ThrRmsNorm"] = h1_ThrNorm[sfe]->GetRMS();
461 float THRnormSig = h1_ThrSigNorm[sfe]->GetMean();
462 pcdMap[modStr][feName]["ThrSigNorm"] = THRnormSig;
463 float THRlong = h1_ThrLong[sfe]->GetMean();
464 pcdMap[modStr][feName]["ThrLong"] = THRlong;
465 pcdMap[modStr][feName]["ThrRmsLong"] = h1_ThrLong[sfe]->GetRMS();
466 float THRlongSig = h1_ThrSigLong[sfe]->GetMean();
467 pcdMap[modStr][feName]["ThrSigLong"] = THRlongSig;
468
469 float blank = 100. * IlledThr[sfe] * npsFEs / (1. * ncol * nrow);
470
471 if (blank > 0.01)
472 badThr_Order.insert(std::pair<float, TString>(blank, (TString)(modName + " : " + blank)));
473
474 if (valid)
475 {
476 h2_Thr[sfe]->Fill(0.5, THRnorm, 1);
477 h2_Thr[sfe]->Fill(1.5, THRlong, 1);
478 h2_ThrSig[sfe]->Fill(0.5, THRnormSig, 1);
479 h2_ThrSig[sfe]->Fill(1.5, THRlongSig, 1);
480 }
481 dirMod->WriteTObject(h1_ThrNorm[sfe].get());
482 dirMod->WriteTObject(h1_ThrLong[sfe].get());
483
484 h1_ThrNorm[sfe].reset();
485 h1_ThrSigNorm[sfe].reset();
486 h1_ThrLong[sfe].reset();
487 h1_ThrSigLong[sfe].reset();
488 }
489 }
490 }
491 roThrDir->WriteTObject(h1dChi2.get());
492 h1dChi2.reset();
493 roThrDir->WriteTObject(h1dThr.get());
494 h1dThr.reset();
495 roThrDir->WriteTObject(h1dSig.get());
496 h1dSig.reset();
497 }
498
499 for (int sfe = 0; sfe < npsFEs; sfe++)
500 {
501 stringstream ss;
502 ss << sfe;
503 string hName = "thrNorm" + ss.str();
504 THR_avg[0][sfe] = h2_Thr[sfe]->ProjectionY(hName.c_str(), 1, 1)->GetMean();
505 hName = "thrLong" + ss.str();
506 THR_avg[1][sfe] = h2_Thr[sfe]->ProjectionY(hName.c_str(), 2, 2)->GetMean();
507 hName = "thrSigNorm" + ss.str();
508 ThrSig_avg[0][sfe] = h2_ThrSig[sfe]->ProjectionY(hName.c_str(), 1, 1)->GetMean();
509 hName = "thrSigLong" + ss.str();
510 ThrSig_avg[1][sfe] = h2_ThrSig[sfe]->ProjectionY(hName.c_str(), 2, 2)->GetMean();
511 h2_Thr[sfe].reset();
512 h2_ThrSig[sfe].reset();
513 }
514 // ****************************** End - Threshold IBL ******************************
515
517 /************************* IBL ToT ***************************/
519
520 if (inTotFile.Length() == 0 || inTotFileAux.Length() == 0)
521 {
522 logout << " Missing ToT file from calib scan as input " << endl;
523 return 0;
524 }
525
526 std::cout << endl
527 << "INFO =>> [IBL] tot calib analysis..." << endl;
528
529 TFile riTotFile(inTotFile, "READ");
530 TFile riTotFileAux(inTotFileAux, "READ");
531
532 TString totHistName = "TOT_MEAN";
533 TString totSigHistName = "TOT_SIGMA";
534
535 TDirectoryFile *scanDir = (TDirectoryFile *)((TKey *)riTotFile.GetListOfKeys()->First())->ReadObj();
536 TList *rodKeyList = (TList *)scanDir->GetListOfKeys();
537 TIter rodItr(rodKeyList);
538 TKey *rodKey;
539
540 std::map<float, std::pair<vector<TString>, vector<Double_t>>> ModuDataToPrint;
541
542#if defined(DEMOXCHECK)
543 vector<TH1F *> h1_ChrgEntry(nToTibl, nullptr);
544
545 vector<TH1F *> h1d_totSprdAll(nToTibl-1, nullptr);
546
547 for (int t = 0; t < nToTibl; t++)
548 {
549 stringstream tt;
550 tt << t;
551
552 string hname = "ChrgEntries_ToT_" + tt.str();
553 h1_ChrgEntry[t] = new TH1F(hname.c_str(), "RD entries ", 100, 0., 100000);
554
555 hname = "totSprdsFll_ToT_" + tt.str();
556 if (t < nToTibl - 1)
557 h1d_totSprdAll[t] = new TH1F(hname.c_str(), "ToT spread ", 36, 0.2, 1.1);
558 }
559#endif
560
561 constexpr Int_t totFE = 14 * 16 * npsFEs; // 16 modules on each of 14 ReadOutDisk
562 using Row = Double_t[nchargeIBL];
563 using Row2 = Double_t[nToTibl];
564 //avoid stack overflow, create on heap
565 std::unique_ptr<Row[]> TotArray{ new Row[totFE]{} };
566 std::unique_ptr<Row[]> TotErrArray{ new Row[totFE]{} };
567 std::unique_ptr<Row[]> TotSigArray { new Row[totFE]{} };
568 std::unique_ptr<Row[]> TotSigErrArray{ new Row[totFE]{} };
569 std::unique_ptr<Row2[]> ChrgArray{ new Row2[totFE]{} };
570 std::unique_ptr<Row[]> ChrgErrArray{ new Row[totFE]{} };
571
572 gRandom = new TRandom3(2203);
573 using Column = Double_t[totFE];
574 std::unique_ptr<Column[]> occuPhiEta{new Column[nchargeIBL]{}};
575
576 Int_t cntRod = 0;
577 std::map<float, TString> devChrg_Order;
578 std::map<float, TString> devToT_Order;
579
580 std::multimap<float, TString, std::greater<float>> badModules_Order;
581 std::multimap<float, TString, std::greater<float>> badModules_Order_detailed;
582
583 while ((rodKey = (TKey *)rodItr()))
584 {
585 TString rodName(rodKey->GetName());
586 string rodStr(rodKey->GetName());
587 TDirectoryFile *rodDir = (TDirectoryFile *)rodKey->ReadObj();
588
589 TString path = rodDir->GetPath();
590 TString pathAux = path.ReplaceAll(rodPath, rodPathAux);
591
592 TDirectoryFile *rodDirAux = (TDirectoryFile *)riTotFileAux.Get(pathAux);
593 if (rodDirAux == NULL)
594 {
595 std::cout<< " Fail to get the rodPath in Aux: "<< pathAux << endl;
596 logout << " Fail to get the rodPath in Aux " << endl;
597 continue;
598 }
599
600 TDirectory *dirRod = roTotDir->mkdir(rodName);
601
602 TList *modKeyList = (TList *)rodDir->GetListOfKeys();
603 TIter modItr(modKeyList);
604
605 TKey *modKey;
606
607 int cntMod = 0;
608 string modNames[16 * npsFEs];
609
610 float occuChrgs[nToTibl][16 * npsFEs];
611
612#if defined(DEMOXCHECK)
613 TString feName_maxDevChrg = "", feName_maxDevToT = "";
614 float maxDevChrg = -9., maxDevToT = -9., avgDevChrg = 0., avgDevToT = 0.;
615
616 vector<TH1F *> h1d_totSprd(nToTibl - 1, nullptr);
617
618 for (int t = 0; t < nToTibl - 1; t++)
619 {
620 stringstream tt;
621 tt << t + 1;
622
623 string prfmodname = "ToT_Sprd_" + tt.str();
624 h1d_totSprd[t] = new TH1F(prfmodname.c_str(), "ToT spread ", 28, 0.3, 1.0);
625 prfmodname = rodStr + "ToT spread @ ToT_" + tt.str();
626 h1d_totSprd[t]->SetTitle(prfmodname.c_str());
627 }
628#endif
629
630 while ((modKey = (TKey *)modItr()))
631 {
632 TString modName(modKey->GetName());
633 string modStr(modKey->GetName());
634
635 TDirectory *dirMod = dirRod->mkdir(modName);
636 bool ibl3Dfe0 = false, ibl3Dfe1 = false;
637
638 int hashID = -1, hashIDL = -1, hashIDR = -1;
639 int bec = -1;
640 int layer = -1;
641 int phi_module = -1;
642 int eta_module = -1;
643 int eta_moduleL = -1, eta_moduleR = -1;
644 pixmap.mapping(modStr, &hashID, &bec, &layer, &phi_module, &eta_module);
645 if (hashID == -1)
646 {
647 pixmap.mapping(modStr + "_1", &hashID, &bec, &layer, &phi_module, &eta_module);
648 if (hashID != -1)
649 {
650 ibl3Dfe0 = true;
651 hashIDL = hashID;
652 eta_moduleL = eta_module;
653 }
654
655 pixmap.mapping(modStr + "_2", &hashID, &bec, &layer, &phi_module, &eta_module);
656 if (hashID != -1)
657 {
658 ibl3Dfe1 = true;
659 hashIDR = hashID;
660 eta_moduleR = eta_module;
661 }
662 }
663 if (hashID == -1){
664 std::cout<< "negative hash ID\n";
665 continue;
666 }
667
668
669 if (pcdMap.find(modStr) == pcdMap.end()){
670 std::cout<< "MOD not found "<< modStr << "\n";
671 continue;
672 }
673
674
675 // a stack of Charge-ToT data for ToT-charge converting
676 array<std::unique_ptr<TH2D>, npsFEs> h2d_XchrgYtot{};
677 array<std::unique_ptr<TH2D>, npsFEs> h2d_XchrgYToTSig{};
678
679 for (int sfe = 0; sfe < npsFEs; sfe++)
680 {
681 stringstream ss;
682 ss << sfe;
683
684 modNames[cntMod * npsFEs + sfe] = modStr + "-" + ss.str();
685
686 string prfmodname = modStr + "ToTvsChrg_FE" + ss.str();
687 h2d_XchrgYtot[sfe] = std::make_unique<TH2D>(prfmodname.c_str(), "ToT vs Charge", nchargeIBL, chrgsbins, nToTibl, totbins);
688
689 prfmodname = modStr + "ToT_Sig_vsChrg_FE" + ss.str();
690 h2d_XchrgYToTSig[sfe] = std::make_unique<TH2D>(prfmodname.c_str(), "ToT Sig vs Charge", nchargeIBL, chrgsbins, 100, 0., 1.);
691 }
692
693 // Fill ToT-Chrg for pixels per module
694 for (int c = 0; c < nchargeIBL; c++)
695 {
696 TString totHistDirPath = modName + "/" + totHistName + "/A0/B0/C";
697 totHistDirPath += std::to_string(c);
698
699 std::unique_ptr<TH2F> h2dTot;
700 TDirectoryFile* totHistDir(static_cast<TDirectoryFile*> (rodDir->Get(totHistDirPath)));
701 if(!totHistDir){
702 std::cout<<" Missing totHistDir in : " << totHistDirPath << endl;
703 abort();
704 }
705 else {
706 h2dTot.reset(static_cast<TH2F*> ((static_cast<TKey*>(totHistDir->GetListOfKeys()->First()))->ReadObj()));
707 if (h2dTot) h2dTot->SetDirectory(0);
708 }
709 if (not h2dTot){
710 std::cout<<" Unrecoverable error in : " <<__LINE__ <<" of CalibrateIBL.cxx\n";
711 abort();
712 }
713
714 unique_ptr<TH2F> h2dTotAux;
715 TDirectoryFile* totHistDirAux(static_cast<TDirectoryFile*>(rodDirAux->Get(totHistDirPath)));
716 if (!totHistDirAux)
717 {
718 std::cout<<" Missing totHistDir in : " << totHistDirPath << endl;
719 logout << " Missing totHistDir in : " << totHistDirPath << endl;
720 abort();
721 }
722 else {
723 h2dTotAux.reset(static_cast<TH2F*> ((static_cast<TKey*>(totHistDirAux->GetListOfKeys()->First())->ReadObj())));
724
725 if(h2dTotAux) h2dTotAux->SetDirectory(0);
726 }
727 if (not h2dTotAux){
728 std::cout<<" Unrecoverable error in : " <<__LINE__ <<" of CalibrateIBL.cxx\n";
729 abort();
730 }
731 TString totSigHistDirPath = modName + "/" + totSigHistName + "/A0/B0/C";
732 totSigHistDirPath += std::to_string(c);
733 TDirectoryFile* totSigHistDir (static_cast<TDirectoryFile*>(rodDir->Get(totSigHistDirPath)));
734 unique_ptr<TH2F> h2dTotSig (static_cast<TH2F*> ((static_cast<TKey*>(totSigHistDir->GetListOfKeys()->First()))->ReadObj()));
735 h2dTotSig->SetDirectory(0);
736
737 // Now one fill the calib-data from all pixles as basics.
738 for (int ieta = 0; ieta < ncol; ieta++)
739 {
740 for (int iphi = 0; iphi < nrow; iphi++)
741 {
742 int circ = -1;
743 if (moreFE)
744 {
745 // virtual FE with 80*84 pixels, so that sFE0, sFE1, sFE7, sFE6 will make up the physical 1'st FE
746 // while sFE2, sFE3, sFE5, sFE4 make up the physical 2'nd.
747 circ = (int)(iphi / 84.); // sFE0, sFE1, sFE2, sFE3
748 if (ieta > 80)
749 {
750 circ = 7 - circ;
751 } // sFE7, sFE6, sFE5, sFE4
752 }
753 else
754 {
755 if (ieta < ncol / 2)
756 circ = 0;
757 else
758 circ = 1;
759 }
760
761 float tot = h2dTot->GetBinContent(ieta + 1, iphi + 1) + HDCshift;
762 float totAux = h2dTotAux->GetBinContent(ieta + 1, iphi + 1);
763
764 // use ToT from higher HDC as default
765 float filltot = tot;
766
767 // use ToT from lower HDC for SMALL charges, dirty in studying
768 // May 4, 2022, please keep below strategy, it give reasonable merging till now
769
770 if (tot <= 5 || c <= 5)
771 {
772 if ((c == 0 && tot - totAux > 0.8) || (c >= 1 && c <= 3 && tot - totAux > 0.5) || (c > 4 && tot - totAux > 0.3))
773 filltot = totAux;
774 else
775 filltot = 0.5 * (totAux + tot);
776 if (c == 0 && totAux > 2.)
777 filltot = 1.;
778 }
779
780 if (c > 19)
781 filltot = 0.5 * (totAux + tot + 2.);
782
783 if (filltot > 0.){
784 h2d_XchrgYtot[circ]->Fill(chrgAbaciIBL[c], filltot, 1.);
785 }
786
787
788 float err = h2dTotSig->GetBinContent(ieta + 1, iphi + 1);
789 h2d_XchrgYToTSig[circ]->Fill(chrgAbaciIBL[c], err, 1.);
790 if (err == 0.)
791 err = 0.05;
792
793#if defined(DEMOXCHECK)
794 if (modName == XcheckModule && (iphi >= XcheckPhi[0] && iphi <= XcheckPhi[1]) && (ieta >= XcheckEta[0] && ieta <= XcheckEta[1]) && (c == XcheckCharge[0] || c == XcheckCharge[1] || (int)(tot + 0.5) == XcheckToT || (int)(totAux + 0.5) == XcheckToT))
795 logout << " tot = " << tot << ", totAux = " << totAux << " @injection " << chrgAbaciIBL[c] << " " << err << endl;
796#endif
797 }
798 } // all pixels done over a module
799
800 h2dTotSig.reset();
801 h2dTotAux.reset();
802 h2dTot.reset();
803
804 } // end looping over charges
805 float modHash = -1;
806 if (!(ibl3Dfe0 || ibl3Dfe1))
807 {
808 modHash = hashID;
809 }
810
811 array<TDirectory *, npsFEs> dirFE;
812
813 Int_t idxMod = cntRod * 16 * npsFEs + cntMod * npsFEs;
814
815 for (int sfe = 0; sfe < npsFEs; sfe++)
816 {
817 stringstream ss;
818 ss << sfe;
819
820 if (ibl3Dfe0 && sfe < npsFEs / 2)
821 {
822 modHash = hashIDL;
823 }
824 else if (ibl3Dfe1 && sfe >= npsFEs / 2)
825 {
826 modHash = hashIDR;
827 }
828 else
829 modHash += (sfe < npsFEs / 2 ? 0 : 1) * 0.8;
830
831 string prfmodname = "DirFE_" + ss.str();
832 dirFE[sfe] = dirMod->mkdir(prfmodname.c_str());
833
834 // standard deviation will be adopted for ERROR
835 prfmodname = modStr + "_profile_Tot_FE" + ss.str();
836 std::unique_ptr<TProfile> prfl_TotsFE(h2d_XchrgYtot[sfe]->ProfileX(prfmodname.c_str(), 1, -1, "s"));
837 prfl_TotsFE->SetTitle(prfmodname.c_str());
838 prfmodname = modStr + "_profile_Chrg_FE" + ss.str();
839 // shanly : seeming free from ROOT-7770 issue. 2021 Sep 17
840 std::unique_ptr<TProfile> prfl_ChrgsFE(h2d_XchrgYtot[sfe]->ProfileY(prfmodname.c_str(), 1, -1, "s"));
841 prfl_ChrgsFE->SetTitle(prfmodname.c_str());
842
843 Double_t TotArr[nchargeIBL], TotErrArr[nchargeIBL];
844 Double_t ChrgArr[nToTibl], ChrgErrArr[nToTibl];
845
846 Int_t idxFE = idxMod + sfe;
847 // ToT distribution along nchargeIBL bins charges
848 int dumbFE = 0;
849 for (int c = 0; c < nchargeIBL; c++)
850 {
851 TotArr[c] = TotArray[idxFE][c] = prfl_TotsFE->GetBinContent(c + 1);
852 TotErrArr[c] = TotErrArray[idxFE][c] = prfl_TotsFE->GetBinError(c + 1);
853
854 occuPhiEta[c][idxFE] = prfl_TotsFE->GetBinEntries(c + 1) * npsFEs / (1. * ncol * nrow);
855
856 if ((1. - occuPhiEta[c][idxFE]) > badRDfracCut)
857 dumbFE++;
858
859 stringstream sc;
860 sc << c;
861 prfmodname = modStr + "_ToTsig_FE" + ss.str() + "Chrg" + sc.str();
862
863 std::unique_ptr<TH1D> h_ToTsig(h2d_XchrgYToTSig[sfe]->ProjectionY(prfmodname.c_str(), c + 1, c + 1));
864 TotSigArray[idxFE][c] = TMath::Sqrt(h_ToTsig->GetMean() * h_ToTsig->GetMean() + h_ToTsig->GetRMS() * h_ToTsig->GetRMS());
865 TotSigErrArray[idxFE][c] = TMath::Sqrt(h_ToTsig->GetMeanError() * h_ToTsig->GetMeanError() + h_ToTsig->GetRMSError() * h_ToTsig->GetRMSError());
866
867 h_ToTsig.reset();
868 }
869 prfl_TotsFE.reset();
870
871 if (dumbFE > 5)
872 {
873 for (int c = 0; c < nchargeIBL; c++)
874 {
875 TotArr[c] = TotArray[idxFE][c] = 0.5 * (TotArray[idxFE - 1][c] + TotArray[idxFE - 2][c]);
876 TotErrArr[c] = TotErrArray[idxFE][c] = 0.5 * (TotErrArray[idxFE - 1][c] + TotErrArray[idxFE - 2][c]);
877
878 TotSigArray[idxFE][c] = 0.5 * (TotSigArray[idxFE - 1][c] + TotSigArray[idxFE - 2][c]);
879 TotSigErrArray[idxFE][c] = 0.5 * (TotSigErrArray[idxFE - 1][c] + TotSigErrArray[idxFE - 2][c]);
880
881 }
882 }
883 // Charges distribution along 16 bins ToT
884 Double_t errToT_overChrg[nToTibl];
885 for (int t = 0; t < nToTibl; t++)
886 {
887 ChrgArr[t] = ChrgArray[idxFE][t] = prfl_ChrgsFE->GetBinContent(t + 1);
888 ChrgErrArr[t] = ChrgErrArray[idxFE][t] = prfl_ChrgsFE->GetBinError(t + 1);
889
890 occuChrgs[t][cntMod * npsFEs + sfe] = prfl_ChrgsFE->GetBinEntries(t + 1) / RDentries[t];
891
892 stringstream st;
893 st << t;
894 prfmodname = modStr + "_Chrg_FE" + ss.str() + "ToT" + st.str();
895 std::unique_ptr<TH1D> h_chrg(h2d_XchrgYtot[sfe]->ProjectionX(prfmodname.c_str(), t + 1, t + 1));
896 st.str("");
897 st << totAbaci[t];
898 prfmodname = modStr + " Charge_FE" + ss.str() + " @ ToT : " + st.str();
899 h_chrg->SetTitle(prfmodname.c_str());
900
901 Double_t scl = h_chrg->Integral();
902 errToT_overChrg[t] = 0.;
903 if (scl > 0.)
904 for (int b = 0; b < nchargeIBL; b++)
905 {
906 errToT_overChrg[t] += TotErrArr[b] * (h_chrg->GetBinContent(b + 1)) / scl;
907 }
908 if (errToT_overChrg[t] == 0.)
909 errToT_overChrg[t] = 1.1;
910
911 h_chrg.reset();
912 }
913 prfl_ChrgsFE.reset();
914#if defined(DEMOXCHECK)
915 for (int b = 1; b < nToTibl; b++)
916 {
917 double err = errToT_overChrg[b];
918 h1d_totSprd[b - 1]->Fill(err);
919 h1d_totSprdAll[b - 1]->Fill(err);
920 }
921#endif
922
923 // try a correction upon dumb FE
924 if (dumbFE > 5)
925 {
926 for (int t = 0; t < nToTibl; t++)
927 {
928 ChrgArr[t] = ChrgArray[idxFE][t] = 0.5 * (ChrgArray[idxFE - 1][t] + ChrgArray[idxFE - 2][t]);
929 ChrgErrArr[t] = ChrgErrArray[idxFE][t] = 0.5 * (ChrgErrArray[idxFE - 1][t] + ChrgErrArray[idxFE - 2][t]);
930 }
931 }
932 bool xoticMod = std::find(reversedModules.begin(), reversedModules.end(), int(modHash)) != reversedModules.end();
933
934 // when charges' order are distorted along ToTs
935 bool reverseH = false, reverseT = false;
936 for (int t = 4; t >= 1; t--)
937 if (ChrgArr[t] > ChrgArr[t + 1])
938 {
939 reverseH = true;
940 break;
941 }
942 for (int t = 4; t >= 1; t--)
943 {
944 int tl = nToTibl - t;
945 if (ChrgArr[tl] < ChrgArr[tl - 1])
946 {
947 reverseT = true;
948 break;
949 }
950 }
951
952 if (reverseH)
953 {
954#if defined(DEMOXCHECK)
955 logout << " Head reversed : " << int(modHash) << " " << modName << " " << sfe << " " << ChrgArr[1] << " "
956 << ChrgArr[2] << " " << ChrgArr[3] << " " << ChrgArr[4] << " " << ChrgArr[5] << std::endl;
957#endif
958 // try a correction with some averaged factors
959 for (int t = 4; t >= 1; t--)
960 if (ChrgArr[t] > ChrgArr[t + 1] && (occuChrgs[t][cntMod * npsFEs + sfe] < 0.5 || xoticMod))
961 ChrgArr[t] = ChrgArray[idxFE][t] = reverseCF_H[t - 1] * ChrgArr[t + 1];
962 }
963 else // prepare the average factors along ToTs
964 {
965 for (int t = 4; t >= 1; t--)
966 if (ChrgArr[t + 1] != 0.)
967 reverseCF_H[t - 1] = (reverseCF_H[t - 1] == tmpRCf_H[t - 1] ? ChrgArr[t] / ChrgArr[t + 1] : 0.5 * (reverseCF_H[t - 1] + ChrgArr[t] / ChrgArr[t + 1]));
968 }
969
970 if (reverseT)
971 {
972#if defined(DEMOXCHECK)
973 logout << " Tail reversed : " << int(modHash) << " " << modName << " " << sfe << " " << ChrgArr[nToTibl - 5] << " "
974 << ChrgArr[nToTibl - 4] << " " << ChrgArr[nToTibl - 3] << " " << ChrgArr[nToTibl - 2] << " " << ChrgArr[nToTibl - 1] << std::endl;
975#endif
976 // try a correction with some averaged factors
977 for (int t = 4; t >= 1; t--)
978 {
979 int tl = nToTibl - t;
980 if (ChrgArr[tl] < ChrgArr[tl - 1] && (occuChrgs[tl][cntMod * npsFEs + sfe] < 0.5 || xoticMod))
981 ChrgArr[tl] = ChrgArray[idxFE][tl] = reverseCF_T[t - 1] * ChrgArr[tl - 1];
982 }
983 }
984 else // prepare the average factors along ToTs
985 {
986 for (int t = 4; t >= 1; t--)
987 {
988 int tl = nToTibl - t;
989 if (ChrgArr[tl - 1] != 0.)
990 reverseCF_T[t - 1] = (reverseCF_T[t - 1] == tmpRCf_T[t - 1] ? ChrgArr[tl] / ChrgArr[tl - 1] : 0.5 * (reverseCF_T[t - 1] + ChrgArr[tl] / ChrgArr[tl - 1]));
991 }
992 }
993
994 string gername = modStr + "_grToTsig_FE_" + ss.str();
995 std::unique_ptr<TGraphErrors> grTotSig = std::make_unique<TGraphErrors>(nchargeIBL, chrgAbaciIBL, TotSigArray[sfe], chargeErrArrIBL, TotSigErrArray[sfe]);
996 grTotSig->SetTitle(gername.c_str());
997 grTotSig->SetName(gername.c_str());
998
999 std::unique_ptr<TGraph> grTotSprd = std::make_unique<TGraph>(nToTibl, totAbaci, errToT_overChrg);
1000 gername = "ToTsprd";
1001 grTotSprd->SetName(gername.c_str());
1002 gername = modStr + " ToT spread over FrontEnd @ FE " + ss.str();
1003 grTotSprd->SetTitle(gername.c_str());
1004 grTotSprd->SetLineColor(4);
1005 grTotSprd->SetMarkerStyle(4);
1006 grTotSprd->SetMarkerSize(1.);
1007
1008 TF1 ToTres("ToTres", funcDispConvoluted, 0.8, 16.5, 3);
1009 ToTres.SetParameter(1,13.);
1010 ToTres.SetParameter(2,0.65);
1011 ToTres.SetParLimits(1, 10., 16.);
1012 ToTres.SetParLimits(2, 0.3, 1.0);
1013
1014 grTotSprd->Fit(&ToTres, "MRQ");
1015 Double_t parP0 = ToTres.GetParameter(0);
1016 Double_t parP1 = ToTres.GetParameter(1);
1017
1018 dirFE[sfe]->WriteTObject(grTotSprd.get());
1019 grTotSprd.reset();
1020 // Lets' keep the bad 2-para fit untill the dataBase will be updated someday
1042
1043 gername = modStr + "_grToT_FE_" + ss.str();
1044 std::unique_ptr<TGraphErrors> grTot = std::make_unique<TGraphErrors>(nchargeIBL, chrgAbaciIBL, TotArr, chargeErrArrIBL, TotErrArr);
1045 grTot->SetTitle(gername.c_str());
1046 grTot->SetName(gername.c_str());
1047 TF1 *f1ToTfromCharge = new TF1("ToTfromCharge", funcRation5, chrgAbaciIBL[0] - 100., chrgAbaciIBL[nchargeIBL - 1] + 300., 5);
1048
1049 grTot->Fit(f1ToTfromCharge, "MRQ");
1050
1051 std::unique_ptr<TGraphErrors> grChrg = std::make_unique<TGraphErrors>(nToTibl, totAbaci, ChrgArr, totErrArr, ChrgErrArr);
1052
1053 gername = modStr + "_grChrg_FE_" + ss.str();
1054 grChrg->SetName(gername.c_str());
1055 grChrg->SetTitle(gername.c_str());
1056 grChrg->SetLineColor(3);
1057 grChrg->SetLineWidth(3);
1058
1059 TF1 *f1ChargefromToTLeft = new TF1("ChargefromToTL", funcRation5, 1., 7.5, 5);
1060 f1ChargefromToTLeft->SetLineColor(2);
1061 grChrg->Fit(f1ChargefromToTLeft, "MRQ");
1062 if (f1ChargefromToTLeft->GetChisquare() / 4. > 2.){
1063 logout << "bad fit Left... " << std::endl;
1064 }
1065
1066 TF1 *f1ChargefromToTRight = new TF1("ChargefromToTR", funcRation5, 5.5, 16., 5);
1067 f1ChargefromToTRight->SetLineColor(4);
1068 grChrg->Fit(f1ChargefromToTRight, "MRQ+");
1069
1070 dirFE[sfe]->WriteTObject(grTot.get());
1071 dirFE[sfe]->WriteTObject(grTotSig.get());
1072 dirFE[sfe]->WriteTObject(h2d_XchrgYtot[sfe].get());
1073
1074 h2d_XchrgYtot[sfe].reset();
1075 h2d_XchrgYToTSig[sfe].reset();
1076 grTot.reset();
1077 grTotSig.reset();
1078 grChrg.reset();
1079
1080 // prepare a map sor sorting
1081 string Idx = "I" + ss.str();
1082 vector<TString> modName2prt;
1083 modName2prt.push_back(modName);
1084 modName2prt.push_back((TString)(Idx));
1085 // unfortunately some tuning is necessary to satisfy dataBase reauirements
1086 // 5 for module ID, 4 for threshold, nToTibl - 1 for charges at ToT, 3 for ResToT
1087 std::vector<Double_t> prtAux;
1088 prtAux.reserve(5 + 4 + nToTibl - 1 + 3); // skip ToT = 0
1089 // @ 0 ... 4
1090 prtAux.push_back(modHash);
1091 prtAux.push_back(bec);
1092 prtAux.push_back(layer);
1093 prtAux.push_back(phi_module);
1094 prtAux.push_back(eta_module);
1095
1096 modName2prt[0] = (modStr + "_" + ss.str()).c_str();
1097 if (ibl3Dfe0 && sfe < npsFEs / 2)
1098 {
1099 if (!moreFE)
1100 modName2prt[0] = modName + "_0";
1101 prtAux[0] = hashIDL;
1102 prtAux[4] = eta_moduleL;
1103 }
1104 if (ibl3Dfe1 && sfe >= npsFEs / 2)
1105 {
1106 if (!moreFE)
1107 modName2prt[0] = modName + "_1";
1108 prtAux[0] = hashIDR;
1109 prtAux[4] = eta_moduleR;
1110 }
1111
1112 // @ 5 ... 8
1113 float ThrNorm = pcdMap[modStr][Idx]["ThrNorm"];
1114 if (ThrNorm == 0. || ThrNorm == -42.)
1115 {
1116 // retrieve something from average when it's missing in calibration
1117 prtAux.push_back(THR_avg[0][sfe]);
1118 prtAux.push_back(ThrSig_avg[0][sfe]);
1119 prtAux.push_back(THR_avg[1][sfe]);
1120 prtAux.push_back(ThrSig_avg[1][sfe]);
1121 }
1122 else
1123 {
1124 prtAux.push_back(pcdMap[modStr][Idx]["ThrNorm"]);
1125 prtAux.push_back(pcdMap[modStr][Idx]["ThrSigNorm"]);
1126 prtAux.push_back(pcdMap[modStr][Idx]["ThrLong"]);
1127 prtAux.push_back(pcdMap[modStr][Idx]["ThrSigLong"]);
1128 }
1129 // since this version, the goodness will be skipped
1130 // @ 10 ... nToTibl + 8, with ToT = 0 skipped
1131 for (int t = 1; t < nToTibl; t++)
1132 prtAux.push_back(ChrgArr[t]);
1133
1134 // @ nToTibl + 9, nToTibl + 10
1135 prtAux.push_back(parP0);
1136 prtAux.push_back(parP1);
1137
1138 std::pair<vector<TString>, vector<Double_t>> payloadDB = std::pair<vector<TString>, vector<Double_t>>(modName2prt, prtAux);
1139 ModuDataToPrint.insert(std::pair<float, std::pair<vector<TString>, vector<Double_t>>>(modHash, payloadDB));
1140 } // end 1'st loop over FrontEnds
1141
1142 cntMod++;
1143 } // end of loop over Mods
1144
1145#if defined(DEMOXCHECK)
1146
1147 TDirectory *dirToTSprd = dirRod->mkdir("ToT_Spreads");
1148 for (int b = 0; b < nToTibl - 1; b++)
1149 {
1150 Int_t upper = h1d_totSprd[b]->FindLastBinAbove(1, 1);
1151 h1d_totSprd[b]->SetAxisRange(h1d_totSprd[b]->GetBinLowEdge(
1152 h1d_totSprd[b]->FindFirstBinAbove(1, 1)),
1153 h1d_totSprd[b]->GetBinLowEdge(upper) + h1d_totSprd[b]->GetBinWidth(upper), "X");
1154
1155 dirToTSprd->WriteTObject(h1d_totSprd[b]);
1156 delete h1d_totSprd[b];
1157 }
1158 h1d_totSprd.clear();
1159
1160 TString hn = "";
1161
1162 TH2F *h2_badChrgs = new TH2F(rodName + "ChargeOccupancy", "Occupancy ", nchargeIBL, 0, nchargeIBL, 16 * npsFEs, 0, 16 * npsFEs);
1163 hn = "Occupancy along charges @ " + rodName;
1164 h2_badChrgs->SetTitle(hn);
1165
1166 TH2F *h2_badToT = new TH2F(rodName + "ToTOccupancy", "Occupancy ", nToTibl - 1, 0.5, nToTibl - 0.5, 16 * npsFEs, 0, 16 * npsFEs);
1167 hn = "Occupancy along ToT @ " + rodName;
1168 h2_badToT->SetTitle(hn);
1169
1170 bool fillChrg = false, fillToT = false;
1171
1172 for (int sfe = 0; sfe < 16 * npsFEs; sfe++)
1173 {
1174 float PhiEta = 0.;
1175 for (int c = 0; c < nchargeIBL; c++)
1176 {
1177 float occu = occuPhiEta[c][cntRod * 16 * npsFEs + sfe];
1178 float nt = 10. - floor(10. * occu + 0.5);
1179 PhiEta += 0.1 * nt;
1180 TString modchrg = (TString)(modNames[sfe] + "_Chrg_" + c);
1181 if (nt > 0.01)
1182 badModules_Order_detailed.insert(std::pair<float, TString>(1. - occu, modchrg));
1183 if (nt > 5.)
1184 continue;
1185 if (nt < 0.1)
1186 nt = 0.01;
1187
1188 h2_badChrgs->SetBinContent(c + 1, sfe + 1, nt);
1189 fillChrg = true;
1190 }
1191 PhiEta /= nchargeIBL;
1192 if (PhiEta > 0.01)
1193 badModules_Order.insert(std::pair<float, TString>(PhiEta,
1194 (TString)(modNames[sfe])));
1195
1196 for (int t = 1; t < nToTibl; t++)
1197 {
1198 float nt = floor(10. * occuChrgs[t][sfe] + 0.5);
1199 if (nt > 5.)
1200 continue;
1201 h2_badToT->SetBinContent(t + 1, sfe + 1, nt);
1202 fillToT = true;
1203 }
1204
1205 TString shortName = modNames[sfe].substr(9, 13).c_str();
1206 h2_badChrgs->GetYaxis()->SetBinLabel(sfe + 1, shortName);
1207 h2_badToT->GetYaxis()->SetBinLabel(sfe + 1, shortName);
1208 h2_badChrgs->SetStats(kFALSE);
1209 h2_badToT->SetStats(kFALSE);
1210 h2_badChrgs->SetTickLength(0.01, "Y");
1211 h2_badToT->SetTickLength(0.01, "Y");
1212 }
1213
1214 h2_badChrgs->SetOption("TEXT");
1215 h2_badToT->SetOption("TEXT");
1216
1217 if (fillChrg)
1218 {
1219 dirRod->WriteTObject(h2_badChrgs, "", "Overwrite");
1220 }
1221
1222 if (fillToT)
1223 {
1224 dirRod->WriteTObject(h2_badToT, "", "WriteDelete");
1225 }
1226
1227 delete h2_badChrgs;
1228 delete h2_badToT;
1229
1230#endif
1231
1232 cntRod++;
1233 } // end of loop over Rods
1234
1235#if defined(DEMOXCHECK)
1236
1237 for (int t = 0; t < 4; t++)
1238 {
1239 if (t == 0)
1240 logout << " correction factors for reversed charges : ";
1241 logout << reverseCF_H[t] << ", ";
1242 if (t == 3)
1243 logout << endl;
1244 }
1245 for (int t = 0; t < 4; t++)
1246 {
1247 if (t == 0)
1248 logout << " correction factors for reversed charges : ";
1249 logout << reverseCF_T[t] << ", ";
1250 if (t == 3)
1251 logout << endl;
1252 }
1253
1254 for (int t = 0; t < nToTibl; t++)
1255 {
1256 if (t == 0)
1257 logout << "RD Entries per ToT bin ";
1258 logout << h1_ChrgEntry[t]->GetMean() << ", ";
1259 if (t == nToTibl - 1)
1260 logout << std::endl;
1261 roTotDir->WriteTObject(h1_ChrgEntry[t]);
1262 delete h1_ChrgEntry[t];
1263 }
1264 h1_ChrgEntry.clear();
1265
1266 for (std::map<float, TString>::const_iterator itr = devChrg_Order.begin();
1267 itr != devChrg_Order.end(); ++itr)
1268 logout << " Charge dev order : " << itr->second << " : " << itr->first << endl;
1269
1270 for (std::map<float, TString>::const_iterator itr = devToT_Order.begin();
1271 itr != devToT_Order.end(); ++itr)
1272 logout << " ToT dev order : " << itr->second << " : " << itr->first << endl;
1273
1274 logout << "ToTRes (spread) & its RMS @ ToT from 1 to 16 : " << endl;
1275 for (int t = 0; t < nToTibl - 1; t++)
1276 {
1277 if (t == 0)
1278 logout << "[ ";
1279 logout << "[ " << h1d_totSprdAll[t]->GetMean() << " , " << h1d_totSprdAll[t]->GetStdDev() << " ] ";
1280 if (t < nToTibl - 2)
1281 logout << " , " << endl;
1282 if (t == nToTibl - 2)
1283 logout << " ] " << endl;
1284 delete h1d_totSprdAll[t];
1285 }
1286 h1d_totSprdAll.clear();
1287#endif
1288
1289 logout << " goto print " << std::endl;
1290
1291 // Comment out for information only
1292 // txtDB << "####################################################################################################" << endl;
1293 // txtDB << "=========== physics meaning of each column ====================" << endl;
1294 // txtDB << "hashId " << "Threshold " << "ThresholdRMS " << "ThresholdLong " << "ThresholdRMSLong " << "Chrg_ToT1 "
1295 // << "Chrg_ToT2 " << "Chrg_ToT3 " << "Chrg_ToT4 " << "Chrg_ToT5 " << "Chrg_ToT6 " << "Chrg_ToT7 " << "Chrg_ToT8 " << "Chrg_ToT9 "
1296 // << "Chrg_ToT10 " << "Chrg_ToT11 " << "Chrg_ToT12 " << "Chrg_ToT13 " << "Chrg_ToT14 " << "Chrg_ToT15 " << "Chrg_ToT16 "
1297 // << "ToT_sprd " << " ToT_sprd_var" << endl;
1298
1299 // txtDB << "######################## TXT for IBL calibration ____Start : _> ###########################" << endl;
1300
1301 // now print the dataBase payloads in a TXT format
1302 for (std::map<float, std::pair<vector<TString>, vector<Double_t>>>::const_iterator itr = ModuDataToPrint.begin();
1303 itr != ModuDataToPrint.end(); ++itr)
1304 {
1305 int hash = floor(itr->first);
1306 std::pair<vector<TString>, vector<Double_t>> payload = itr->second;
1307 vector<Double_t> fe = payload.second;
1308
1309 txtDB << hash << " ";
1310
1311 for (unsigned int t = 5; t < fe.size(); t++)
1312 {
1313 if (t < fe.size() - 2)
1314 {
1315 txtDB << (int)(fe[t]) << " ";
1316#if defined(DEMOXCHECK)
1317 if (fe[t] > fe[t + 1] && t >= 9 && t <= 23)
1318 logout << " Reversed charge ! " << t - 5 << " " << fe[t] << " " << fe[t + 1] << std::endl;
1319#endif
1320 }
1321 else
1322 {
1323 float p01 = abs(fe[t]);
1324 if (t < fe.size() - 1)
1325 txtDB << 0.001 * (int)(p01 * 1000.) << " ";
1326 else
1327 txtDB << 0.000000001 * (int)(p01 * 1000000000.) << " ";
1328 }
1329 }
1330 txtDB << endl;
1331 }
1332 // txtDB << "####################################################################################################" << endl;
1333 // txtDB << "######################## TXT for IBL calibration <___ : End _____ ###########################" << endl;
1334 // txtDB << "####################################################################################################" << endl;
1335
1336 std::cout << " Please find the file : " << dbFileName << " for dataBase payload " << endl;
1337
1338 // statistics for BAD frontends, only for ELOG reports
1339 logout << " modules lacking in RD during Threshold scan : " << std::endl;
1340 for (std::multimap<float, TString, std::greater<float>>::const_iterator itr = badThr_Order.begin(); itr != badThr_Order.end(); ++itr)
1341 logout << " " << itr->second << " " << (itr->first) * 100. << "%" << endl;
1342
1343 logout << " modules lacking in RD during ToT scan : " << std::endl;
1344 for (std::multimap<float, TString, std::greater<float>>::const_iterator itr = badModules_Order.begin(); itr != badModules_Order.end(); ++itr)
1345 logout << " " << itr->second << " " << (itr->first) * 100. << "%" << endl;
1346
1347 logout << " modules lacking in RD at certain charges during ToT scan : " << std::endl;
1348 for (std::multimap<float, TString, std::greater<float>>::const_iterator itr = badModules_Order_detailed.begin();
1349 itr != badModules_Order_detailed.end(); ++itr)
1350 logout << " " << itr->second << " " << (itr->first) * 100. << "%" << endl;
1351
1352 roFile.Close();
1353 txtDB.close();
1354 logout.close();
1355
1356 return 0;
1357}
1358
1360 printf("ERROR - Argument not expected or wrongly set:\n\n");
1361 printf("Valid format is: ./IBLCalibration THR=SCAN_Sxxxxxxxxx TOT_HISDIS=SCAN_Sxxxxxxxxx TOT_LOWQ=SCAN_Sxxxxxxxxx directory_path=path/to/file/\n");
1362 printf("\n\t i.e: ./IBLCalibration THR=SCAN_S000087719 TOT_HISDIS=SCAN_S000087717 TOT_LOWQ=SCAN_S000087710 directory_path=/eos/user/x/xxxx/\n");
1363}
1364
1365int main(int argc, char *argv[]) {
1366
1367 bool saveInfo = false;
1368 std::string THR = "THR";
1369 std::string TOT_HISDIS = "TOT_HISDIS";
1370 std::string TOT_LOWQ = "TOT_LOWQ";
1371 std::string dpath = "directory_path";
1372
1373 for(int i=1; i<argc; i++){
1374 std::string aux(argv[i]);
1375 if (THR.compare(aux.substr(0,aux.find("="))) == 0) THR = aux.substr(aux.find("=")+1);
1376 else if(TOT_HISDIS.compare(aux.substr(0,aux.find("="))) == 0) TOT_HISDIS = aux.substr(aux.find("=")+1);
1377 else if(TOT_LOWQ.compare(aux.substr(0,aux.find("="))) == 0) TOT_LOWQ = aux.substr(aux.find("=")+1);
1378 else if(dpath.compare(aux.substr(0,aux.find("="))) == 0) dpath = aux.substr(aux.find("=")+1);
1379 else if(aux.compare("saveInfo") == 0) saveInfo = true;
1380 else{
1381 printError();
1382 return 1;
1383 }
1384 }
1385
1386 printf("%-14s = %s\n","Directory path",dpath.c_str());
1387 printf("%-14s = %s.root\n","THR",THR.c_str());
1388 printf("%-14s = %s.root\n","TOT_HISDIS",TOT_HISDIS.c_str());
1389 printf("%-14s = %s.root\n","TOT_LOWQ",TOT_LOWQ.c_str());
1390 printf("%-14s = %s\n\n\n" ,"Save root file",saveInfo ? "True" : "False" );
1391
1392 bool correctArgc = (THR.compare("THR") == 0) or (TOT_HISDIS.compare("TOT_HISDIS") == 0) or (TOT_LOWQ.compare("TOT_LOWQ") == 0) or (dpath.compare("directory_path") == 0);
1393
1394 if(correctArgc){
1395 printf("Cannot continue, one arguments is incorrect or not filled correctly...\n");
1396 printf("Helper below:\n**********************\n\n");
1397 printError();
1398 return 1;
1399 }
1400
1401 iblCalib(dpath, THR, TOT_HISDIS, TOT_LOWQ);
1402 return 0;
1403
1404}
1405
double ToTfromChrg(float chrg, double par[5])
double funcDispConvoluted(double *x, double *par)
double funcDisp(double *x, double *par)
double funcRation5(double *x, double *par)
double ChrgfromToT(float tot, double par[10])
void printError()
int iblCalib(const std::string &InDir, const std::string &THRscan, const std::string &scan, const std::string &scanLowCharge)
static std::string to_string(const std::vector< T > &v)
int upper(int c)
static Double_t ss
static Double_t sc
#define x
Define macros for attributes used to control the static checker.
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
void mapping(const std::string &geographicalID, int *hashID, int *bec, int *layer, int *phimod, int *etamod) const
double chi2(TH1 *h0, TH1 *h1)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
int main()
Definition hello.cxx:18
void scan(TDirectory *td=0, int depth=0)
Definition listroot.cxx:440
STL namespace.