Belle II Software  release-06-00-14
CDCDedxWireGainAlgorithm.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <reconstruction/calibration/CDCDedxWireGainAlgorithm.h>
10 #include <TCanvas.h>
11 #include <TMath.h>
12 #include <TLine.h>
13 #include <TStyle.h>
14 #include <algorithm>
15 #include <iostream>
16 #include <fstream>
17 #include <TH1I.h>
18 #include <TPaveText.h>
19 #include <TText.h>
20 #include <TLegend.h>
21 using namespace Belle2;
22 
23 //-----------------------------------------------------------------
24 // Implementation
25 //-----------------------------------------------------------------
27  CalibrationAlgorithm("CDCDedxElectronCollector"),
28  m_badWireFPath(""),
29  m_badWireFName(""),
30  isMakePlots(true),
31  isMergePayload(true),
32  isLTruc(false),
33  isLayerScale(true),
34  fdEdxBins(250),
35  fdEdxMin(0.0),
36  fdEdxMax(5.0),
37  fTrucMin(0.05),
38  fTrucMax(0.75),
39  fStartRun(0)
40 {
41  // Set module properties
42  setDescription("A calibration algorithm for CDC dE/dx wire gains");
43 }
44 
45 
46 //-----------------------------------------------------------------
47 // Run the calibration
48 //-----------------------------------------------------------------
50 {
51 
52  // Get data objects
53  auto ttree = getObjectPtr<TTree>("tree");
54  if (ttree->GetEntries() < 100)return c_NotEnoughData;
55 
56  const auto expRun = getRunList()[0];
57  updateDBObjPtrs(1, expRun.second, expRun.first);
58  fStartRun = expRun.second;
59 
60  //checking existing payload pointer
61  if (!m_DBBadWires.isValid())
62  B2FATAL("There is no valid payload for CDCDedxBadWires");
63 
64  if (!m_DBWireGains.isValid())
65  B2FATAL("There is no valid payload for CDCDedxWireGain");
66 
67  std::vector<int>* wire = 0;
68  std::vector<double>* dedxhit = 0;
69  ttree->SetBranchAddress("wire", &wire);
70  ttree->SetBranchAddress("dedxhit", &dedxhit);
71 
72  // dedxhit vector to store dE/dx values for each wire
73  std::vector<std::vector<double>> wirededx(14336, std::vector<double>());
74  for (int i = 0; i < ttree->GetEntries(); ++i) {
75  ttree->GetEvent(i);
76  for (unsigned int j = 0; j < wire->size(); ++j) {
77  wirededx[wire->at(j)].push_back(dedxhit->at(j));
78  }
79  }
80 
81  //25-75 is estimated values for 250 bins
82  Int_t lBinILayer = 25, hBinILayer = 75;
83  Int_t lBinOLayer = 25, hBinOLayer = 75;
84 
85  if (!isLTruc) {
86 
87  TH1D* hILayer = new TH1D(Form("hILayer_%d", fStartRun), Form("Inner Layer (start run: %d);dedxhit;entries", fStartRun), fdEdxBins,
89  TH1D* hOLayer = new TH1D(Form("hOLayer_%d", fStartRun), Form("Outer Layer (start run: %d);dedxhit;entries", fStartRun), fdEdxBins,
91 
92  for (unsigned int jwire = 0; jwire < 14336; ++jwire) {
93  for (unsigned int jdedxhit = 0; jdedxhit < wirededx[jwire].size(); ++jdedxhit) {
94  double ihitdedx = wirededx[jwire][jdedxhit];
95  if (jwire > 0 && jwire < 160 * 8)hILayer->Fill(ihitdedx);
96  else hOLayer->Fill(ihitdedx);
97  }
98  }
99  getTrucationBins(hILayer, lBinILayer, hBinILayer);
100  getTrucationBins(hOLayer, lBinOLayer, hBinOLayer);
101 
102  if (isMakePlots) {
103  TCanvas* ctem = new TCanvas("Layerhisto", "Inner and Outer Layer dedxhit dist", 900, 400);
104  ctem->Divide(2, 1);
105  ctem->cd(1);
106  hILayer->SetFillColor(kYellow);
107  double lowedge = hILayer->GetXaxis()->GetBinLowEdge(lBinILayer);
108  double upedge = hILayer->GetXaxis()->GetBinUpEdge(hBinILayer);
109  hILayer->SetTitle(Form("%s, trunc range: %0.02f - %0.02f", hILayer->GetTitle(), lowedge, upedge));
110  hILayer->Draw("histo");
111  TH1D* hILayerClone = (TH1D*)hILayer->Clone(Form("hILClone_frun%d", fStartRun));
112  hILayerClone->GetXaxis()->SetRange(lBinILayer, hBinILayer);
113  hILayerClone->SetFillColor(kAzure + 1);
114  hILayerClone->Draw("same histo");
115  ctem->cd(2);
116  lowedge = hOLayer->GetXaxis()->GetBinLowEdge(lBinOLayer);
117  upedge = hOLayer->GetXaxis()->GetBinUpEdge(hBinOLayer);
118  hOLayer->SetTitle(Form("%s trunc range: %0.02f - %0.02f", hOLayer->GetTitle(), lowedge, upedge));
119  hOLayer->SetFillColor(kYellow);
120  hOLayer->Draw("histo");
121  TH1D* hOLayerClone = (TH1D*)hOLayer->Clone(Form("hOLClone_frun%d", fStartRun));
122  hOLayerClone->GetXaxis()->SetRange(lBinOLayer, hBinOLayer);
123  hOLayerClone->SetFillColor(kAzure + 1);
124  hOLayerClone->Draw("same histo");
125  ctem->SaveAs(Form("cdcdedx_wiregain_layerdists_frun%d.pdf", fStartRun));
126  delete ctem;
127  }
128  }
129 
130 
131  TCanvas* ctmp = new TCanvas("tmp", "tmp", 1200, 1200);
132  std::stringstream psname; psname << Form("cdcdedx_wiregain_wiredists_frun%d.pdf[", fStartRun);
133  if (isMakePlots) {
134  ctmp->Divide(4, 4);
135  ctmp->SetBatch(kTRUE);
136  ctmp->Print(psname.str().c_str());
137  psname.str(""); psname << Form("cdcdedx_wiregain_wiredists_frun%d.pdf", fStartRun);
138  }
139 
140  //initialisation of wire gains
141  double iWireTruncMean[14336];
142  for (Int_t jwire = 0; jwire < 14336; jwire++) {
143  iWireTruncMean[jwire] = 1.0;
144  }
145 
146  //Calculations part
147  TH1D* htempPerWire = new TH1D(Form("htempPerWire_frun%d", fStartRun), "blah-blah", fdEdxBins, fdEdxMin, fdEdxMax);
148 
149  for (unsigned int jwire = 0; jwire < 14336; ++jwire) {
150 
151  htempPerWire->SetName(Form("htempPerWire_%d_run%d", jwire, fStartRun));
152  htempPerWire->SetTitle(Form("dedxhit-dist, wire # = %d (start run: %d);dedxhit;entries", jwire, fStartRun));
153  for (unsigned int jdedxhit = 0; jdedxhit < wirededx[jwire].size(); ++jdedxhit) {
154  htempPerWire->Fill(wirededx[jwire][jdedxhit]);
155  }
156 
157  double truncMean = 1.0;
158  int startfrom = 1, endat = 1;
159 
160  if (htempPerWire->Integral() <= 50 || m_DBBadWires->getBadWireStatus(jwire)) {
161  truncMean = 0.0; //dead or bad wire
162  } else if (htempPerWire->Integral() > 50 && htempPerWire->Integral() < 1000) {
163  truncMean = 1.0; //partial dead wire
164  } else {
165  if (!isLTruc) {
166  if (jwire < 160 * 8) {
167  startfrom = lBinILayer; endat = hBinILayer;
168  } else {
169  startfrom = lBinOLayer; endat = hBinOLayer;
170  }
171  } else {
172  getTrucationBins(htempPerWire, startfrom, endat);
173  }
174 
175  double binweights = 0.0, sumofbc = 0.0;
176  for (int ibin = startfrom; ibin <= endat; ibin++) {
177  if (htempPerWire->GetBinContent(ibin) > 0) {
178  binweights += (htempPerWire->GetBinContent(ibin) * htempPerWire->GetBinCenter(ibin));
179  sumofbc += htempPerWire->GetBinContent(ibin);
180  }
181  }
182  if (sumofbc > 0)truncMean = binweights / sumofbc;
183  else truncMean = 1.0;
184  }
185 
186  if (truncMean < 0)truncMean = 0.0; // not <=0 as 0 is reserved for dead wires
187  iWireTruncMean[jwire] = truncMean;
188 
189  if (isMakePlots) {
190  ctmp->cd(jwire % 16 + 1);
191  htempPerWire->SetFillColor(kYellow);
192  htempPerWire->SetTitle(Form("%s, rel. #mu_{truc} %0.04f", htempPerWire->GetTitle(), iWireTruncMean[jwire]));
193  htempPerWire->DrawCopy("hist");
194  TH1D* htempPerWireClone = (TH1D*)htempPerWire->Clone(Form("htempPerWireClone_%d_frun%d", jwire, fStartRun));
195  htempPerWireClone->GetXaxis()->SetRange(startfrom, endat);
196  htempPerWireClone->SetFillColor(kAzure + 1);
197  htempPerWireClone->Draw("same histo");
198  // printf("--> wire %u, rel gain = %0.04f \n", jwire, iWireTruncMean[jwire]);
199  if ((jwire + 1) % 16 == 0)ctmp->Print(psname.str().c_str());
200  }
201  htempPerWire->Reset();
202  }//end of relative gains
203 
204  delete htempPerWire;
205  if (isMakePlots) {
206  psname.str(""); psname << Form("cdcdedx_wiregain_wiredists_frun%d.pdf]", fStartRun);
207  ctmp->Print(psname.str().c_str());
208  delete ctmp;
209 
210  TCanvas* cstats = new TCanvas("cstats", "cstats", 1000, 500);
211  cstats->SetBatch(kTRUE);
212  cstats->Divide(2, 1);
213  cstats->cd(1);
214  auto hestats = getObjectPtr<TH1I>("hestats");
215  if (hestats) {
216  hestats->SetName(Form("hestats_frun%d", fStartRun));
217  hestats->SetStats(0);
218  hestats->DrawCopy("");
219  }
220  cstats->cd(2);
221  auto htstats = getObjectPtr<TH1I>("htstats");
222  if (htstats) {
223  hestats->SetName(Form("htstats_frun%d", fStartRun));
224  htstats->DrawCopy("");
225  hestats->SetStats(0);
226  }
227  cstats->Print(Form("cdcdedx_wiregain_stats_frun%d.pdf", fStartRun));
228  delete cstats;
229 
230  }
231 
232  //changing to vector array
233  std::vector<double> dedxTruncmean;
234  for (Int_t jwire = 0; jwire < 14336; jwire++) {
235  dedxTruncmean.push_back(iWireTruncMean[jwire]);
236  }
237 
238  generateNewPayloads(dedxTruncmean);
239  return c_OK;
240 }
241 
242 
243 void CDCDedxWireGainAlgorithm::generateNewPayloads(std::vector<double> dedxTruncmean)
244 {
245 
246  const auto expRun = getRunList()[0];
247  updateDBObjPtrs(1, expRun.second, expRun.first);
248 
249  if (isMergePayload) {
250  //previous dead but active now ==> abs/merge gain = rel (this is abs by default)
251  //previous dead and dead now ==> abs/merge gain = 0.0
252  //previous active and active now ==> abs/merge gain = pre*rel
253  //previous active but dead now ==> abs/merge gain = 0.0
254  //bool refchange = m_DBWireGains.hasChanged(); //for future or manjor processing
255  B2INFO("Saving merged wiregains for (Exp, Run) : (" << expRun.first << "," << expRun.second << ")");
256  for (unsigned int iwire = 0; iwire < 14336; iwire++) {
257  double pre = m_DBWireGains->getWireGain(iwire);
258  double rel = dedxTruncmean.at(iwire);
259  if (pre != 0.0)dedxTruncmean.at(iwire) *= (double)m_DBWireGains->getWireGain(iwire); //merged or 0.0
260  B2INFO("WG for wire [" << iwire << "], previous = " << pre << ", relative = " << rel << ", merged = " << dedxTruncmean.at(iwire));
261  }
262  } else {
263  B2INFO("Saving relative wiregains for (Exp, Run) : (" << expRun.first << "," << expRun.second << ")");
264  }
265 
266  double layeravg = 1.0;
267  if (isLayerScale) {
268  layeravg = getLayerAverage(dedxTruncmean);
269  for (unsigned int iwire = 0; iwire < 14336; iwire++) {
270  //merged or 0.0 for all bad/dead wire
271  if (layeravg != 0.0) {
272  dedxTruncmean.at(iwire) /= layeravg;
273  }
274  }
275  }
276 
277  //saving final constants in a histograms for validation
278  if (isMakePlots) {
279 
280  TCanvas* cLConst = new TCanvas("cLConst", "cLConst", 1600, 1000);
281  std::stringstream psnameL; psnameL << Form("cdcdedx_wiregain_layerconst_frun%d.pdf[", fStartRun);
282  cLConst->Divide(2, 2);
283  cLConst->SetBatch(kTRUE);
284  cLConst->Print(psnameL.str().c_str());
285  psnameL.str(""); psnameL << Form("cdcdedx_wiregain_layerconst_frun%d.pdf", fStartRun);
286 
287  TH1D* hWGConst = new TH1D(Form("hWGConst_frun%d", fStartRun), Form("wiregain constant (start run: %d); wire numbers;<dedxhit>",
288  fStartRun), 14336, -0.5, 14335.5);
289  if (isMergePayload)hWGConst->SetTitle(Form("abs-const: %s", hWGConst->GetTitle()));
290  else hWGConst->SetTitle(Form("rel-const: %s", hWGConst->GetTitle()));
291 
292  TH1D* hWGConstVar = new TH1D(Form("hWGConstVar_frun%d", fStartRun), Form("wiregain variation (start run: %d); wire gains; nentries",
293  fStartRun), 400, -0.5, 3.5);
294  if (isMergePayload)hWGConstVar->SetTitle(Form("abs-const: %s", hWGConstVar->GetTitle()));
295  else hWGConstVar->SetTitle(Form("rel-const: %s", hWGConstVar->GetTitle()));
296 
297  std::ofstream fBadWG;
298  fBadWG.open(Form("cdcdedx_wiregain_badwire_frun%d.txt", fStartRun));
299 
300  std::ofstream fDeadWG_New;
301  fDeadWG_New.open(Form("cdcdedx_wiregain_deadwire_frun%d_new.txt", fStartRun));
302 
303  std::ofstream fDeadWG_Old;
304  fDeadWG_Old.open(Form("cdcdedx_wiregain_deadwire_frun%d_old.txt", fStartRun));
305 
306  int toWire = 0, countwire = 0;
307  int cnewdeadwires = 0, colddeadwires = 0, cbadwires = 0;
308  for (int iLayer = 0; iLayer < 56; iLayer++) {
309 
310  int iSuperLayer = (iLayer - 2) / 6;
311  if (iSuperLayer <= 0)iSuperLayer = 1; //hack for wire#
312  int nWireiLayer = 160 + (iSuperLayer - 1) * 32;
313 
314  int fromWire = countwire;
315  toWire = toWire + nWireiLayer;
316 
317  TH1D* hLayerConst = new TH1D(Form("hWireConst_L%d_frun%d", iLayer, fStartRun), "blah-blah", nWireiLayer, fromWire * 1.0,
318  toWire * 1.0);
319  if (isMergePayload)hLayerConst->SetTitle(Form("abs-const: Layer = %d (start run: %d); wire numbers;<dedxhit>", iLayer, fStartRun));
320  else hLayerConst->SetTitle(Form("rel-const: Layer = %d (start run: %d); wire numbers;<dedxhit>", iLayer, fStartRun));
321 
322  int iwire = 0, cnewdeadLwires = 0, colddeadLwires = 0, cbadLwires = 0;
323  for (int jwire = fromWire; jwire < toWire; jwire++) {
324 
325  countwire++;
326  iwire++;
327 
328  hLayerConst->SetBinContent(iwire, dedxTruncmean.at(jwire));
329  if (iLayer < 32 && (iwire % 10 == 0))hLayerConst->GetXaxis()->SetBinLabel(iwire, Form("w%d", jwire));
330  else if (iLayer >= 32 && (iwire % 15 == 0))hLayerConst->GetXaxis()->SetBinLabel(iwire, Form("w%d", jwire));
331 
332  hWGConstVar->Fill(dedxTruncmean.at(jwire));
333  hWGConst->SetBinContent(countwire, dedxTruncmean.at(jwire));
334 
335  //see new dead wires
336  if (m_DBBadWires->getBadWireStatus(jwire)) {
337  cbadwires++;
338  cbadLwires++;
339  fBadWG << jwire << "\n";
340  }
341 
342  //see new dead wires
343  if (dedxTruncmean.at(jwire) == 0 && !m_DBBadWires->getBadWireStatus(jwire)) {
344  cnewdeadwires++;
345  cnewdeadLwires++;
346  fDeadWG_New << jwire << "\n";
347  }
348 
349  //see old dead wires
350  if (m_DBWireGains->getWireGain(jwire) == 0 && !m_DBBadWires->getBadWireStatus(jwire)) {
351  colddeadwires++;
352  colddeadLwires++;
353  fDeadWG_Old << jwire << "\n";
354  }
355 
356  if ((countwire) % 500 == 0)hWGConst->GetXaxis()->SetBinLabel(countwire, Form("w%d", countwire));
357  }
358 
359  cLConst->cd(iLayer % 4 + 1);
360  gStyle->SetOptStat("ne");
361  double fraclbad = (100.0 * (cnewdeadLwires + cbadLwires)) / nWireiLayer;
362  if (isLayerScale)hLayerConst->SetTitle(Form("%s, avg = %0.04f, nDeadwires = %d->%d(%0.02f%%)", hLayerConst->GetTitle(),
363  flayerAvg.at(iLayer) / layeravg, colddeadLwires + cbadLwires, cnewdeadLwires + cbadLwires, fraclbad));
364  else hLayerConst->SetTitle(Form("%s, nDeadwires = %d->%d(%0.02f%%)", hLayerConst->GetTitle(), colddeadLwires + cbadLwires,
365  cnewdeadLwires + cbadLwires,
366  fraclbad));
367  if (iLayer < 8)hLayerConst->GetYaxis()->SetRangeUser(-0.1, 4.0);
368  else hLayerConst->GetYaxis()->SetRangeUser(-0.1, 2.0);
369  hLayerConst->SetFillColorAlpha(kAzure, 0.10);
370  hLayerConst->LabelsOption("u", "X");
371  hLayerConst->DrawCopy("hist");
372  if (isLayerScale) {
373  TLine* tlc = new TLine();
374  tlc->SetLineColor(kRed);
375  tlc->SetX1(fromWire); tlc->SetX2(toWire);
376  tlc->SetY1(flayerAvg.at(iLayer) / layeravg); tlc->SetY2(flayerAvg.at(iLayer) / layeravg);
377  tlc->DrawClone("same");
378  delete tlc;
379  }
380  if ((iLayer + 1) % 4 == 0)cLConst->Print(psnameL.str().c_str());
381  hLayerConst->Reset();
382  delete hLayerConst;
383  }
384 
385  psnameL.str(""); psnameL << Form("cdcdedx_wiregain_layerconst_frun%d.pdf]", fStartRun);
386  cLConst->Print(psnameL.str().c_str());
387  delete cLConst;
388 
389  TCanvas* cConst = new TCanvas("cConst", "cConst", 900, 500);
390  cConst->cd();
391  cConst->SetGridy(1);
392  hWGConst->LabelsOption("u", "X");
393  hWGConst->GetYaxis()->SetRangeUser(-0.1, hWGConst->GetMaximum() * 1.05);
394  double fracabad = (100.0 * (cnewdeadwires + cbadwires)) / 14336.0;
395  if (isMergePayload)hWGConst->SetTitle(Form("merged %s, nDeadwires = %d->%d (%0.02f%%)", hWGConst->GetTitle(),
396  colddeadwires + cbadwires,
397  cnewdeadwires + cbadwires, fracabad));
398  else hWGConst->SetTitle(Form("relative %s, nDeadwires = %d->%d (%0.02f%%)", hWGConst->GetTitle(), colddeadwires + cbadwires,
399  cnewdeadwires + cbadwires,
400  fracabad));
401  // hWGConst->SetStats(0);
402  hWGConst->LabelsDeflate();
403  hWGConst->Draw("");
404  cConst->SaveAs(Form("cdcdedx_wiregain_allconstants_frun%d.pdf", fStartRun));
405  delete cConst;
406 
407  TCanvas* cConstvar = new TCanvas("cConstvar", "cConstvar", 500, 400);
408  cConstvar->cd();
409  if (isMergePayload)hWGConstVar->SetTitle(Form("merged %s, nDeadwires = %d->%d (%0.02f%%)", hWGConstVar->GetTitle(),
410  colddeadwires + cbadwires,
411  cnewdeadwires + cbadwires,
412  fracabad));
413  else hWGConstVar->SetTitle(Form("relative %s, bad wire = %d->%d (%0.02f)", hWGConstVar->GetTitle(), colddeadwires + cbadwires,
414  cnewdeadwires + cbadwires,
415  fracabad));
416  //hWGConst->SetStats(0);
417  hWGConstVar->SetFillColorAlpha(kAzure, 0.10);
418  hWGConstVar->Draw("");
419  cConstvar->SaveAs(Form("cdcdedx_wiregain_constantsvar_frun%d.pdf", fStartRun));
420  delete cConstvar;
421 
422  fBadWG.close();
423  fDeadWG_New.close();
424  fDeadWG_Old.close();
425 
426  //create nice plots for bad wire status
427  plotBadWires(cnewdeadwires, colddeadwires, cbadwires);
428  }
429 
430  B2INFO("dE/dx Calibration done for " << dedxTruncmean.size() << " CDC wires");
431  CDCDedxWireGain* gains = new CDCDedxWireGain(dedxTruncmean);
432  saveCalibration(gains, "CDCDedxWireGain");
433 }
434 
435 
436 void CDCDedxWireGainAlgorithm::getTrucationBins(TH1D* htemp, int& binlow, int& binhigh)
437 {
438  //calculating truncation average
439  double TotalInt = htemp->Integral();
440  if (TotalInt <= 0 || htemp->GetNbinsX() <= 0) {
441  binlow = 1.0; binhigh = 1.0;
442  return;
443  } else {
444  binlow = 1.0; binhigh = 1.0;
445  double sumPer5 = 0.0, sumPer75 = 0.0;
446  for (int ibin = 1; ibin <= htemp->GetNbinsX(); ibin++) {
447 
448  if (sumPer5 <= fTrucMin * TotalInt) {
449  sumPer5 += htemp->GetBinContent(ibin);
450  binlow = ibin;
451  }
452 
453  if (sumPer75 <= fTrucMax * TotalInt) {
454  sumPer75 += htemp->GetBinContent(ibin);
455  binhigh = ibin;
456  }
457  }
458  }
459 }
460 
461 double CDCDedxWireGainAlgorithm::getLayerAverage(std::vector<double> tempWire)
462 {
463  //calculating layer average
464  double jLayerMeanAvg = 0.0, OutLayerMeanSum = 0.0;
465  int toWire = 0;
466  int countwire = 0, OutActLayer = 0;
467 
468  TH1D* hLayerAvg = new TH1D(Form("hLayerAvg_frun%d", fStartRun),
469  Form("Layer vs trunc mean avg (star run: %d); layer numbers;<dedxhit>", fStartRun), 56, -0.5, 55.5);
470 
471  for (int iLayer = 0; iLayer < 56; iLayer++) {
472 
473  int iSuperLayer = (iLayer - 2) / 6;
474  if (iSuperLayer <= 0)iSuperLayer = 1; //hack for wire#
475  int nWireiLayer = 160 + (iSuperLayer - 1) * 32;
476 
477  int fromWire = countwire; // or towire+countwire
478  toWire = toWire + nWireiLayer;
479 
480  double jLayerMeanSum = 0.0;
481  int jLayerActWires = 0;
482  std::cout << "iLayer = " << iLayer << ", from wire = " << fromWire << ", to wire = " << toWire << std::endl;
483  for (int jwire = fromWire; jwire < toWire; jwire++) {
484  countwire++;
485  if (tempWire.at(jwire) > 0.) { //active wire only
486  jLayerMeanSum += tempWire.at(jwire);
487  jLayerActWires++;
488  } else continue;
489  }
490 
491  if (jLayerActWires > 0)jLayerMeanAvg = jLayerMeanSum / jLayerActWires;
492  else jLayerMeanAvg = 0.0;
493 
494  flayerAvg.push_back(jLayerMeanAvg);
495  hLayerAvg->SetBinContent(iLayer + 1, jLayerMeanAvg);
496  if ((iLayer + 1) % 2 == 0)hLayerAvg->GetXaxis()->SetBinLabel(iLayer + 1, Form("L%d", iLayer));
497  std::cout << " \t --> sum = " << jLayerMeanSum << ", active wires = " << jLayerActWires
498  << ", average = " << jLayerMeanAvg << std::endl;
499 
500  if (iLayer >= 8 && jLayerMeanAvg > 0.0) {
501  OutLayerMeanSum += jLayerMeanAvg;
502  OutActLayer++; //if any layer is completely dead
503  }
504  }
505 
506  double OutLayerMeanAvg = 1.0;
507  if (OutActLayer > 0) OutLayerMeanAvg = OutLayerMeanSum / OutActLayer;
508 
509  if (isMakePlots) {
510  TCanvas* cLAvg = new TCanvas("clayerAvg", "clayerAvg", 800, 500);
511  cLAvg->SetGridy(1);
512  cLAvg->cd();
513  gStyle->SetOptStat("ne");
514  hLayerAvg->LabelsOption("u", "X");
515  hLayerAvg->SetLineColor(kBlue);
516  hLayerAvg->GetYaxis()->SetRangeUser(-0.1, hLayerAvg->GetMaximum() * 1.20);
517  if (isMergePayload)hLayerAvg->SetTitle(Form("%s, avg = %0.04f (abs)", hLayerAvg->GetTitle(), OutLayerMeanAvg));
518  else hLayerAvg->SetTitle(Form("%s, avg = %0.04f (rel)", hLayerAvg->GetTitle(), OutLayerMeanAvg));
519  hLayerAvg->LabelsDeflate();
520  hLayerAvg->Draw("");
521  TLine* tl = new TLine();
522  tl->SetLineColor(kRed);
523  tl->SetX1(-0.5); tl->SetX2(55.5);
524  tl->SetY1(OutLayerMeanAvg); tl->SetY2(OutLayerMeanAvg);
525  tl->DrawClone("same");
526  cLAvg->SaveAs(Form("cdcdedx_wiregain_layeravg_frun%d.pdf", fStartRun));
527  delete cLAvg;
528  }
529  return OutLayerMeanAvg;
530 }
531 
532 void CDCDedxWireGainAlgorithm::plotBadWires(int nDeadwires, int oDeadwires, int Badwires)
533 {
534 
535  TCanvas* cCDCWires = new TCanvas(Form("cCDCWires_frun%d", fStartRun), "CDC dE/dx bad wire status", 800, 800);
536  TH2F* hxyAll = getHistoPattern("all", "allwires");
537  hxyAll->SetMarkerStyle(20);
538  hxyAll->SetMarkerSize(0.2);
539  hxyAll->SetMarkerColor(kGray);
540  hxyAll->SetStats(0);
541  hxyAll->Draw();
542 
543 
544  TH2F* hxyBad = getHistoPattern(Form("cdcdedx_wiregain_badwire_frun%d.txt", fStartRun), "badwire");
545  if (hxyBad) {
546  hxyBad->SetTitle("");
547  hxyBad->SetMarkerStyle(20);
548  hxyBad->SetMarkerSize(0.3);
549  hxyBad->SetMarkerColor(kBlue);
550  hxyBad->SetStats(0);
551  hxyBad->Draw("same");
552  }
553 
554  TH2F* hxyOldDead = getHistoPattern(Form("cdcdedx_wiregain_deadwire_frun%d_old.txt", fStartRun), "olddead");
555  if (hxyOldDead) {
556  hxyOldDead->SetTitle("");
557  hxyOldDead->SetMarkerStyle(20);
558  hxyOldDead->SetMarkerSize(0.3);
559  hxyOldDead->SetMarkerColor(kBlack);
560  hxyOldDead->SetStats(0);
561  hxyOldDead->Draw("same");
562  }
563 
564  TH2F* hxyNewDead = getHistoPattern(Form("cdcdedx_wiregain_deadwire_frun%d_new.txt", fStartRun), "newdead");
565  if (hxyNewDead) {
566  hxyNewDead->SetTitle("");
567  hxyNewDead->SetMarkerStyle(20);
568  hxyNewDead->SetMarkerSize(0.25);
569  hxyNewDead->SetMarkerColor(kRed);
570  hxyNewDead->SetStats(0);
571  hxyNewDead->Draw("same");
572  }
573 
574  auto legend = new TLegend(0.72, 0.80, 0.90, 0.92);
575  legend->SetBorderSize(0);
576  legend->SetLineWidth(3);
577  legend->SetHeader(Form("Total Bad: %d (~%0.02f%%)", nDeadwires + Badwires, 100.*(nDeadwires + Badwires) / 14336.0));
578  legend->AddEntry(hxyBad, Form("badadc %d" , Badwires), "p");
579  legend->AddEntry(hxyOldDead, Form("olddead %d" , oDeadwires), "p");
580  legend->AddEntry(hxyNewDead, Form("newdead %d" , nDeadwires), "p");
581  legend->Draw();
582 
583  gStyle->SetLegendTextSize(0.025);
584  TPaveText* pt = new TPaveText(-0.30993, -1.470968, -0.3102707, -1.304516, "br");
585  pt->SetFillColor(0);
586  pt->SetFillStyle(3001);
587  pt->SetLineColor(2);
588  pt->SetTextFont(82);
589  pt->SetTextSize(0.02258064);
590  TText* t1 = pt->AddText("CDC-wire map: counter-clockwise and start from +x");
591  t1->SetTextColor(kGray + 1);
592  pt->Draw("same");
593 
594  cCDCWires->SaveAs(Form("cdcdedx_wiregain_wirestatus_frun%d.pdf", fStartRun));
595  delete cCDCWires;
596 }
597 
598 TH2F* CDCDedxWireGainAlgorithm::getHistoPattern(TString badFileName, TString suffix = "")
599 {
600 
601  int wire, nwire, twire;
602  double radius, phi, x, y;
603 
604  std::ifstream infile;
605  infile.open(Form("%s", badFileName.Data()));
606 
607  TH2F* temp = new TH2F(Form("temp_%s_frun%d", suffix.Data(), fStartRun), Form("wire status (start run: %d)", fStartRun), 2400, -1.2,
608  1.2, 2400, -1.2, 1.2);
609  if (!infile.fail()) {
610  int bwires = 0;
611  while (infile >> bwires) {
612  nwire = getIndexVal(bwires, "nwirelayer");
613  twire = getIndexVal(bwires, "twire");
614  radius = getIndexVal(bwires, "rwire");
615  wire = bwires - twire ;
616  phi = 2.*TMath::Pi() * (float(wire) / float(nwire));
617  x = radius * cos(phi);
618  y = radius * sin(phi);
619  temp->Fill(x, y);
620  }
621  } else {
622  for (int iwires = 0; iwires < 14336; iwires++) {
623  nwire = getIndexVal(iwires, "nwirelayer");
624  twire = getIndexVal(iwires, "twire");
625  radius = getIndexVal(iwires, "rwire");
626  wire = iwires - twire ;
627  phi = 2.*TMath::Pi() * (float(wire) / float(nwire));
628  x = radius * cos(phi);
629  y = radius * sin(phi);
630  temp->Fill(x, y);
631  }
632  }
633  return temp;
634 }
635 
636 double CDCDedxWireGainAlgorithm::getIndexVal(int iWire, TString what)
637 {
638  //radius of each CDC layer
639  double r[56] = {
640  16.80, 17.80, 18.80, 19.80, 20.80, 21.80, 22.80, 23.80,
641  25.70, 27.52, 29.34, 31.16, 32.98, 34.80,
642  36.52, 38.34, 40.16, 41.98, 43.80, 45.57,
643  47.69, 49.46, 51.28, 53.10, 54.92, 56.69,
644  58.41, 60.18, 62.00, 63.82, 65.64, 67.41,
645  69.53, 71.30, 73.12, 74.94, 76.76, 78.53,
646  80.25, 82.02, 83.84, 85.66, 87.48, 89.25,
647  91.37, 93.14, 94.96, 96.78, 98.60, 100.37,
648  102.09, 103.86, 105.68, 107.50, 109.32, 111.14
649  };
650 
651  Int_t totalWireiLayer = 0 ;
652  double myreturn = 0;
653  for (Int_t iLayer = 0; iLayer < 56; iLayer++) {
654  int iSuperLayer = (iLayer - 2) / 6;
655  if (iSuperLayer <= 0)iSuperLayer = 1;
656  int nWireiLayer = 160 + (iSuperLayer - 1) * 32;
657  totalWireiLayer += nWireiLayer;
658 
659  if (iWire < totalWireiLayer) {
660  if (what == "layer")myreturn = iLayer;
661  else if (what == "nwirelayer") myreturn = nWireiLayer;
662  else if (what == "twire") myreturn = totalWireiLayer - nWireiLayer;
663  else if (what == "rwire") myreturn = r[iLayer] / 100.;
664  else std::cout << "Invalid return :0 " << std::endl;
665  break;
666  }
667  }
668  return myreturn;
669 }
bool isLayerScale
method of scaling layer avg
double fTrucMax
max trunc range for mean
double getLayerAverage(std::vector< double > tempWire)
function to get layer avg from outer layers
TH2F * getHistoPattern(TString badFileName, TString suffix)
function to plot wires in hist with input file
int fStartRun
boundary start at this run
double fdEdxMax
max dedx range for wiregain cal
bool isMergePayload
merge payload at the of calibration
bool isLTruc
method of trunc range for mean
DBObjPtr< CDCDedxBadWires > m_DBBadWires
Bad wire DB object.
std::vector< double > flayerAvg
layer wire avg of trun mean
CDCDedxWireGainAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
DBObjPtr< CDCDedxWireGain > m_DBWireGains
Wire gain DB object.
double fTrucMin
min trunc range for mean
double getIndexVal(int iWire, TString what)
function to return various CDC indexing for given wire
virtual EResult calibrate() override
Wire gain algorithm.
double fdEdxMin
min dedx range for wiregain cal
void getTrucationBins(TH1D *htemp, int &binlow, int &binhigh)
function to get bins of trunction from histogram
int fdEdxBins
number of bins for dedx histogram
bool isMakePlots
produce plots for status
void plotBadWires(int nDeadwires, int oDeadwires, int Badwires)
function to plot bad wire status (then and now)
void generateNewPayloads(std::vector< double > dedxTruncmean)
function to finally store new payload after full calibration
dE/dx wire gain calibration constants
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
Abstract base class for different kinds of events.