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/DBObjPtr.h>
21#include <framework/logging/Logger.h>
22using namespace std;
23using namespace Belle2;
24using namespace CDC;
25
27{
28
30 " -------------------------- T0 Calibration Algorithm -------------------------\n"
31 );
32}
33
35
36{
37
38 B2INFO("CreateHisto");
39
41 const auto exprun = getRunList();
42 B2INFO("Changed ExpRun to: " << exprun[0].first << " " << exprun[0].second);
43 evtPtr->setExperiment(exprun[0].first);
44 evtPtr->setRun(exprun[0].second);
46 B2INFO("create TDChist");
47
48 for (int il = 0; il < 56; ++il) {
49 for (unsigned short w = 0; w < cdcgeo.nWiresInLayer(il); ++w) {
50 m_hTDC[il][w] = new TH1D(Form("hLay%d_ch%d", il, w), "tdc", m_tdcMax - m_tdcMin, m_tdcMin, m_tdcMax);
51 }
52 }
53
54 B2INFO("create TDChist(board)");
55 for (int ib = 0; ib < 300; ++ib) {
56 m_hTDCBoard[ib] = new TH1D(Form("hTDCBoard%d", ib), "", m_tdcMax - m_tdcMin, m_tdcMin, m_tdcMax);
57 }
58 m_hT0All = new TH1D("hT0All", "", 8500, 0, 8500);
59
60 unsigned short lay;
61 unsigned short wire;
62 unsigned short tdc;
63 auto tree = getObjectPtr<TTree>("tree");
64 tree->SetBranchAddress("lay", &lay);
65 tree->SetBranchAddress("wire", &wire);
66 tree->SetBranchAddress("tdc", &tdc);
67
68 const int nEntries = tree->GetEntries();
69 B2INFO("fill hist");
70 for (int i = 0; i < nEntries ; ++i) {
71 tree->GetEntry(i);
72 m_hTDC[lay][wire]->Fill(tdc);
73 m_hTDCBoard[cdcgeo.getBoardID(WireID(lay, wire))]->Fill(tdc);
74 m_hT0All->Fill(tdc);
75 }
76 B2INFO("end of filling hist");
77}
78
80{
81 B2INFO("Start calibration");
82
83 gROOT->SetBatch(1);
84 gErrorIgnoreLevel = 3001;
85
86 // We create an EventMetaData object. But since it's possible we're re-running this algorithm inside a process
87 // that has already created a DataStore, we need to check if it's already valid, or if it needs registering.
89 if (!evtPtr.isValid()) {
90 // Construct an EventMetaData object in the Datastore so that the DB objects in CDCGeometryPar can work
92 B2INFO("Registering EventMetaData object in DataStore");
93 evtPtr.registerInDataStore();
95 B2INFO("Creating EventMetaData object");
96 evtPtr.create();
97 } else {
98 B2INFO("A valid EventMetaData object already exists.");
99 }
100 // Construct a CDCGeometryPar object which will update to the correct DB values when we change the EventMetaData and update
101 // the Database instance
102 DBObjPtr<CDCGeometry> cdcGeometry;
103 CDC::CDCGeometryPar::Instance(&(*cdcGeometry));
104 B2INFO("ExpRun at init : " << evtPtr->getExperiment() << " " << evtPtr->getRun());
105
106 createHisto(evtPtr);
107
108 TH1D* hs = new TH1D("hs", "sigma", 100, 0, 20);
109 std::vector<double> sb;
110 std::vector<double> dsb;
111 std::vector<double> t0b;
112 std::vector<double> dt0b;
113 std::vector<double> b;
114 std::vector<double> db;
115
116 static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
117 TF1* f1 = new TF1("f1", "[0]+[1]*(exp([2]*(x-[3]))/(1+exp(-([4]-x)/[5])))", m_tdcMin, m_tdcMax);
118 f1->SetParLimits(0, 0., 1000.);
119 f1->SetLineColor(kRed);
120 const double tdcBinWidth = cdcgeo.getTdcBinWidth();
121 bool bflag[300] = {false};
122
123 for (int ib = 1; ib < 300; ++ib) {
124 if (m_hTDCBoard[ib]->GetEntries() < m_minEntries) {
125 B2DEBUG(199, "Warning: this board low statistic: " << m_hTDCBoard[ib]->GetEntries());
126 bflag[ib] = false;
127 m_t0b[ib] = m_initT0;
128 continue;
129 }
130 double p3 = m_hTDCBoard[ib]->GetXaxis()->GetBinCenter(m_hTDCBoard[ib]->GetMaximumBin());
131 f1->SetParameters(0, m_hTDCBoard[ib]->GetMaximum(), -0.001, p3, m_initT0, 2.5);
132 m_hTDCBoard[ib]->Fit("f1", "QM", "", m_initT0 - 60, m_initT0 + 60);
133
134 if ((fabs(f1->GetParameter(4) - m_initT0) > 100)
135 || (fabs(f1->GetParameter(5)) < 0.01)
136 || (fabs(f1->GetParameter(5)) > 16)) {
137
138 bflag[ib] = false;
139 m_t0b[ib] = m_initT0;
140 continue;
141 }
142
143 bflag[ib] = true;
144 m_t0b[ib] = f1->GetParameter(4) * tdcBinWidth;
145
146 sb.push_back(f1->GetParameter(5));
147 dsb.push_back(f1->GetParError(5));
148 t0b.push_back(f1->GetParameter(4));
149 dt0b.push_back(f1->GetParError(4));
150 b.push_back(ib);
151 db.push_back(0);
152 }
153
154 for (int il = 0; il < 56; ++il) {
155 for (unsigned short w = 0; w < cdcgeo.nWiresInLayer(il); ++w) {
156 B2DEBUG(99, "fitting for channel: " << il << " - " << w);
157 B2DEBUG(99, "number of entries" << m_hTDC[il][w]->GetEntries());
158 m_t0[il][w] = m_initT0 * tdcBinWidth;
159 int bid = cdcgeo.getBoardID(WireID(il, w));
160 if (m_hTDC[il][w]->GetEntries() < m_minEntries) {
161 B2DEBUG(99, "Warning: low statistic channel: " << m_hTDC[il][w]->GetEntries());
162 if (bflag[bid] != false) {
163 m_t0[il][w] = m_t0b[bid];
164 m_flag[il][w] = true;
165 } else {
166 m_flag[il][w] = false;
167 }
168 } else {
169 double p3 = m_hTDC[il][w]->GetXaxis()->GetBinCenter(m_hTDC[il][w]->GetMaximumBin());
170 f1->SetParameters(0, m_hTDC[il][w]->GetMaximum(), -0.001, p3, m_initT0, 2.5);
171 m_hTDC[il][w]->Fit("f1", "QM", "", m_initT0 - 60, m_initT0 + 60);
172 B2DEBUG(99, "prob of fit : " << f1->GetProb());
173 if ((f1->GetProb() < 1E-150) || (fabs(f1->GetParameter(4) - m_initT0) > 100) || (f1->GetParameter(5) < 0.1)
174 || (f1->GetParameter(5) > 20)) {
175 if (bflag[bid] != 0) {
176 m_t0[il][w] = m_t0b[bid];
177 m_flag[il][w] = true;
178 } else {
179 m_flag[il][w] = false;
180 }
181 } else {
182 m_t0[il][w] = f1->GetParameter(4) * tdcBinWidth;
183 hs->Fill(f1->GetParameter(5));
184 m_flag[il][w] = true;
185 }
186 }
187
188 B2DEBUG(99, "P4 = " << m_t0[il][w]);
189 if (m_cosmic && cdcgeo.wireBackwardPosition(il, w).Y() > 0) {
190 m_t0[il][w] -= cdcgeo.senseWireR(il) / Const::speedOfLight;
191 } else {
192 m_t0[il][w] += cdcgeo.senseWireR(il) / Const::speedOfLight;
193 }
194 m_t0[il][w] += (m_zOffset - cdcgeo.wireBackwardPosition(il, w).Z()) / 27.25;
195 m_t0[il][w] += 6.122;
196 m_hT0All->Fill(m_t0[il][w]);
197 }
198 }
199
200 B2INFO("Write constants");
201 write(evtPtr);
202 saveHisto();
203 return c_OK;
204}
205
207{
208 static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
209 const auto exprun = getRunList();
210 B2INFO("Changed ExpRun to: " << exprun[0].first << " " << exprun[0].second);
211 evtPtr->setExperiment(exprun[0].first);
212 evtPtr->setRun(exprun[0].second);
214
215 CDCTimeZeros* tz = new CDCTimeZeros();
216 for (int ilay = 0; ilay < 56; ++ilay) {
217 for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
218 WireID wireid(ilay, iwire);
219 tz->setT0(wireid, m_t0[ilay][iwire]);
220 }
221 }
222 saveCalibration(tz, "CDCTimeZeros");
223}
224
226{
227 static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
228 TFile* fhist = new TFile("histCrudeT0.root", "recreate");
229 fhist->cd();
230 TDirectory* top = gDirectory;
231 TDirectory* Direct[56];
232 for (int il = 0; il < 56; ++il) {
233 top->cd();
234 Direct[il] = gDirectory->mkdir(Form("lay_%d", il));
235 Direct[il]->cd();
236 for (unsigned short w = 0; w < cdcgeo.nWiresInLayer(il); ++w) {
237 if (m_flag[il][w] == 1) {
238 m_hTDC[il][w]->Write();
239 }
240 }
241 }
242 top->cd();
243 TDirectory* board = gDirectory->mkdir("board");
244 board->cd();
245 for (int ib = 0; ib < 300; ++ib) {
246 if (m_hTDCBoard[ib]) {
247 m_hTDCBoard[ib]->Write();
248 }
249 }
250 top->cd();
251 m_hT0All->Write();
252
253 fhist->Close();
254}
R E
internal precision of FFTW codelets
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition B2Vector3.h:433
Database object for timing offset (t0).
void setT0(unsigned short iCLayer, unsigned short iWire, float t0)
Set t0 in the list.
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 output 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,
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.
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
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:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
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.
Class to identify a wire inside the CDC.
Definition WireID.h:34
std::shared_ptr< T > getObjectPtr(const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
Get calibration data object by name and list of runs, the Merge function will be called to generate t...
static DBStore & Instance()
Instance of a singleton DBStore.
Definition DBStore.cc:26
void update()
Updates all objects that are outside their interval of validity.
Definition DBStore.cc:77
Abstract base class for different kinds of events.
STL namespace.