Belle II Software  release-05-02-19
eclEdgeAlgorithm.cc
1 #include <ecl/calibration/eclEdgeAlgorithm.h>
2 #include <ecl/dbobjects/ECLCrystalCalib.h>
3 #include "TH1F.h"
4 #include "TMath.h"
5 #include "TString.h"
6 #include "TFile.h"
7 #include "TDirectory.h"
8 #include <iostream>
9 
10 using namespace std;
11 using namespace Belle2;
12 using namespace ECL;
13 using namespace Calibration;
14 
15 
17 eclEdgeAlgorithm::eclEdgeAlgorithm(): CalibrationAlgorithm("eclEdgeCollector")
18 {
20  "Generate payloads ECLCrystalThetaEdge and ECLCrystalPhiEdge found by eclEdgeCollector"
21  );
22 }
23 
24 
27 {
28 
29  //-----------------------------------------------------------------------------------
30  //..Read in histograms created by the collector
31  auto eclCrystalX = getObjectPtr<TH1F>("eclCrystalX");
32  auto eclCrystalY = getObjectPtr<TH1F>("eclCrystalY");
33  auto eclCrystalZ = getObjectPtr<TH1F>("eclCrystalZ");
34  auto eclCrystalR = getObjectPtr<TH1F>("eclCrystalR");
35  auto eclCrystalTheta = getObjectPtr<TH1F>("eclCrystalTheta");
36  auto eclCrystalPhi = getObjectPtr<TH1F>("eclCrystalPhi");
37  auto eclCrystalDirTheta = getObjectPtr<TH1F>("eclCrystalDirTheta");
38  auto eclCrystalDirPhi = getObjectPtr<TH1F>("eclCrystalDirPhi");
39  auto eclCrystalEdgeTheta = getObjectPtr<TH1F>("eclCrystalEdgeTheta");
40  auto eclCrystalEdgePhi = getObjectPtr<TH1F>("eclCrystalEdgePhi");
41  auto eclEdgeCounter = getObjectPtr<TH1F>("eclEdgeCounter");
42 
43  //..And write them to disk
44  TFile* histfile = new TFile("eclEdgeAlgorithm.root", "recreate");
45  eclCrystalX->Write();
46  eclCrystalY->Write();
47  eclCrystalZ->Write();
48  eclCrystalR->Write();
49  eclCrystalTheta->Write();
50  eclCrystalPhi->Write();
51  eclCrystalDirTheta->Write();
52  eclCrystalDirPhi->Write();
53  eclCrystalEdgeTheta->Write();
54  eclCrystalEdgePhi->Write();
55  eclEdgeCounter->Write();
56 
57  //-----------------------------------------------------------------------------------
58  //..Set up
59 
60  //..Number of collector calls. Intended to be 1.
61  const int nCalls = (int)(eclEdgeCounter->GetBinContent(1) + 0.0001);
62 
63  //..First crysID of each thetaID will be handy
64  int firstCrysID[69] = {};
65  for (int thetaID = 1; thetaID < 69; thetaID++) {
66  firstCrysID[thetaID] = firstCrysID[thetaID - 1] + m_crystalsPerRing[thetaID - 1];
67  }
68 
69  //..Histograms of width payloads
70  TH1F* eclCrystalWidthTheta = new TH1F("eclCrystalWidthTheta", "Width of each crystal in theta;cellID;crystal width (rad)", 8736, 1,
71  8737);
72  TH1F* eclCrystalWidthPhi = new TH1F("eclCrystalWidthPhi", "Width of each crystal in phi;cellID;crystal width (rad)", 8736, 1, 8737);
73 
74  //-----------------------------------------------------------------------------------
75  //..Edges of the crystals in theta
76  std::vector<float> tempThetaEdge;
77  std::vector<float> tempUnc(8736, 0.);
78  for (int cellID = 1; cellID <= 8736; cellID++) {
79  tempThetaEdge.push_back(eclCrystalEdgeTheta->GetBinContent(cellID) / nCalls);
80  }
81  ECLCrystalCalib* crystalThetaEdge = new ECLCrystalCalib();
82  crystalThetaEdge->setCalibVector(tempThetaEdge, tempUnc);
83  saveCalibration(crystalThetaEdge, "ECLCrystalThetaEdge");
84  B2RESULT("eclEdgeAlgorithm: successfully stored payload ECLCrystalThetaEdge");
85 
86  //-----------------------------------------------------------------------------------
87  //..Edges of the crystals in phi
88  std::vector<float> tempPhiEdge;
89  for (int cellID = 1; cellID <= 8736; cellID++) {
90  tempPhiEdge.push_back(eclCrystalEdgePhi->GetBinContent(cellID) / nCalls);
91  }
92  ECLCrystalCalib* crystalPhiEdge = new ECLCrystalCalib();
93  crystalPhiEdge->setCalibVector(tempPhiEdge, tempUnc);
94  saveCalibration(crystalPhiEdge, "ECLCrystalPhiEdge");
95  B2RESULT("eclEdgeAlgorithm: successfully stored payload ECLCrystalPhiEdge");
96 
97  //-----------------------------------------------------------------------------------
98  //..Width of the crystals in phi.
99  // Lower edge of next crystal in phi minus lower edge of crystal.
100  std::vector<float> tempPhiWidth;
101  int crysID = -1;
102  for (int thetaID = 0; thetaID < 69; thetaID++) {
103  for (int phiID = 0; phiID < m_crystalsPerRing[thetaID]; phiID++) {
104  crysID++;
105  int nextID = crysID + 1;
106  if (phiID == m_crystalsPerRing[thetaID] - 1) {nextID -= m_crystalsPerRing[thetaID];}
107  double width = tempPhiEdge[nextID] - tempPhiEdge[crysID];
108  if (width < 0) {width += 2.*TMath::Pi();}
109  tempPhiWidth.push_back(width);
110  }
111  }
112  ECLCrystalCalib* crystalPhiWidth = new ECLCrystalCalib();
113  crystalPhiWidth->setCalibVector(tempPhiWidth, tempUnc);
114  saveCalibration(crystalPhiWidth, "ECLCrystalPhiWidth");
115  B2RESULT("eclEdgeAlgorithm: successfully stored payload ECLCrystalPhiWidth");
116 
117  //..Also store in histogram
118  for (int cellID = 1; cellID <= 8736; cellID++) {
119  eclCrystalWidthPhi->SetBinContent(cellID, tempPhiWidth[cellID - 1]);
120  eclCrystalWidthPhi->SetBinError(cellID, 0.);
121  }
122  histfile->cd();
123  eclCrystalWidthPhi->Write();
124 
125  //-----------------------------------------------------------------------------------
126  //..Width in theta. Look crystals in the next thetaID that overlap in phi.
127  // Last thetaID is a special case.
128  std::vector<float> tempThetaWidth;
129  for (int thetaID = 0; thetaID < 68; thetaID++) {
130  for (int ic = firstCrysID[thetaID]; ic < firstCrysID[thetaID] + m_crystalsPerRing[thetaID]; ic++) {
131  double minThetaWidth = 999.;
132  double maxThetaWidth = -999.;
133  for (int icnext = firstCrysID[thetaID + 1]; icnext < firstCrysID[thetaID + 1] + m_crystalsPerRing[thetaID + 1]; icnext++) {
134 
135  //..Lower edge of ic falls within icnext
136  double offset = tempPhiEdge[ic] - tempPhiEdge[icnext];
137  if (offset < -TMath::Pi()) {offset += 2.*TMath::Pi();}
138  if (offset > TMath::Pi()) {offset -= 2.*TMath::Pi();}
139  if (offset >= 0. and offset < tempPhiWidth[icnext]) {
140  double width = tempThetaEdge[icnext] - tempThetaEdge[ic];
141  if (width < minThetaWidth) {minThetaWidth = width;}
142  if (width > maxThetaWidth) {maxThetaWidth = width;}
143  }
144 
145  //..Lower edge of icnext falls within ic
146  offset = tempPhiEdge[icnext] - tempPhiEdge[ic];
147  if (offset < -TMath::Pi()) {offset += 2.*TMath::Pi();}
148  if (offset > TMath::Pi()) {offset -= 2.*TMath::Pi();}
149  if (offset >= 0. and offset < tempPhiWidth[ic]) {
150  double width = tempThetaEdge[icnext] - tempThetaEdge[ic];
151  if (width < minThetaWidth) {minThetaWidth = width;}
152  if (width > maxThetaWidth) {maxThetaWidth = width;}
153  }
154 
155  }
156  tempThetaWidth.push_back(0.5 * (maxThetaWidth + minThetaWidth));
157  }
158  }
159 
160  //..Last thetaID; assume crystals end at nominal value from detector drawings
161  const double upperThetaEdge = 2.7416;
162  const int thetaID68 = 68;
163  for (int ic = firstCrysID[thetaID68]; ic < firstCrysID[thetaID68] + m_crystalsPerRing[thetaID68]; ic++) {
164  tempThetaWidth.push_back(upperThetaEdge - tempThetaEdge[ic]);
165  }
166 
167  //..Store the payload
168  ECLCrystalCalib* crystalThetaWidth = new ECLCrystalCalib();
169  crystalThetaWidth->setCalibVector(tempThetaWidth, tempUnc);
170  saveCalibration(crystalThetaWidth, "ECLCrystalThetaWidth");
171  B2RESULT("eclEdgeAlgorithm: successfully stored payload ECLCrystalThetaWidth");
172 
173  //..Also store in histogram
174  for (int cellID = 1; cellID <= 8736; cellID++) {
175  eclCrystalWidthTheta->SetBinContent(cellID, tempThetaWidth[cellID - 1]);
176  eclCrystalWidthTheta->SetBinError(cellID, 0.);
177  }
178  histfile->cd();
179  eclCrystalWidthTheta->Write();
180 
181  //-----------------------------------------------------------------------------------
182  //..Done
183  histfile->Close();
184  return c_OK;
185 }
Belle2::CalibrationAlgorithm::saveCalibration
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
Definition: CalibrationAlgorithm.cc:290
Belle2::CalibrationAlgorithm::c_OK
@ c_OK
Finished successfuly =0 in Python.
Definition: CalibrationAlgorithm.h:51
Belle2::ECLCrystalCalib
General DB object to store one calibration number per ECL crystal.
Definition: ECLCrystalCalib.h:34
Belle2::CalibrationAlgorithm::setDescription
void setDescription(const std::string &description)
Set algorithm description (in constructor)
Definition: CalibrationAlgorithm.h:331
Belle2::ECL::eclEdgeAlgorithm::calibrate
virtual EResult calibrate() override
..Run algorithm
Definition: eclEdgeAlgorithm.cc:26
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::ECL::eclEdgeAlgorithm::m_crystalsPerRing
const short m_crystalsPerRing[69]
crystals per thetaID
Definition: eclEdgeAlgorithm.h:53
Belle2::CalibrationAlgorithm::EResult
EResult
The result of calibration.
Definition: CalibrationAlgorithm.h:50
Belle2::ECLCrystalCalib::setCalibVector
void setCalibVector(const std::vector< float > &CalibConst, const std::vector< float > &CalibConstUnc)
Set vector of constants with uncertainties.
Definition: ECLCrystalCalib.h:48
Belle2::CalibrationAlgorithm
Base class for calibration algorithms.
Definition: CalibrationAlgorithm.h:47