8#include <cdc/calibration/TimeWalkCalibration.h>
9#include <cdc/dbobjects/CDCTimeWalks.h>
10#include <cdc/geometry/CDCGeometryPar.h>
11#include <cdc/dataobjects/WireID.h>
16#include <TDirectory.h>
18#include <framework/utilities/FileSystem.h>
19#include <framework/database/DBImportObjPtr.h>
20#include <framework/database/DBObjPtr.h>
21#include <framework/database/IntervalOfValidity.h>
22#include <framework/logging/Logger.h>
46 TChain* tree =
new TChain(
"tree");
49 tree->SetBranchAddress(
"lay", &lay);
50 tree->SetBranchAddress(
"IWire", &IWire);
51 tree->SetBranchAddress(
"x_u", &x);
52 tree->SetBranchAddress(
"t", &t_mea);
53 tree->SetBranchAddress(
"t_fit", &t_fit);
54 tree->SetBranchAddress(
"weight", &w);
55 tree->SetBranchAddress(
"ndf", &ndf);
56 tree->SetBranchAddress(
"Pval", &Pval);
57 tree->SetBranchAddress(
"adc", &adc);
60 std::vector<TString> list_vars = {
"lay",
"IWire",
"x_u",
"t",
"t_fit",
"weight",
"Pval",
"ndf",
"adc"};
61 tree->SetBranchStatus(
"*", 0);
63 for (TString brname : list_vars) {
64 tree->SetBranchStatus(brname, 1);
70 for (
int i = 0; i < 56; ++i) {
73 halfCSize[i] = M_PI *
R / nW;
75 int nEntries = tree->GetEntries();
76 B2INFO(
"Number of entry: " << nEntries);
78 for (
int i = 0; i < 300; ++i) {
79 m_h2[i] =
new TH2D(Form(
"board_%d", i), Form(
"board_%d", i), 50, 0., 500, 60, -30, 30);
83 for (
int i = 0; i < nEntries; ++i) {
85 double xmax = halfCSize[lay] - 0.12;
86 if ((fabs(x) <
m_xmin) || (fabs(x) > xmax)
92 B2INFO(
"Reading data and filling histogram are done");
102 fold =
new TF1(
"fold",
"[0]/sqrt(x)", 0, 500);
104 fold =
new TF1(
"fold",
"[0]*exp(-1*[1]*x)", 0, 500);
108 B2INFO(
"Old time walk formular: ");
113 for (
int ib = 1; ib < 300; ++ib) {
115 B2DEBUG(199,
"Board ID:" << ib);
116 m_h2[ib]->SetDirectory(0);
119 if (
m_h2[ib]->GetEntries() < 500) {
m_flag[ib] = 0;
continue;}
121 m_h2[ib]->FitSlicesY(0, 1, -1, 10);
122 TString name =
m_h2[ib]->GetName();
123 TString hm_name = name +
"_1";
124 m_h1[ib] = (TH1D*)gDirectory->Get(hm_name);
126 m_h1[ib]->SetDirectory(0);
129 if (
m_h1[ib]->GetEntries() < 5) {
131 B2WARNING(
"Low statistic, number of points after slice fit: " <<
m_h1[ib]->GetEntries());
137 fold->SetParameter(p,
m_tw_old[ib][p]);
141 TF1* func =
new TF1(
"func",
"[0]+[1]/sqrt(x)", 0, 500);
142 func->SetParameters(-4, 28);
143 m_h1[ib]->Fit(
"func",
"MQ",
"", 20, 150);
148 B2FATAL(
"Mode " <<
m_twParamMode_new <<
" is not available, please check again");
152 TF1* f1 =
m_h1[ib]->GetFunction(
"func");
153 if (!f1) {
m_flag[ib] = 0;
continue;}
157 m_tw_new[ib][i - 1] = f1->GetParameter(i);
159 B2DEBUG(199,
"Prob of fitting:" << f1->GetProb());
160 B2DEBUG(199,
"Fitting Param 0-1:" << f1->GetParameter(0) <<
" - " << f1->GetParameter(1));
164 B2INFO(
"Storing histogram");
165 TFile* fhist =
new TFile(
"tw_histo.root",
"recreate");
166 TDirectory* old = gDirectory;
167 TDirectory* h1D = old->mkdir(
"h1D");
168 TDirectory* h2D = old->mkdir(
"h2D");
170 for (
int ib = 1; ib < 300; ++ib) {
172 m_h1[ib]->SetDirectory(0);
173 if (
m_h1[ib]->GetEntries() < 5)
continue;
175 m_h1[ib]->SetMinimum(-5);
176 m_h1[ib]->SetMaximum(15);
179 B2DEBUG(199,
"Store 2D histogram");
181 for (
int ib = 1; ib < 300; ++ib) {
183 m_h2[ib]->SetDirectory(0);
188 B2INFO(
"All hitograms were stored");
196 B2INFO(
"Store calibrated time walk parameters");
202 for (
int ib = 0; ib < 300; ++ib) {
207 dbTw->setTimeWalkParams(ib,
m_tw_old[ib]);
212 dbTw->setTimeWalkParams(ib,
m_tw_new[ib]);
216 dbTw->setTimeWalkParams(ib,
m_tw_new[ib]);
227 B2RESULT(
"Failure to calibrate time-walk for " << nfailure <<
" board");
232 B2INFO(
"Add constant term into T0 database");
239 for (
int ilay = 0; ilay < 56; ++ilay) {
240 for (
unsigned int iwire = 0; iwire < cdcgeo.
nWiresInLayer(ilay); ++iwire) {
241 WireID wireid(ilay, iwire);
243 T0 = cdcgeo.
getT0(wireid);
245 ofs << ilay <<
"\t" << iwire <<
"\t" << T0 -
m_constTerm[bID] << std::endl;
249 ofs << ilay <<
"\t" << iwire <<
"\t" << T0 << std::endl;
261 B2RESULT(
"updated constant term of tw correction to T0 constant.");
266 int max = h1->GetMaximumBin();
267 double maxX = h1->GetBinCenter(max);
268 double maxY = h1->GetBinContent(max);
269 B2DEBUG(199,
"Max: id - x - y : " << max <<
" " << maxX <<
" " << maxY);
273 h1->Fit(
"pol0",
"MQE",
"", maxX + 125, 500);
274 if (h1->GetFunction(
"pol0")) {
275 p0 = h1->GetFunction(
"pol0")->GetParameter(0);
279 TH1D* hshift =
new TH1D(
"hshift",
"shift", h1->GetNbinsX(), 0, 500);
280 hshift->SetDirectory(0);
281 for (
int i = 0; i <= h1->GetNbinsX(); ++i) {
282 hshift->SetBinContent(i, h1->GetBinContent(i) - p0);
284 hshift->Fit(
"expo",
"MQE",
"", 0, 400);
285 double p1 = maxY + p0;
287 if (hshift->GetFunction(
"expo")) {
288 p1 = exp(hshift->GetFunction(
"expo")->GetParameter(0));
289 p2 = hshift->GetFunction(
"expo")->GetParameter(1);
293 TF1* func =
new TF1(
"func",
"[0]+ [1]*exp(-1*[2]*x)", 0, 500);
294 func->SetParameters(p0, p1, -1 * p2);
295 func->SetParLimits(0, -5, 5);
296 func->SetParLimits(1, -5, 500);
297 func->SetParLimits(2, -0.01, 0.1);
298 h1->Fit(
"func",
"MQE",
"", 10, 400);
305 for (
int ib = 0; ib < 300; ++ib) {
306 m_tw_old[ib] = oldDB->getTimeWalkParams(ib);
313 if (fileName ==
"") {
316 if (fileName ==
"") {
317 B2FATAL(
"CDCGeometryPar: " << fileName1 <<
" not exist!");
319 B2INFO(
"Time Walk Calibration: open " << fileName);
320 ifs.open(fileName.c_str());
321 if (!ifs) B2FATAL(
"CDCGeometryPar: cannot open " << fileName1 <<
" !");
324 unsigned short iBoard(0);
328 while (ifs >> iBoard) {
336 if (nRead - 1 != 299) B2FATAL(
"#lines read-in (=" << nRead <<
") is not equal #boards 299 !");
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.
unsigned short m_twParamMode_new
=0 for P0/Sqrt(ADC); =1 for P0*Exp(-P1*ADC).
unsigned short m_nTwParams_new
No.
double m_xmin
minimum value cut of drift length.
virtual void readTW()
read tw from database
std::string m_outputT0FileName
Output tw file name for time walk.
TH2D * m_h2[300]
2D histogram of residual vs ADC for each board
TimeWalkCalibration()
Constructor.
double m_constTerm[300]
const term in fitting, it will be added to T0 instead tw
bool m_storeHisto
Store all Histogram or not.
double m_ndfmin
minimum number of degree of freedom required for track.
unsigned short m_flag[300]
flag for fit status
virtual void updateT0()
update constant term to t0 database.
std::vector< float > m_tw_old[300]
tw list old.
int m_lastExperiment
Last experiment.
virtual void Write()
save calibration
std::string m_InputTWFileName
Old tw file name.
std::string m_outputTWFileName
Output tw file name for time walk.
std::vector< float > m_tw_new[300]
tw list new.
virtual bool calibrate()
Run algorithm.
virtual void CreateHisto()
Create histo for calibrate.
std::string m_InputRootFileName
root input file name.
virtual void fitToExponentialFunc(TH1D *h1)
fit tw histogram
int m_firstExperiment
First experiment.
unsigned short m_twParamMode_old
=0 for P0/Sqrt(ADC); =1 for P0*Exp(-P1*ADC).
TH1D * m_h1[300]
Mean of residual as function of ADC of each board.
double m_Pvalmin
minimum number of Prob(chi2) of fitted track.
unsigned short m_nTwParams_old
No.
bool m_useDB
flag to switch btw text mode and database.
bool import(const IntervalOfValidity &iov)
Import the object to database.
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.
Class for accessing objects in the database.
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
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.
Abstract base class for different kinds of events.