Belle II Software development
T0Correction.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#include <cdc/calibration/T0Correction.h>
9#include <cdc/dbobjects/CDCTimeZeros.h>
10#include <cdc/geometry/CDCGeometryPar.h>
11#include <cdc/dataobjects/WireID.h>
12
13#include <TError.h>
14#include <TROOT.h>
15#include <TGraphErrors.h>
16#include <TF1.h>
17#include <TFile.h>
18#include <TChain.h>
19
20#include <framework/database/IntervalOfValidity.h>
21#include <framework/database/DBImportObjPtr.h>
22#include <framework/logging/Logger.h>
23
24using namespace std;
25using namespace Belle2;
26using namespace CDC;
27
29 m_firstExperiment(0), m_firstRun(0),
30 m_lastExperiment(-1), m_lastRun(-1)
31{
32 /*
33 setDescription(
34 " -------------------------- Test Calibration Algoritm -------------------------\n"
35 " \n"
36 " Testing algorithm which just gets mean of a test histogram collected by \n"
37 " CaTest module and provides a DB object with another histogram with one \n"
38 " entry at calibrated value. \n"
39 " ------------------------------------------------------------------------------\n"
40 );
41 */
42}
43
45{
46
47 B2INFO("CreateHisto");
48 double x;
49 double t_mea;
50 double w;
51 double t_fit;
52 double ndf;
53 double Pval;
54 int IWire;
55 int lay;
56
57 // auto& tree = getObject<TTree>("cdcCalib");
58 TChain* tree = new TChain("tree");
59 tree->Add(m_inputRootFileName.c_str());
60 tree->SetBranchAddress("lay", &lay);
61 tree->SetBranchAddress("IWire", &IWire);
62 tree->SetBranchAddress("x_u", &x);
63 tree->SetBranchAddress("t", &t_mea);
64 tree->SetBranchAddress("t_fit", &t_fit);
65 tree->SetBranchAddress("weight", &w);
66 tree->SetBranchAddress("ndf", &ndf);
67 tree->SetBranchAddress("Pval", &Pval);
68
69 /* Disable unused branch */
70 std::vector<TString> list_vars = {"lay", "IWire", "x_u", "t", "t_fit", "weight", "Pval", "ndf"};
71 tree->SetBranchStatus("*", 0);
72
73 for (TString brname : list_vars) {
74 tree->SetBranchStatus(brname, 1);
75 }
76
77
78 double halfCSize[56];
80 for (int i = 0; i < 56; ++i) {
81 double R = cdcgeo.senseWireR(i);
82 double nW = cdcgeo.nWiresInLayer(i);
83 halfCSize[i] = M_PI * R / nW;
84 }
85
86 m_hTotal = new TH1F("hTotal", "hTotal", 30, -15, 15);
87 //for each channel
88 for (int il = 0; il < 56; il++) {
89 const int nW = cdcgeo.nWiresInLayer(il);
90 for (int ic = 0; ic < nW; ++ic) {
91 m_h1[il][ic] = new TH1F(Form("h1%d@%d", il, ic), Form("L%d_cell%d", il, ic), 30, -15, 15);
92 }
93 }
94 //for each board
95 for (int ib = 0; ib < 300; ++ib) {
96 m_hT0b[ib] = new TH1F(Form("hT0b%d", ib), Form("boardID_%d", ib), 100, -20, 20);
97 }
98 //read data
99 const int nEntries = tree->GetEntries();
100 B2INFO("Number of entries: " << nEntries);
101 for (int i = 0; i < nEntries; ++i) {
102 tree->GetEntry(i);
103 double xmax = halfCSize[lay] - 0.1;
104 if ((fabs(x) < m_xmin) || (fabs(x) > xmax)
105 || (ndf < m_ndfmin)
106 || (Pval < m_Pvalmin)) continue; /*select good region*/
107 //each channel
108 m_hTotal->Fill(t_mea - t_fit);
109 m_h1[lay][IWire]->Fill(t_mea - t_fit);
110 //each board
111 m_hT0b[cdcgeo.getBoardID(WireID(lay, IWire))]->Fill(t_mea - t_fit);
112 }
113 B2INFO("Finish making histogram for all channels");
114}
115
117{
118 B2INFO("Start calibration");
119
120 gROOT->SetBatch(1);
121 gErrorIgnoreLevel = 3001;
122
123 CreateHisto();
124 static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
125
126 TF1* g1 = new TF1("g1", "gaus", -100, 100);
127 vector<double> b, db, Sb, dSb;
128 vector<double> c[56];
129 vector<double> dc[56];
130 vector<double> s[56];
131 vector<double> ds[56];
132
133 B2INFO("Gaus fitting for whole channel");
134 double par[3];
135 m_hTotal->SetDirectory(0);
136 double mean = m_hTotal->GetMean();
137 m_hTotal->Fit("g1", "Q", "", mean - 15, mean + 15);
138 g1->GetParameters(par);
139
140 B2INFO("Gaus fitting for each board");
141 for (int ib = 1; ib < 300; ++ib) {
142 if (m_hT0b[ib]->GetEntries() < 10) continue;
143 mean = m_hT0b[ib]->GetMean();
144 m_hT0b[ib]->SetDirectory(0);
145 m_hT0b[ib]->Fit("g1", "Q", "", mean - 15, mean + 15);
146 g1->GetParameters(par);
147 b.push_back(ib);
148 db.push_back(0.0);
149 Sb.push_back(par[1]);
150 dSb.push_back(g1->GetParError(1));
151 dtb[ib] = par[1];
152 err_dtb[ib] = g1->GetParError(1);
153 }
154 B2INFO("Gaus fitting for each cell");
155 for (int ilay = 0; ilay < 56; ++ilay) {
156 for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
157 const int n = m_h1[ilay][iwire]->GetEntries();
158 B2DEBUG(99, "layer " << ilay << " wire " << iwire << " entries " << n);
159 if (n < 10) continue;
160 mean = m_h1[ilay][iwire]->GetMean();
161 m_h1[ilay][iwire]->SetDirectory(0);
162 m_h1[ilay][iwire]->Fit("g1", "Q", "", mean - 15, mean + 15);
163 g1->GetParameters(par);
164 c[ilay].push_back(iwire);
165 dc[ilay].push_back(0.0);
166 s[ilay].push_back(par[1]);
167 ds[ilay].push_back(g1->GetParError(1));
168
169 dt[ilay][iwire] = par[1];
170 err_dt[ilay][iwire] = g1->GetParError(1);
171 }
172 }
173
174
175 if (m_storeHisto) {
176 B2INFO("Store histo");
177 TFile* fout = new TFile("Correct_T0.root", "RECREATE");
178 fout->cd();
179 TGraphErrors* gr[56];
180 TDirectory* top = gDirectory;
181 m_hTotal->Write();
182 TDirectory* subDir[56];
183 for (int ilay = 0; ilay < 56; ++ilay) {
184 subDir[ilay] = top ->mkdir(Form("lay_%d", ilay));
185 subDir[ilay]->cd();
186 for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
187 m_h1[ilay][iwire]->Write();
188 }
189 }
190 top->cd();
191 TDirectory* corrT0 = top->mkdir("DeltaT0");
192 corrT0->cd();
193
194 if (b.size() > 2) {
195 TGraphErrors* grb = new TGraphErrors(b.size(), &b.at(0), &Sb.at(0), &db.at(0), &dSb.at(0));
196 grb->SetMarkerColor(2);
197 grb->SetMarkerSize(1.0);
198 grb->SetTitle("#DeltaT0;BoardID;#DeltaT0[ns]");
199 grb->SetMaximum(10);
200 grb->SetMinimum(-10);
201 grb->SetName("Board");
202 grb->Write();
203 }
204 for (int sl = 0; sl < 56; ++sl) {
205 if (c[sl].size() < 2) continue;
206 gr[sl] = new TGraphErrors(c[sl].size(), &c[sl].at(0), &s[sl].at(0), &dc[sl].at(0), &ds[sl].at(0));
207 gr[sl]->SetMarkerColor(2);
208 gr[sl]->SetMarkerSize(1.0);
209 gr[sl]->SetTitle(Form("Layer_%d;IWire;#LT t_{mea}-t_{fit} #GT [ns]", sl));
210 gr[sl]->SetMaximum(10);
211 gr[sl]->SetMinimum(-10);
212 gr[sl]->SetName(Form("lay%d", sl));
213 gr[sl]->Write();
214 }
215 fout->Close();
216 }
217 B2INFO("Write constants");
218 Write();
219 return true;
220}
222{
223 static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
224 ofstream ofs(m_outputT0FileName.c_str());
226 tz.construct();
227
228 double T0;
229 TH1F* T0B[300];
230 for (int ib = 0; ib < 300; ++ib) {
231 T0B[ib] = new TH1F(Form("T0B%d", ib), Form("boardID_%d", ib), 9000, 0, 9000);
232 }
233 //for calculate T0 mean of each board
234 for (int ilay = 0; ilay < 56; ++ilay) {
235 for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
236 WireID wireid(ilay, iwire);
237 T0 = cdcgeo.getT0(wireid);
238 T0B[cdcgeo.getBoardID(wireid)]->Fill(T0);
239 }
240 }
241
242 //correct T0 and write
243 for (int ilay = 0; ilay < 56; ++ilay) {
244 for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
245 WireID wireid(ilay, iwire);
246 int bID = cdcgeo.getBoardID(wireid);
247 if (abs(err_dt[ilay][iwire]) > 2 || abs(dt[ilay][iwire]) > 1.e3) {
248 // if (abs(err_dt[ilay][iwire]) > 2) {
249 T0 = T0B[bID]->GetMean();
250 dt[ilay][iwire] = dtb[bID];
251 } else {
252 T0 = cdcgeo.getT0(wireid);
253 }
254 ofs << ilay << "\t" << iwire << "\t" << T0 - dt[ilay][iwire] << std::endl;
255 if (m_useDB) {
256 tz->setT0(wireid, T0 - dt[ilay][iwire]);
257 }
258 }
259 }
260 ofs.close();
261 if (m_useDB) {
262 IntervalOfValidity iov(m_firstExperiment, m_firstRun,
263 m_lastExperiment, m_lastRun);
264 tz.import(iov);
265 B2RESULT("T0 was calibrated and imported to database.");
266 }
267
268}
double R
typedef autogenerated by FFTW
The Class for CDC Geometry Parameters.
unsigned short getBoardID(const WireID &wID) const
Returns frontend board id. corresponding to the wire id.
float getT0(const WireID &wireID) const
Returns t0 parameter of the specified sense wire.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
T0Correction()
Constructor.
Definition: T0Correction.cc:28
virtual void Write()
write outut or store db
virtual bool calibrate()
Run algo on data.
virtual void CreateHisto()
create histo for each channel
Definition: T0Correction.cc:44
bool import(const IntervalOfValidity &iov)
Import the object to database.
Definition: DBImportBase.cc:36
Class for importing a single object to the database.
void construct(Args &&... params)
Construct an object of type T in this DBImportObjPtr using the provided constructor arguments.
A class that describes the interval of experiments/runs for which an object in the database is valid.
Class to identify a wire inside the CDC.
Definition: WireID.h:34
Abstract base class for different kinds of events.
STL namespace.