Belle II Software  release-08-01-10
CrudeT0CalibrationAlgorithm.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/CrudeT0CalibrationAlgorithm.h>
9 #include <calibration/CalibrationAlgorithm.h>
10 #include <cdc/geometry/CDCGeometryPar.h>
11 #include <cdc/dbobjects/CDCTimeZeros.h>
12 #include <framework/gearbox/Const.h>
13 #include <TError.h>
14 #include <TROOT.h>
15 #include <TF1.h>
16 #include <TFile.h>
17 #include <TTree.h>
18 
19 #include <framework/datastore/StoreObjPtr.h>
20 #include <framework/database/Database.h>
21 #include <framework/database/DBObjPtr.h>
22 #include <framework/database/IntervalOfValidity.h>
23 #include <framework/database/DBImportObjPtr.h>
24 #include <framework/logging/Logger.h>
25 using namespace std;
26 using namespace Belle2;
27 using namespace CDC;
28 
29 CrudeT0CalibrationAlgorithm::CrudeT0CalibrationAlgorithm(): CalibrationAlgorithm("CDCCrudeT0Collector")
30 {
31 
33  " -------------------------- T0 Calibration Algorithm -------------------------\n"
34  );
35 }
36 
38 
39 {
40 
41  B2INFO("CreateHisto");
42 
43  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
44  const auto exprun = getRunList();
45  B2INFO("Changed ExpRun to: " << exprun[0].first << " " << exprun[0].second);
46  evtPtr->setExperiment(exprun[0].first);
47  evtPtr->setRun(exprun[0].second);
49  B2INFO("create TDChist");
50 
51  for (int il = 0; il < 56; ++il) {
52  for (unsigned short w = 0; w < cdcgeo.nWiresInLayer(il); ++w) {
53  m_hTDC[il][w] = new TH1D(Form("hLay%d_ch%d", il, w), "tdc", m_tdcMax - m_tdcMin, m_tdcMin, m_tdcMax);
54  }
55  }
56 
57  B2INFO("create TDChist(board)");
58  for (int ib = 0; ib < 300; ++ib) {
59  m_hTDCBoard[ib] = new TH1D(Form("hTDCBoard%d", ib), "", m_tdcMax - m_tdcMin, m_tdcMin, m_tdcMax);
60  }
61  m_hT0All = new TH1D("hT0All", "", 8500, 0, 8500);
62 
63  unsigned short lay;
64  unsigned short wire;
65  unsigned short tdc;
66  auto tree = getObjectPtr<TTree>("tree");
67  tree->SetBranchAddress("lay", &lay);
68  tree->SetBranchAddress("wire", &wire);
69  tree->SetBranchAddress("tdc", &tdc);
70 
71  const int nEntries = tree->GetEntries();
72  B2INFO("fill hist");
73  for (int i = 0; i < nEntries ; ++i) {
74  tree->GetEntry(i);
75  m_hTDC[lay][wire]->Fill(tdc);
76  m_hTDCBoard[cdcgeo.getBoardID(WireID(lay, wire))]->Fill(tdc);
77  m_hT0All->Fill(tdc);
78  }
79  B2INFO("end of filling hist");
80 }
81 
83 {
84  B2INFO("Start calibration");
85 
86  gROOT->SetBatch(1);
87  gErrorIgnoreLevel = 3001;
88 
89  // We create an EventMetaData object. But since it's possible we're re-running this algorithm inside a process
90  // that has already created a DataStore, we need to check if it's already valid, or if it needs registering.
92  if (!evtPtr.isValid()) {
93  // Construct an EventMetaData object in the Datastore so that the DB objects in CDCGeometryPar can work
95  B2INFO("Registering EventMetaData object in DataStore");
96  evtPtr.registerInDataStore();
98  B2INFO("Creating EventMetaData object");
99  evtPtr.create();
100  } else {
101  B2INFO("A valid EventMetaData object already exists.");
102  }
103  // Construct a CDCGeometryPar object which will update to the correct DB values when we change the EventMetaData and update
104  // the Database instance
105  DBObjPtr<CDCGeometry> cdcGeometry;
106  CDC::CDCGeometryPar::Instance(&(*cdcGeometry));
107  B2INFO("ExpRun at init : " << evtPtr->getExperiment() << " " << evtPtr->getRun());
108 
109  createHisto(evtPtr);
110 
111  TH1D* hs = new TH1D("hs", "sigma", 100, 0, 20);
112  std::vector<double> sb;
113  std::vector<double> dsb;
114  std::vector<double> t0b;
115  std::vector<double> dt0b;
116  std::vector<double> b;
117  std::vector<double> db;
118 
119  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
120  TF1* f1 = new TF1("f1", "[0]+[1]*(exp([2]*(x-[3]))/(1+exp(-([4]-x)/[5])))", m_tdcMin, m_tdcMax);
121  f1->SetParLimits(0, 0., 1000.);
122  f1->SetLineColor(kRed);
123  const double tdcBinWidth = cdcgeo.getTdcBinWidth();
124  bool bflag[300] = {false};
125 
126  for (int ib = 1; ib < 300; ++ib) {
127  if (m_hTDCBoard[ib]->GetEntries() < m_minEntries) {
128  B2DEBUG(199, "Warning: this board low statistic: " << m_hTDCBoard[ib]->GetEntries());
129  bflag[ib] = false;
130  m_t0b[ib] = m_initT0;
131  continue;
132  }
133  double p3 = m_hTDCBoard[ib]->GetXaxis()->GetBinCenter(m_hTDCBoard[ib]->GetMaximumBin());
134  f1->SetParameters(0, m_hTDCBoard[ib]->GetMaximum(), -0.001, p3, m_initT0, 2.5);
135  m_hTDCBoard[ib]->Fit("f1", "QM", "", m_initT0 - 60, m_initT0 + 60);
136 
137  if ((fabs(f1->GetParameter(4) - m_initT0) > 100)
138  || (fabs(f1->GetParameter(5)) < 0.01)
139  || (fabs(f1->GetParameter(5)) > 16)) {
140 
141  bflag[ib] = false;
142  m_t0b[ib] = m_initT0;
143  continue;
144  }
145 
146  bflag[ib] = true;
147  m_t0b[ib] = f1->GetParameter(4) * tdcBinWidth;
148 
149  sb.push_back(f1->GetParameter(5));
150  dsb.push_back(f1->GetParError(5));
151  t0b.push_back(f1->GetParameter(4));
152  dt0b.push_back(f1->GetParError(4));
153  b.push_back(ib);
154  db.push_back(0);
155  }
156 
157  for (int il = 0; il < 56; ++il) {
158  for (unsigned short w = 0; w < cdcgeo.nWiresInLayer(il); ++w) {
159  B2DEBUG(99, "fitting for channel: " << il << " - " << w);
160  B2DEBUG(99, "number of entries" << m_hTDC[il][w]->GetEntries());
161  m_t0[il][w] = m_initT0 * tdcBinWidth;
162  int bid = cdcgeo.getBoardID(WireID(il, w));
163  if (m_hTDC[il][w]->GetEntries() < m_minEntries) {
164  B2DEBUG(99, "Warning: low statistic channel: " << m_hTDC[il][w]->GetEntries());
165  if (bflag[bid] != false) {
166  m_t0[il][w] = m_t0b[bid];
167  m_flag[il][w] = true;
168  } else {
169  m_flag[il][w] = false;
170  }
171  } else {
172  double p3 = m_hTDC[il][w]->GetXaxis()->GetBinCenter(m_hTDC[il][w]->GetMaximumBin());
173  f1->SetParameters(0, m_hTDC[il][w]->GetMaximum(), -0.001, p3, m_initT0, 2.5);
174  m_hTDC[il][w]->Fit("f1", "QM", "", m_initT0 - 60, m_initT0 + 60);
175  B2DEBUG(99, "prob of fit : " << f1->GetProb());
176  if ((f1->GetProb() < 1E-150) || (fabs(f1->GetParameter(4) - m_initT0) > 100) || (f1->GetParameter(5) < 0.1)
177  || (f1->GetParameter(5) > 20)) {
178  if (bflag[bid] != 0) {
179  m_t0[il][w] = m_t0b[bid];
180  m_flag[il][w] = true;
181  } else {
182  m_flag[il][w] = false;
183  }
184  } else {
185  m_t0[il][w] = f1->GetParameter(4) * tdcBinWidth;
186  hs->Fill(f1->GetParameter(5));
187  m_flag[il][w] = true;
188  }
189  }
190 
191  B2DEBUG(99, "P4 = " << m_t0[il][w]);
192  if (m_cosmic && cdcgeo.wireBackwardPosition(il, w).Y() > 0) {
193  m_t0[il][w] -= cdcgeo.senseWireR(il) / Const::speedOfLight;
194  } else {
195  m_t0[il][w] += cdcgeo.senseWireR(il) / Const::speedOfLight;
196  }
197  m_t0[il][w] += (m_zOffset - cdcgeo.wireBackwardPosition(il, w).Z()) / 27.25;
198  m_t0[il][w] += 6.122;
199  m_hT0All->Fill(m_t0[il][w]);
200  }
201  }
202 
203  B2INFO("Write constants");
204  write(evtPtr);
205  saveHisto();
206  return c_OK;
207 }
208 
210 {
211  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
212  const auto exprun = getRunList();
213  B2INFO("Changed ExpRun to: " << exprun[0].first << " " << exprun[0].second);
214  evtPtr->setExperiment(exprun[0].first);
215  evtPtr->setRun(exprun[0].second);
217 
218  CDCTimeZeros* tz = new CDCTimeZeros();
219  for (int ilay = 0; ilay < 56; ++ilay) {
220  for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
221  WireID wireid(ilay, iwire);
222  tz->setT0(wireid, m_t0[ilay][iwire]);
223  }
224  }
225  saveCalibration(tz, "CDCTimeZeros");
226 }
227 
229 {
230  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
231  TFile* fhist = new TFile("histCrudeT0.root", "recreate");
232  fhist->cd();
233  TDirectory* top = gDirectory;
234  TDirectory* Direct[56];
235  for (int il = 0; il < 56; ++il) {
236  top->cd();
237  Direct[il] = gDirectory->mkdir(Form("lay_%d", il));
238  Direct[il]->cd();
239  for (unsigned short w = 0; w < cdcgeo.nWiresInLayer(il); ++w) {
240  if (m_flag[il][w] == 1) {
241  m_hTDC[il][w]->Write();
242  }
243  }
244  }
245  top->cd();
246  TDirectory* board = gDirectory->mkdir("board");
247  board->cd();
248  for (int ib = 0; ib < 300; ++ib) {
249  if (m_hTDCBoard[ib]) {
250  m_hTDCBoard[ib]->Write();
251  }
252  }
253  top->cd();
254  m_hT0All->Write();
255 
256  fhist->Close();
257 }
R E
internal precision of FFTW codelets
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
Database object for timing offset (t0).
Definition: CDCTimeZeros.h:26
void setT0(unsigned short iCLayer, unsigned short iWire, float t0)
Set t0 in the list.
Definition: CDCTimeZeros.h:40
The Class for CDC Geometry Parameters.
unsigned short getBoardID(const WireID &wID) const
Returns frontend board id. corresponding to the wire id.
const B2Vector3D wireBackwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
double getTdcBinWidth() const
Return TDC bin width (nsec).
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.
TH1D * m_hT0All
T0 distribution of all channel.
unsigned short m_tdcMax
maximum of TDC hist for fitting
TH1D * m_hTDCBoard[300]
T0 distribution of each board.
float m_initT0
Common initial T0 for fitting.
bool m_flag[56][400]
flag =1 for good, =0 for low statistic or bad fit
void saveHisto()
Save hitograms of the calibration results.
bool m_cosmic
for cosmic case, tof of upper sector will be negative
virtual void createHisto(StoreObjPtr< EventMetaData > &evtPtr)
create histo for each channel
unsigned short m_tdcMin
minimum of TDC hist for fitting
virtual void write(StoreObjPtr< EventMetaData > &evtPtr)
write outut or store db
unsigned short m_minEntries
minimum entries required by histo.
EResult calibrate() override
Run algo on data.
TH1D * m_hTDC[56][400]
TDC distribution histo.
float m_zOffset
z offset for calculate prop time, it is position of trigger counter,
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
static const double speedOfLight
[cm/ns]
Definition: Const.h:686
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
Definition: StoreObjPtr.h:111
Class to identify a wire inside the CDC.
Definition: WireID.h:34
static DBStore & Instance()
Instance of a singleton DBStore.
Definition: DBStore.cc:28
void update()
Updates all objects that are outside their interval of validity.
Definition: DBStore.cc:79
Abstract base class for different kinds of events.