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 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.