Belle II Software development
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>
25using namespace std;
26using namespace Belle2;
27using namespace CDC;
28
30{
31
33 " -------------------------- T0 Calibration Algorithm -------------------------\n"
34 );
35}
36
38
39{
40
41 B2INFO("CreateHisto");
42
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)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
static const double speedOfLight
[cm/ns]
Definition: Const.h:695
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.
STL namespace.