Belle II Software development
KLMTimeAlgorithm.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
9/* Own header. */
10#include <klm/calibration/KLMTimeAlgorithm.h>
11
12/* KLM headers. */
13#include <klm/dataobjects/bklm/BKLMElementNumbers.h>
14
15/* Basf2 headers. */
16#include <framework/database/Database.h>
17#include <framework/database/DBObjPtr.h>
18#include <framework/database/DBStore.h>
19#include <framework/dataobjects/EventMetaData.h>
20#include <framework/gearbox/Const.h>
21#include <framework/logging/Logger.h>
22
23/* ROOT headers. */
24#include <Math/MinimizerOptions.h>
25#include <Math/Vector3D.h>
26#include <TFile.h>
27#include <TFitResult.h>
28#include <TMinuit.h>
29#include <TROOT.h>
30#include <TString.h>
31#include <TTree.h>
32
33/* C++ headers. */
34#include <functional> // ADD THIS
35#include <set> // ADD THIS
36
37using namespace Belle2;
38using namespace ROOT::Math;
39
41const int c_NBinsTime = 100;
42
44const int c_NBinsDistance = 100;
45
47static double s_BinnedData[c_NBinsTime][c_NBinsDistance];
48
50static double s_LowerTimeBoundary = 0;
51
53static double s_UpperTimeBoundary = 0;
54
56static double s_StripLength = 0;
57
58static bool compareEventNumber(const std::pair<KLMChannelNumber, unsigned int>& pair1,
59 const std::pair<KLMChannelNumber, unsigned int>& pair2)
60{
61 return pair1.second < pair2.second;
62}
63
64static double timeDensity(const double x[2], const double* par)
65{
66 double polynomial, t0, gauss;
67 polynomial = par[0];
68 t0 = par[2] + par[4] * x[1];
69 gauss = par[1] / (sqrt(2.0 * M_PI) * par[3]) *
70 exp(-0.5 * pow((x[0] - t0) / par[3], 2));
71 return fabs(polynomial + gauss);
72}
73
74static void fcn(int& npar, double* grad, double& fval, double* par, int iflag)
75{
76 (void)npar;
77 (void)grad;
78 (void)iflag;
79 double x[2];
80 fval = 0;
81 for (int i = 0; i < c_NBinsTime; ++i) {
82 x[0] = s_LowerTimeBoundary +
83 (s_UpperTimeBoundary - s_LowerTimeBoundary) *
84 (double(i) + 0.5) / c_NBinsTime;
85 for (int j = 0; j < c_NBinsDistance; ++j) {
86 x[1] = s_StripLength * (double(j) + 0.5) / c_NBinsDistance;
87 double f = timeDensity(x, par);
88 if (s_BinnedData[i][j] == 0)
89 fval = fval + 2.0 * f;
90 else
91 fval = fval + 2.0 * (f - s_BinnedData[i][j] *
92 (1.0 - log(s_BinnedData[i][j] / f)));
93 }
94 }
95}
96
98 CalibrationAlgorithm("KLMTimeCollector")
99{
101 m_minimizerOptions = ROOT::Math::MinimizerOptions();
102}
103
107
109{
110 const std::vector<Calibration::ExpRun>& runs = getRunList();
111 int firstExperiment = runs[0].first;
112 int lastExperiment = runs[runs.size() - 1].first;
113 if (firstExperiment != lastExperiment) {
114 B2FATAL("Runs from different experiments are used "
115 "for KLM time calibration (single algorithm run).");
116 }
117 /* DataStore. */
119 StoreObjPtr<EventMetaData> eventMetaData;
120 eventMetaData.registerInDataStore();
122 /* Database. */
123 if (eventMetaData.isValid()) {
124 if (eventMetaData->getExperiment() != firstExperiment) {
125 B2FATAL("Runs from different experiments are used "
126 "for KLM time calibration (consecutive algorithm runs).");
127 }
128 eventMetaData->setExperiment(firstExperiment);
129 eventMetaData->setRun(runs[0].second);
130 } else {
131 eventMetaData.construct(1, runs[0].second, firstExperiment);
132 }
133 DBStore& dbStore = DBStore::Instance();
134 dbStore.update();
135 dbStore.updateEvent();
136 /*
137 * For calibration algorithms, the database is not initialized on class
138 * creation. Do not move the database object to class members.
139 */
140 DBObjPtr<BKLMGeometryPar> bklmGeometry;
143}
144
145// Version 1: Initial check only (don't load data)
147{
148 B2INFO("Read tree entries (initial data check only).");
149 std::shared_ptr<TTree> timeCalibrationData;
150 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
151
152 int n = timeCalibrationData->GetEntries();
153 B2INFO(LogVar("Total number of digits:", n));
154
155 if (n < m_MinimalDigitNumber)
157
159}
160
161void KLMTimeAlgorithm::readCalibrationDataCounts(std::map<KLMChannelNumber, unsigned int>& eventCounts)
162{
163 B2INFO("Counting events per channel (lightweight scan)...");
164 Event event;
165 std::shared_ptr<TTree> timeCalibrationData;
166 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
167 timeCalibrationData->SetBranchAddress("channelId", &event.channelId);
168
169 eventCounts.clear();
170
171 int n = timeCalibrationData->GetEntries();
172 for (int i = 0; i < n; ++i) {
173 timeCalibrationData->GetEntry(i);
174 eventCounts[event.channelId]++;
175 }
176
177 B2INFO("Event counting complete." << LogVar("Total events", n) << LogVar("Unique channels", eventCounts.size()));
178}
179
181 const std::vector<std::pair<KLMChannelNumber, unsigned int>>& channelsBKLM,
182 const std::vector<std::pair<KLMChannelNumber, unsigned int>>& channelsEKLM)
183{
184 B2INFO("Loading data for 2D fit (top 1000 channels from BKLM and EKLM)...");
185 Event event;
186 std::shared_ptr<TTree> timeCalibrationData;
187 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
188 timeCalibrationData->SetBranchAddress("t0", &event.t0);
189 timeCalibrationData->SetBranchAddress("flyTime", &event.flyTime);
190 timeCalibrationData->SetBranchAddress("recTime", &event.recTime);
191 timeCalibrationData->SetBranchAddress("dist", &event.dist);
192 timeCalibrationData->SetBranchAddress("diffDistX", &event.diffDistX);
193 timeCalibrationData->SetBranchAddress("diffDistY", &event.diffDistY);
194 timeCalibrationData->SetBranchAddress("diffDistZ", &event.diffDistZ);
195 timeCalibrationData->SetBranchAddress("eDep", &event.eDep);
196 timeCalibrationData->SetBranchAddress("nPE", &event.nPE);
197 timeCalibrationData->SetBranchAddress("channelId", &event.channelId);
198 timeCalibrationData->SetBranchAddress("inRPC", &event.inRPC);
199 timeCalibrationData->SetBranchAddress("isFlipped", &event.isFlipped);
200
201 m_evts.clear();
202
203 // Build set of channels we need for 2D fit (top 1000 from each)
204 std::set<KLMChannelNumber> neededChannels;
205 int maxChannels = 1000;
206
207 for (size_t i = 0; i < channelsBKLM.size() && i < static_cast<size_t>(maxChannels); ++i) {
208 neededChannels.insert(channelsBKLM[i].first);
209 }
210 for (size_t i = 0; i < channelsEKLM.size() && i < static_cast<size_t>(maxChannels); ++i) {
211 neededChannels.insert(channelsEKLM[i].first);
212 }
213
214 int n = timeCalibrationData->GetEntries();
215 int loadedEvents = 0;
216
217 for (int i = 0; i < n; ++i) {
218 timeCalibrationData->GetEntry(i);
219
220 if (neededChannels.find(event.channelId) != neededChannels.end()) {
221 m_evts[event.channelId].push_back(event);
222 loadedEvents++;
223 }
224 }
225
226 B2INFO("2D fit data loaded." << LogVar("Events", loadedEvents) << LogVar("Channels", m_evts.size()));
227}
228
229void KLMTimeAlgorithm::readCalibrationDataBatch(std::function<bool(const KLMChannelIndex&)> channelFilter)
230{
231 B2INFO("Loading calibration data batch...");
232 Event event;
233 std::shared_ptr<TTree> timeCalibrationData;
234 timeCalibrationData = getObjectPtr<TTree>("time_calibration_data");
235 timeCalibrationData->SetBranchAddress("t0", &event.t0);
236 timeCalibrationData->SetBranchAddress("flyTime", &event.flyTime);
237 timeCalibrationData->SetBranchAddress("recTime", &event.recTime);
238 timeCalibrationData->SetBranchAddress("dist", &event.dist);
239 timeCalibrationData->SetBranchAddress("diffDistX", &event.diffDistX);
240 timeCalibrationData->SetBranchAddress("diffDistY", &event.diffDistY);
241 timeCalibrationData->SetBranchAddress("diffDistZ", &event.diffDistZ);
242 timeCalibrationData->SetBranchAddress("eDep", &event.eDep);
243 timeCalibrationData->SetBranchAddress("nPE", &event.nPE);
244 timeCalibrationData->SetBranchAddress("channelId", &event.channelId);
245 timeCalibrationData->SetBranchAddress("inRPC", &event.inRPC);
246 timeCalibrationData->SetBranchAddress("isFlipped", &event.isFlipped);
247
248 m_evts.clear();
249
250 int n = timeCalibrationData->GetEntries();
251 int loadedEvents = 0;
252
253 for (int i = 0; i < n; ++i) {
254 timeCalibrationData->GetEntry(i);
255
256 // Convert channel number to KLMChannelIndex using channelNumberToElementNumbers
257 int subdetector, section, sector, layer, plane, strip;
258 m_ElementNumbers->channelNumberToElementNumbers(
259 event.channelId, &subdetector, &section, &sector, &layer, &plane, &strip);
260 KLMChannelIndex klmChannel(subdetector, section, sector, layer, plane, strip);
261
262 if (channelFilter(klmChannel)) {
263 m_evts[event.channelId].push_back(event);
264 loadedEvents++;
265 }
266 }
267
268 B2INFO("Batch loaded." << LogVar("Events", loadedEvents) << LogVar("Channels", m_evts.size()));
269}
270
272{
273 if (m_mc) {
280 } else {
281 m_LowerTimeBoundaryRPC = -800.0;
282 m_UpperTimeBoundaryRPC = -600.0;
287
288 }
289 int nBin = 80;
290 int nBin_scint = 80;
291
292 TString iFstring[2] = {"Backward", "Forward"};
293 TString iPstring[2] = {"ZReadout", "PhiReadout"};
294 TString hn, ht;
295
296 h_diff = new TH1F("h_diff", "Position difference between bklmHit2d and extHit;position difference", 100, 0, 10);
297 h_calibrated = new TH1I("h_calibrated_summary", "h_calibrated_summary;calibrated or not", 3, 0, 3);
298 hc_calibrated = new TH1I("hc_calibrated_summary", "hc_calibrated_summary;calibrated or not", 3, 0, 3);
299
300 gre_time_channel_scint = new TGraphErrors();
301 gre_time_channel_rpc = new TGraphErrors();
302 gre_time_channel_scint_end = new TGraphErrors();
303
304 gr_timeShift_channel_scint = new TGraph();
305 gr_timeShift_channel_rpc = new TGraph();
306 gr_timeShift_channel_scint_end = new TGraph();
307
308 gre_ctime_channel_scint = new TGraphErrors();
309 gre_ctime_channel_rpc = new TGraphErrors();
310 gre_ctime_channel_scint_end = new TGraphErrors();
311
312 gr_timeRes_channel_scint = new TGraph();
313 gr_timeRes_channel_rpc = new TGraph();
314 gr_timeRes_channel_scint_end = new TGraph();
315
316 double maximalPhiStripLengthBKLM =
317 m_BKLMGeometry->getMaximalPhiStripLength();
318 double maximalZStripLengthBKLM =
319 m_BKLMGeometry->getMaximalZStripLength();
320 double maximalStripLengthEKLM =
321 m_EKLMGeometry->getMaximalStripLength() / CLHEP::cm * Unit::cm;
322
323 m_ProfileRpcPhi = new TProfile("hprf_rpc_phi_effC",
324 "Time over propagation length for RPCs (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
325 400.0);
326 m_ProfileRpcZ = new TProfile("hprf_rpc_z_effC",
327 "Time over propagation length for RPCs (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
328 400.0);
329 m_ProfileBKLMScintillatorPhi = new TProfile("hprf_scint_phi_effC",
330 "Time over propagation length for scintillators (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
331 50, 0.0, maximalPhiStripLengthBKLM);
332 m_ProfileBKLMScintillatorZ = new TProfile("hprf_scint_z_effC",
333 "Time over propagation length for scintillators (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
334 50, 0.0, maximalZStripLengthBKLM);
335 m_ProfileEKLMScintillatorPlane1 = new TProfile("hprf_scint_plane1_effC_end",
336 "Time over propagation length for scintillators (plane1, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
337 50, 0.0, maximalStripLengthEKLM);
338 m_ProfileEKLMScintillatorPlane2 = new TProfile("hprf_scint_plane2_effC_end",
339 "Time over propagation length for scintillators (plane2, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
340 50, 0.0, maximalStripLengthEKLM);
341
342 m_Profile2RpcPhi = new TProfile("hprf2_rpc_phi_effC",
343 "Time over propagation length for RPCs (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
344 400.0);
345 m_Profile2RpcZ = new TProfile("hprf2_rpc_z_effC",
346 "Time over propagation length for RPCs (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
347 400.0);
348 m_Profile2BKLMScintillatorPhi = new TProfile("hprf2_scint_phi_effC",
349 "Time over propagation length for scintillators (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
350 50, 0.0, maximalPhiStripLengthBKLM);
351 m_Profile2BKLMScintillatorZ = new TProfile("hprf2_scint_z_effC",
352 "Time over propagation length for scintillators (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
353 50, 0.0, maximalZStripLengthBKLM);
354 m_Profile2EKLMScintillatorPlane1 = new TProfile("hprf2_scint_plane1_effC_end",
355 "Time over propagation length for scintillators (plane1, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
356 50, 0.0, maximalStripLengthEKLM);
357 m_Profile2EKLMScintillatorPlane2 = new TProfile("hprf2_scint_plane2_effC_end",
358 "Time over propagation length for scintillators (plane2, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
359 50, 0.0, maximalStripLengthEKLM);
360
361 h_time_rpc_tc = new TH1F("h_time_rpc_tc", "time distribution for RPC", nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
362 h_time_scint_tc = new TH1F("h_time_scint_tc", "time distribution for Scintillator", nBin_scint,
364 h_time_scint_tc_end = new TH1F("h_time_scint_tc_end", "time distribution for Scintillator (Endcap)", nBin_scint,
367
369 h_time_rpc = new TH1F("h_time_rpc", "time distribution for RPC; T_rec-T_0-T_fly-T_propagation[ns]", nBin, m_LowerTimeBoundaryRPC,
371 h_time_scint = new TH1F("h_time_scint", "time distribution for Scintillator; T_rec-T_0-T_fly-T_propagation[ns]", nBin_scint,
373 h_time_scint_end = new TH1F("h_time_scint_end", "time distribution for Scintillator (Endcap); T_rec-T_0-T_fly-T_propagation[ns]",
375
376 hc_time_rpc = new TH1F("hc_time_rpc", "Calibrated time distribution for RPC; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
378 hc_time_scint = new TH1F("hc_time_scint",
379 "Calibrated time distribution for Scintillator; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", nBin_scint,
382 hc_time_scint_end = new TH1F("hc_time_scint_end",
383 "Calibrated time distribution for Scintillator (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", nBin_scint,
385
386 if (!m_saveAllPlots) {
387 B2INFO("Skipping debug histogram allocation (m_saveAllPlots = false)");
388 return; // Skip all debugging histogram allocation
389 }
390
391 for (int iF = 0; iF < 2; ++iF) {
392 hn = Form("h_timeF%d_rpc", iF);
393 ht = Form("Time distribution for RPC of %s; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
394 h_timeF_rpc[iF] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
395 hn = Form("h_timeF%d_scint", iF);
396 ht = Form("Time distribution for Scintillator of %s; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
397 h_timeF_scint[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
399 hn = Form("h_timeF%d_scint_end", iF);
400 ht = Form("Time distribution for Scintillator of %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
401 h_timeF_scint_end[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
403
404 hn = Form("h2_timeF%d_rpc", iF);
405 ht = Form("Time distribution for RPC of %s; Sector Index; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
406 h2_timeF_rpc[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
407 hn = Form("h2_timeF%d_scint", iF);
408 ht = Form("Time distribution for Scintillator of %s; Sector Index; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
409 h2_timeF_scint[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
411 hn = Form("h2_timeF%d_scint_end", iF);
412 ht = Form("Time distribution for Scintillator of %s (Endcap); Sector Index; T_rec-T_0-T_fly-T_propagation[ns]",
413 iFstring[iF].Data());
414 h2_timeF_scint_end[iF] = new TH2F(hn.Data(), ht.Data(), 4, 0, 4, nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
416
417 hn = Form("hc_timeF%d_rpc", iF);
418 ht = Form("Calibrated time distribution for RPC of %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iFstring[iF].Data());
419 hc_timeF_rpc[iF] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC, m_UpperTimeBoundaryCalibratedRPC);
420 hn = Form("hc_timeF%d_scint", iF);
421 ht = Form("Calibrated time distribution for Scintillator of %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
422 iFstring[iF].Data());
423 hc_timeF_scint[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
425 hn = Form("hc_timeF%d_scint_end", iF);
426 ht = Form("Calibrated time distribution for Scintillator of %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
427 iFstring[iF].Data());
428 hc_timeF_scint_end[iF] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
430
431 hn = Form("h2c_timeF%d_rpc", iF);
432 ht = Form("Calibrated time distribution for RPC of %s; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
433 iFstring[iF].Data());
434 h2c_timeF_rpc[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin, m_LowerTimeBoundaryCalibratedRPC,
436 hn = Form("h2c_timeF%d_scint", iF);
437 ht = Form("Calibrated time distribution for Scintillator of %s; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
438 iFstring[iF].Data());
439 h2c_timeF_scint[iF] = new TH2F(hn.Data(), ht.Data(), 8, 0, 8, nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
441 hn = Form("h2c_timeF%d_scint_end", iF);
442 ht = Form("Calibrated time distribution for Scintillator of %s (Endcap) ; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
443 iFstring[iF].Data());
444 h2c_timeF_scint_end[iF] = new TH2F(hn.Data(), ht.Data(), 4, 0, 4, nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
446
447 for (int iS = 0; iS < 8; ++iS) {
448 // Barrel parts
449 hn = Form("h_timeF%d_S%d_scint", iF, iS);
450 ht = Form("Time distribution for Scintillator of Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
451 h_timeFS_scint[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
453 hn = Form("h_timeF%d_S%d_rpc", iF, iS);
454 ht = Form("Time distribution for RPC of Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
455 h_timeFS_rpc[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
456 hn = Form("h2_timeF%d_S%d", iF, iS);
457 ht = Form("Time distribution of Sector%d, %s; Layer Index; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
458 h2_timeFS[iF][iS] = new TH2F(hn.Data(), ht.Data(), 15, 0, 15, nBin_scint, m_LowerTimeBoundaryRPC,
460
461 hn = Form("hc_timeF%d_S%d_scint", iF, iS);
462 ht = Form("Calibrated time distribution for Scintillator of Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
463 iFstring[iF].Data());
464 hc_timeFS_scint[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
466 hn = Form("hc_timeF%d_S%d_rpc", iF, iS);
467 ht = Form("Calibrated time distribution for RPC of Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
468 iFstring[iF].Data());
469 hc_timeFS_rpc[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedRPC,
471 hn = Form("h2c_timeF%d_S%d", iF, iS);
472 ht = Form("Calibrated time distribution of Sector%d, %s; Layer Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
473 iFstring[iF].Data());
474 h2c_timeFS[iF][iS] = new TH2F(hn.Data(), ht.Data(), 15, 0, 15, nBin_scint, m_LowerTimeBoundaryCalibratedRPC,
476
477 // Inner 2 layers --> Scintillators
478 for (int iL = 0; iL < 2; ++iL) {
479 hn = Form("h_timeF%d_S%d_L%d", iF, iS, iL);
480 ht = Form("Time distribution for Scintillator of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iL, iS,
481 iFstring[iF].Data());
482 h_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
484 hn = Form("hc_timeF%d_S%d_L%d", iF, iS, iL);
485 ht = Form("Calibrated time distribution for Scintillator of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
486 iL, iS, iFstring[iF].Data());
487 hc_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
489
490 for (int iP = 0; iP < 2; ++iP) {
491 hn = Form("h_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
492 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]",
493 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
494 h_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
496 hn = Form("h2_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
497 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
498 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
499 h2_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 54, 0, 54, nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
501
502 hn = Form("hc_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
503 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
504 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
505 hc_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
507 hn = Form("h2c_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
508 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
509 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
510 h2c_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 54, 0, 54, nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
512 }
513 }
514
515 for (int iL = 2; iL < 15; ++iL) {
516 hn = Form("h_timeF%d_S%d_L%d", iF, iS, iL);
517 ht = Form("time distribution for RPC of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iL, iS, iFstring[iF].Data());
518 h_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
519
520 hn = Form("hc_timeF%d_S%d_L%d", iF, iS, iL);
521 ht = Form("Calibrated time distribution for RPC of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iL, iS,
522 iFstring[iF].Data());
523 hc_timeFSL[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC, m_UpperTimeBoundaryCalibratedRPC);
524
525 for (int iP = 0; iP < 2; ++iP) {
526 hn = Form("h_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
527 ht = Form("time distribution for RPC of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iPstring[iP].Data(), iL, iS,
528 iFstring[iF].Data());
529 h_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
530
531 hn = Form("h2_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
532 ht = Form("time distribution for RPC of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
533 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
534 h2_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 48, 0, 48, nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
535
536 hn = Form("hc_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
537 ht = Form("Calibrated time distribution for RPC of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
538 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
539 hc_timeFSLP[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC,
541
542 hn = Form("h2c_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
543 ht = Form("Calibrated time distribution for RPC of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
544 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
545 h2c_timeFSLP[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 48, 0, 48, nBin, m_LowerTimeBoundaryCalibratedRPC,
547 }
548 }
549 }
550 // Endcap part
551 int maxLay = 12 + 2 * iF;
552 for (int iS = 0; iS < 4; ++iS) {
553 hn = Form("h_timeF%d_S%d_scint_end", iF, iS);
554 ht = Form("Time distribution for Scintillator of Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iS,
555 iFstring[iF].Data());
556 h_timeFS_scint_end[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
558 hn = Form("h2_timeF%d_S%d_end", iF, iS);
559 ht = Form("Time distribution of Sector%d, %s (Endcap); Layer Index; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
560 h2_timeFS_end[iF][iS] = new TH2F(hn.Data(), ht.Data(), maxLay, 0, maxLay, nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
562 hn = Form("hc_timeF%d_S%d_scint_end", iF, iS);
563 ht = Form("Calibrated time distribution for Scintillator of Sector%d (Endcap), %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
564 iS, iFstring[iF].Data());
565 hc_timeFS_scint_end[iF][iS] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
567 hn = Form("h2c_timeF%d_S%d_end", iF, iS);
568 ht = Form("Calibrated time distribution of Sector%d, %s (Endcap); Layer Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
569 iS, iFstring[iF].Data());
570 h2c_timeFS_end[iF][iS] = new TH2F(hn.Data(), ht.Data(), maxLay, 0, maxLay, nBin_scint,
573
574 for (int iL = 0; iL < maxLay; ++iL) {
575 hn = Form("h_timeF%d_S%d_L%d_end", iF, iS, iL);
576 ht = Form("Time distribution for Scintillator of Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iL, iS,
577 iFstring[iF].Data());
578 h_timeFSL_end[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
580 hn = Form("hc_timeF%d_S%d_L%d_end", iF, iS, iL);
581 ht = Form("Calibrated time distribution for Scintillator of Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
582 iL, iS, iFstring[iF].Data());
583 hc_timeFSL_end[iF][iS][iL] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
585
586 for (int iP = 0; iP < 2; ++iP) {
587 hn = Form("h_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
588 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]",
589 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
590 h_timeFSLP_end[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
592
593 hn = Form("h2_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
594 ht = Form("Time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
595 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
596 h2_timeFSLP_end[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 75, 0, 75, nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
598
599 hn = Form("hc_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
600 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
601 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
602 hc_timeFSLP_end[iF][iS][iL][iP] = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
604
605 hn = Form("h2c_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
606 ht = Form("Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
607 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
608 h2c_timeFSLP_end[iF][iS][iL][iP] = new TH2F(hn.Data(), ht.Data(), 75, 0, 75, nBin_scint,
611 }
612 }
613 }
614 }
615}
616
618 TProfile* profileRpcPhi, TProfile* profileRpcZ,
619 TProfile* profileBKLMScintillatorPhi, TProfile* profileBKLMScintillatorZ,
620 TProfile* profileEKLMScintillatorPlane1,
621 TProfile* profileEKLMScintillatorPlane2, bool fill2dHistograms)
622{
623 B2INFO("Filling time-distance profiles" << (fill2dHistograms ? " with 2D histograms" : "") << " (batched processing)...");
624
625 TString iFstring[2] = {"Backward", "Forward"};
626 TString iPstring[2] = {"ZReadout", "PhiReadout"};
627
628 // Define the 6 batches (same as in calibrate())
629 auto isRPCBackward = [](const KLMChannelIndex & ch) {
630 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
631 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
632 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
633 };
634
635 auto isRPCForward = [](const KLMChannelIndex & ch) {
636 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
637 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
638 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
639 };
640
641 auto isBKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
642 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
643 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
644 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
645 };
646
647 auto isBKLMScintillatorForward = [](const KLMChannelIndex & ch) {
648 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
649 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
650 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
651 };
652
653 auto isEKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
654 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
655 ch.getSection() == EKLMElementNumbers::c_BackwardSection;
656 };
657
658 auto isEKLMScintillatorForward = [](const KLMChannelIndex & ch) {
659 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
660 ch.getSection() == EKLMElementNumbers::c_ForwardSection;
661 };
662
663 std::vector<std::pair<std::string, std::function<bool(const KLMChannelIndex&)>>> batches = {
664 {"RPC Backward", isRPCBackward},
665 {"RPC Forward", isRPCForward},
666 {"BKLM Scintillator Backward", isBKLMScintillatorBackward},
667 {"BKLM Scintillator Forward", isBKLMScintillatorForward},
668 {"EKLM Scintillator Backward", isEKLMScintillatorBackward},
669 {"EKLM Scintillator Forward", isEKLMScintillatorForward}
670 };
671
672 // Process each batch
673 for (const auto& batch : batches) {
674 B2INFO("Processing batch for profiles: " << batch.first);
675 readCalibrationDataBatch(batch.second);
676
677 // Temporary storage for per-channel 2D histograms (only if fill2dHistograms is true)
678 std::map<KLMChannelNumber, TH2F*> tempHistBKLM;
679 std::map<KLMChannelNumber, TH2F*> tempHistEKLM;
680
681 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
682 KLMChannelNumber channel = klmChannel.getKLMChannelNumber();
683
684 // Skip if not in current batch
685 if (!batch.second(klmChannel))
686 continue;
687
688 if (m_cFlag[channel] == ChannelCalibrationStatus::c_NotEnoughData)
689 continue;
690
691 if (m_evts.find(channel) == m_evts.end())
692 continue;
693
694 std::vector<struct Event> eventsChannel = m_evts[channel];
695 int iSub = klmChannel.getSubdetector();
696
697 // Create 2D histogram for this channel if needed
698 TH2F* hist2d = nullptr;
699 if (fill2dHistograms) {
700 if (iSub == KLMElementNumbers::c_BKLM) {
701 int iF = klmChannel.getSection();
702 int iS = klmChannel.getSector() - 1;
703 int iL = klmChannel.getLayer() - 1;
704 int iP = klmChannel.getPlane();
705 int iC = klmChannel.getStrip() - 1;
706
707 // Only create for scintillators (layers 0-1)
708 if (iL < 2) {
709 TString hn = Form("time_length_bklm_F%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
710 double stripLength = 200;
711 hist2d = new TH2F(hn.Data(),
712 "Time versus propagation length; "
713 "propagation distance[cm]; "
714 "T_rec-T_0-T_fly-'T_calibration'[ns]",
715 50, 0.0, stripLength,
718 tempHistBKLM[channel] = hist2d;
719 }
720 } else { // EKLM
721 int iF = klmChannel.getSection() - 1;
722 int iS = klmChannel.getSector() - 1;
723 int iL = klmChannel.getLayer() - 1;
724 int iP = klmChannel.getPlane() - 1;
725 int iC = klmChannel.getStrip() - 1;
726
727 TString hn = Form("time_length_eklm_F%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
728 double stripLength = m_EKLMGeometry->getStripLength(iC + 1) / CLHEP::cm * Unit::cm;
729 hist2d = new TH2F(hn.Data(),
730 "Time versus propagation length; "
731 "propagation distance[cm]; "
732 "T_rec-T_0-T_fly-'T_calibration'[ns]",
733 50, 0.0, stripLength,
736 tempHistEKLM[channel] = hist2d;
737 }
738 }
739
740 // Fill histograms
741 for (const Event& event : eventsChannel) {
742 double timeHit = event.time() - m_timeShift[channel];
743 if (m_useEventT0)
744 timeHit = timeHit - event.t0;
745 double distHit = event.dist;
746
747 if (timeHit <= -400e3)
748 continue;
749
750 if (iSub == KLMElementNumbers::c_BKLM) {
751 int iL = klmChannel.getLayer() - 1;
752 int iP = klmChannel.getPlane();
753
754 if (iL > 1) {
755 // RPC
756 if (iP) {
757 profileRpcPhi->Fill(distHit, timeHit);
758 } else {
759 profileRpcZ->Fill(distHit, timeHit);
760 }
761 } else {
762 // Scintillator
763 if (hist2d)
764 hist2d->Fill(distHit, timeHit);
765
766 if (iP) {
767 profileBKLMScintillatorPhi->Fill(distHit, timeHit);
768 } else {
769 profileBKLMScintillatorZ->Fill(distHit, timeHit);
770 }
771 }
772 } else { // EKLM
773 int iP = klmChannel.getPlane() - 1;
774
775 if (hist2d)
776 hist2d->Fill(distHit, timeHit);
777
778 if (iP) {
779 profileEKLMScintillatorPlane1->Fill(distHit, timeHit);
780 } else {
781 profileEKLMScintillatorPlane2->Fill(distHit, timeHit);
782 }
783 }
784 }
785 }
786
787 // Write and delete 2D histograms for this batch
788 if (fill2dHistograms) {
789 for (auto& pair : tempHistBKLM) {
791 }
792 for (auto& pair : tempHistEKLM) {
794 }
795 }
796
797 m_evts.clear();
798 B2INFO("Batch processed and cleared: " << batch.first);
799 }
800
801 B2INFO("Time-distance profile filling complete.");
802}
803
805 const std::vector< std::pair<KLMChannelNumber, unsigned int> >& channels,
806 double& delay, double& delayError)
807{
808 std::vector<struct Event> eventsChannel;
809 int nFits = 1000;
810 int nConvergedFits = 0;
811 delay = 0;
812 delayError = 0;
813 if (nFits > (int)channels.size())
814 nFits = channels.size();
815 for (int i = 0; i < nFits; ++i) {
816 int subdetector, section, sector, layer, plane, strip;
817 m_ElementNumbers->channelNumberToElementNumbers(
818 channels[i].first, &subdetector, &section, &sector, &layer, &plane,
819 &strip);
820 if (subdetector == KLMElementNumbers::c_BKLM) {
821 s_LowerTimeBoundary = m_LowerTimeBoundaryScintillatorsBKLM;
822 s_UpperTimeBoundary = m_UpperTimeBoundaryScintillatorsBKLM;
823 const bklm::Module* module =
824 m_BKLMGeometry->findModule(section, sector, layer);
825 s_StripLength = module->getStripLength(plane, strip);
826 } else {
827 s_LowerTimeBoundary = m_LowerTimeBoundaryScintillatorsEKLM;
828 s_UpperTimeBoundary = m_UpperTimeBoundaryScintillatorsEKLM;
829 s_StripLength = m_EKLMGeometry->getStripLength(strip) /
830 CLHEP::cm * Unit::cm;
831 }
832 for (int j = 0; j < c_NBinsTime; ++j) {
833 for (int k = 0; k < c_NBinsDistance; ++k)
834 s_BinnedData[j][k] = 0;
835 }
836 eventsChannel = m_evts[channels[i].first];
837 double averageTime = 0;
838 for (const Event& event : eventsChannel) {
839 double timeHit = event.time();
840 if (m_useEventT0)
841 timeHit = timeHit - event.t0;
842
843 if (timeHit <= -400e3) {
844 continue;
845 }
846
847 averageTime = averageTime + timeHit;
848 int timeBin = std::floor((timeHit - s_LowerTimeBoundary) * c_NBinsTime /
849 (s_UpperTimeBoundary - s_LowerTimeBoundary));
850 if (timeBin < 0 || timeBin >= c_NBinsTime)
851 continue;
852 int distanceBin = std::floor(event.dist * c_NBinsDistance / s_StripLength);
853 if (distanceBin < 0 || distanceBin >= c_NBinsDistance) {
854 B2ERROR("The distance to SiPM is greater than the strip length.");
855 continue;
856 }
857 s_BinnedData[timeBin][distanceBin] += 1;
858 }
859 averageTime = averageTime / eventsChannel.size();
860 TMinuit minuit(5);
861 minuit.SetPrintLevel(-1);
862 int minuitResult;
863 minuit.mnparm(0, "P0", 1, 0.001, 0, 0, minuitResult);
864 minuit.mnparm(1, "N", 10, 0.001, 0, 0, minuitResult);
865 minuit.mnparm(2, "T0", averageTime, 0.001, 0, 0, minuitResult);
866 minuit.mnparm(3, "SIGMA", 10, 0.001, 0, 0, minuitResult);
867 minuit.mnparm(4, "DELAY", 0.0, 0.001, 0, 0, minuitResult);
868 minuit.SetFCN(fcn);
869 minuit.mncomd("FIX 2 3 4 5", minuitResult);
870 minuit.mncomd("MIGRAD 10000", minuitResult);
871 minuit.mncomd("RELEASE 2", minuitResult);
872 minuit.mncomd("MIGRAD 10000", minuitResult);
873 minuit.mncomd("RELEASE 3", minuitResult);
874 minuit.mncomd("MIGRAD 10000", minuitResult);
875 minuit.mncomd("RELEASE 4", minuitResult);
876 minuit.mncomd("MIGRAD 10000", minuitResult);
877 minuit.mncomd("RELEASE 5", minuitResult);
878 minuit.mncomd("MIGRAD 10000", minuitResult);
879 /* Require converged fit with accurate error matrix. */
880 if (minuit.fISW[1] != 3)
881 continue;
882 nConvergedFits++;
883 double channelDelay, channelDelayError;
884 minuit.GetParameter(4, channelDelay, channelDelayError);
885 delay = delay + channelDelay;
886 delayError = delayError + channelDelayError * channelDelayError;
887 }
888 delay = delay / nConvergedFits;
889 delayError = sqrt(delayError) / (nConvergedFits - 1);
890}
891
893{
894 if (h == nullptr)
895 return;
896 if (write && m_outFile) {
897 h->Write();
898 }
899 delete h;
900}
901
903{
904 if (h == nullptr)
905 return;
906 if (write && m_outFile) {
907 h->Write();
908 }
909 delete h;
910}
911
913{
914 int channelId;
915 gROOT->SetBatch(kTRUE);
920
921 fcn_gaus = new TF1("fcn_gaus", "gaus");
922 fcn_land = new TF1("fcn_land", "landau");
923 fcn_pol1 = new TF1("fcn_pol1", "pol1");
924 fcn_const = new TF1("fcn_const", "pol0");
925
926 // Initial validation only - DON'T load all data yet
928 if (result != CalibrationAlgorithm::c_OK)
929 return result;
930
931 /* Choose non-existing file name. */
932 std::string name = "time_calibration.root";
933 int i = 1;
934 while (1) {
935 struct stat buffer;
936 if (stat(name.c_str(), &buffer) != 0)
937 break;
938 name = "time_calibration_" + std::to_string(i) + ".root";
939 i = i + 1;
940 if (i < 0)
941 break;
942 }
943 m_outFile = new TFile(name.c_str(), "recreate");
945
946 std::vector<struct Event> eventsChannel;
947 eventsChannel.clear();
948 m_cFlag.clear();
949 m_minimizerOptions.SetDefaultStrategy(2);
950
951 // ===================================================================
952 // COUNT EVENTS PER CHANNEL (lightweight scan, no full data load)
953 // ===================================================================
954 B2INFO("Counting events per channel...");
955 std::map<KLMChannelNumber, unsigned int> eventCounts;
956 readCalibrationDataCounts(eventCounts);
957
958 /* Sort channels by number of events and initialize flags. */
959 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsBKLM;
960 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsEKLM;
961 KLMChannelIndex klmChannels;
962
963 for (KLMChannelIndex& klmChannel : klmChannels) {
964 KLMChannelNumber channel = klmChannel.getKLMChannelNumber();
965 m_cFlag[channel] = ChannelCalibrationStatus::c_NotEnoughData;
966
967 if (eventCounts.find(channel) == eventCounts.end())
968 continue;
969
970 int nEvents = eventCounts[channel];
971 if (nEvents < m_lower_limit_counts) {
972 B2WARNING("Not enough calibration data collected."
973 << LogVar("channel", channel)
974 << LogVar("number of digit", nEvents));
975 continue;
976 }
977
978 m_cFlag[channel] = ChannelCalibrationStatus::c_FailedFit;
979
980 if (klmChannel.getSubdetector() == KLMElementNumbers::c_BKLM &&
981 klmChannel.getLayer() < BKLMElementNumbers::c_FirstRPCLayer) {
982 channelsBKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
983 }
984 if (klmChannel.getSubdetector() == KLMElementNumbers::c_EKLM) {
985 channelsEKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
986 }
987 }
988
989 std::sort(channelsBKLM.begin(), channelsBKLM.end(), compareEventNumber);
990 std::sort(channelsEKLM.begin(), channelsEKLM.end(), compareEventNumber);
991
992 // ===================================================================
993 // TWO-DIMENSIONAL FIT (needs data for top channels only)
994 // ===================================================================
995 double delayBKLM, delayBKLMError;
996 double delayEKLM, delayEKLMError;
997
998 // Load data for 2D fit channels only
999 readCalibrationDataFor2DFit(channelsBKLM, channelsEKLM);
1000 timeDistance2dFit(channelsBKLM, delayBKLM, delayBKLMError);
1001 timeDistance2dFit(channelsEKLM, delayEKLM, delayEKLMError);
1002 m_evts.clear(); // Clear after 2D fit
1003
1004 B2INFO("2D fits complete, data cleared.");
1005
1006 // ===================================================================
1007 // DEFINE 6 PROCESSING BATCHES
1008 // ===================================================================
1009 auto isRPCBackward = [](const KLMChannelIndex & ch) {
1010 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1011 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
1012 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
1013 };
1014
1015 auto isRPCForward = [](const KLMChannelIndex & ch) {
1016 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1017 ch.getLayer() >= BKLMElementNumbers::c_FirstRPCLayer &&
1018 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
1019 };
1020
1021 auto isBKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1022 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1023 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
1024 ch.getSection() == BKLMElementNumbers::c_BackwardSection;
1025 };
1026
1027 auto isBKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1028 return ch.getSubdetector() == KLMElementNumbers::c_BKLM &&
1029 ch.getLayer() < BKLMElementNumbers::c_FirstRPCLayer &&
1030 ch.getSection() == BKLMElementNumbers::c_ForwardSection;
1031 };
1032
1033 auto isEKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1034 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
1035 ch.getSection() == EKLMElementNumbers::c_BackwardSection;
1036 };
1037
1038 auto isEKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1039 return ch.getSubdetector() == KLMElementNumbers::c_EKLM &&
1040 ch.getSection() == EKLMElementNumbers::c_ForwardSection;
1041 };
1042
1043 std::vector<std::pair<std::string, std::function<bool(const KLMChannelIndex&)>>> batches = {
1044 {"RPC Backward", isRPCBackward},
1045 {"RPC Forward", isRPCForward},
1046 {"BKLM Scintillator Backward", isBKLMScintillatorBackward},
1047 {"BKLM Scintillator Forward", isBKLMScintillatorForward},
1048 {"EKLM Scintillator Backward", isEKLMScintillatorBackward},
1049 {"EKLM Scintillator Forward", isEKLMScintillatorForward}
1050 };
1051
1052 /**********************************
1053 * FIRST LOOP (BATCHED)
1054 * Fill global histograms to compute global means
1055 **********************************/
1056 B2INFO("First loop: Computing global statistics (batched processing)...");
1057
1058 TString iFstring[2] = {"Backward", "Forward"};
1059 TString iPstring[2] = {"ZReadout", "PhiReadout"};
1060 int nBin = 80;
1061 int nBin_scint = 80;
1062
1063 for (const auto& batch : batches) {
1064 B2INFO("Processing batch for global stats: " << batch.first);
1065 readCalibrationDataBatch(batch.second);
1066
1067 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1068 channelId = klmChannel.getKLMChannelNumber();
1069
1070 if (!batch.second(klmChannel))
1071 continue;
1072
1073 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1074 continue;
1075
1076 if (m_evts.find(channelId) == m_evts.end())
1077 continue;
1078
1079 eventsChannel = m_evts[channelId];
1080 int iSub = klmChannel.getSubdetector();
1081 int iL = (iSub == KLMElementNumbers::c_BKLM) ? klmChannel.getLayer() - 1 : -1;
1082
1083 // Fill global histograms only
1084 for (const Event& event : eventsChannel) {
1085 XYZVector diffD = XYZVector(event.diffDistX, event.diffDistY, event.diffDistZ);
1086 h_diff->Fill(diffD.R());
1087
1088 double timeHit = event.time();
1089 if (m_useEventT0)
1090 timeHit = timeHit - event.t0;
1091
1092 if (timeHit <= -400e3)
1093 continue;
1094
1095 if (iSub == KLMElementNumbers::c_BKLM) {
1096 if (iL > 1) {
1097 h_time_rpc_tc->Fill(timeHit);
1098 } else {
1099 h_time_scint_tc->Fill(timeHit);
1100 }
1101 } else {
1102 h_time_scint_tc_end->Fill(timeHit);
1103 }
1104 }
1105 }
1106
1107 m_evts.clear();
1108 B2INFO("Batch processed and cleared: " << batch.first);
1109 }
1110
1111 // Compute global means
1112 m_timeShift.clear();
1113 double tmpMean_rpc_global = h_time_rpc_tc->GetMean();
1114 double tmpMean_scint_global = h_time_scint_tc->GetMean();
1115 double tmpMean_scint_global_end = h_time_scint_tc_end->GetMean();
1116
1117 B2INFO("Global Mean for Raw." << LogVar("RPC", tmpMean_rpc_global)
1118 << LogVar("Scint BKLM", tmpMean_scint_global)
1119 << LogVar("Scint EKLM", tmpMean_scint_global_end));
1120
1121 /**********************************
1122 * SECOND PASS (BATCHED)
1123 * Compute per-channel time shifts
1124 **********************************/
1125 B2INFO("Second pass: Computing per-channel time shifts (batched processing)...");
1126
1127 for (const auto& batch : batches) {
1128 B2INFO("Processing batch for time shifts: " << batch.first);
1129 readCalibrationDataBatch(batch.second);
1130
1131 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1132 channelId = klmChannel.getKLMChannelNumber();
1133
1134 if (!batch.second(klmChannel))
1135 continue;
1136
1137 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1138 continue;
1139
1140 if (m_evts.find(channelId) == m_evts.end())
1141 continue;
1142
1143 eventsChannel = m_evts[channelId];
1144 int iSub = klmChannel.getSubdetector();
1145 int iF, iS, iL, iP, iC;
1146
1147 if (iSub == KLMElementNumbers::c_BKLM) {
1148 iF = klmChannel.getSection();
1149 iS = klmChannel.getSector() - 1;
1150 iL = klmChannel.getLayer() - 1;
1151 iP = klmChannel.getPlane();
1152 iC = klmChannel.getStrip() - 1;
1153 } else {
1154 iF = klmChannel.getSection() - 1;
1155 iS = klmChannel.getSector() - 1;
1156 iL = klmChannel.getLayer() - 1;
1157 iP = klmChannel.getPlane() - 1;
1158 iC = klmChannel.getStrip() - 1;
1159 }
1160
1161 // Create and fill temp histogram
1162 TString hn, ht;
1163 TH1F* h_temp_tc = nullptr;
1164
1165 if (iSub == KLMElementNumbers::c_BKLM) {
1166 if (iL > 1) {
1167 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1168 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1169 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1170 h_temp_tc = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
1171 } else {
1172 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1173 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1174 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1175 h_temp_tc = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
1177 }
1178 } else {
1179 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc_end", iF, iS, iL, iP, iC);
1180 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1181 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1182 h_temp_tc = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
1184 }
1185
1186 for (const Event& event : eventsChannel) {
1187 double timeHit = event.time();
1188 if (m_useEventT0)
1189 timeHit = timeHit - event.t0;
1190 if (timeHit <= -400e3)
1191 continue;
1192 h_temp_tc->Fill(timeHit);
1193 }
1194
1195 h_temp_tc->Fit(fcn_gaus, "LESQ");
1196 double tmpMean_channel = fcn_gaus->GetParameter(1);
1197
1198 if (iSub == KLMElementNumbers::c_BKLM) {
1199 if (iL > 1) {
1200 m_timeShift[channelId] = tmpMean_channel - tmpMean_rpc_global;
1201 } else {
1202 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global;
1203 }
1204 } else {
1205 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global_end;
1206 }
1207
1208 delete h_temp_tc;
1209 }
1210
1211 m_evts.clear();
1212 B2INFO("Batch processed and cleared: " << batch.first);
1213 }
1214
1215 delete h_time_scint_tc;
1216 delete h_time_scint_tc_end;
1217 delete h_time_rpc_tc;
1218 B2INFO("Effective Light m_timeShift obtained.");
1219
1220 // NOTE: fillTimeDistanceProfiles also needs batching - user will handle separately
1225
1226 B2INFO("Effective light speed fitting.");
1227 m_ProfileRpcPhi->Fit("fcn_pol1", "EMQ");
1228 double delayRPCPhi = fcn_pol1->GetParameter(1);
1229 double e_slope_rpc_phi = fcn_pol1->GetParError(1);
1230
1231 m_ProfileRpcZ->Fit("fcn_pol1", "EMQ");
1232 double delayRPCZ = fcn_pol1->GetParameter(1);
1233 double e_slope_rpc_z = fcn_pol1->GetParError(1);
1234
1235 m_ProfileBKLMScintillatorPhi->Fit("fcn_pol1", "EMQ");
1236 double slope_scint_phi = fcn_pol1->GetParameter(1);
1237 double e_slope_scint_phi = fcn_pol1->GetParError(1);
1238
1239 m_ProfileBKLMScintillatorZ->Fit("fcn_pol1", "EMQ");
1240 double slope_scint_z = fcn_pol1->GetParameter(1);
1241 double e_slope_scint_z = fcn_pol1->GetParError(1);
1242
1243 m_ProfileEKLMScintillatorPlane1->Fit("fcn_pol1", "EMQ");
1244 double slope_scint_plane1_end = fcn_pol1->GetParameter(1);
1245 double e_slope_scint_plane1_end = fcn_pol1->GetParError(1);
1246
1247 m_ProfileEKLMScintillatorPlane2->Fit("fcn_pol1", "EMQ");
1248 double slope_scint_plane2_end = fcn_pol1->GetParameter(1);
1249 double e_slope_scint_plane2_end = fcn_pol1->GetParError(1);
1250
1251 TString logStr_phi, logStr_z;
1252 logStr_phi = Form("%.4f +/- %.4f ns/cm", delayRPCPhi, e_slope_rpc_phi);
1253 logStr_z = Form("%.4f +/- %.4f ns/cm", delayRPCZ, e_slope_rpc_z);
1254 B2INFO("Delay in RPCs:"
1255 << LogVar("Fitted Value (phi readout) ", logStr_phi.Data())
1256 << LogVar("Fitted Value (z readout) ", logStr_z.Data()));
1257 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_phi, e_slope_scint_phi);
1258 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_z, e_slope_scint_z);
1259 B2INFO("Delay in BKLM scintillators:"
1260 << LogVar("Fitted Value (phi readout) ", logStr_phi.Data())
1261 << LogVar("Fitted Value (z readout) ", logStr_z.Data()));
1262 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_plane1_end,
1263 e_slope_scint_plane1_end);
1264 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_plane2_end,
1265 e_slope_scint_plane2_end);
1266 B2INFO("Delay in EKLM scintillators:"
1267 << LogVar("Fitted Value (plane1 readout) ", logStr_phi.Data())
1268 << LogVar("Fitted Value (plane2 readout) ", logStr_z.Data()));
1269
1270 logStr_z = Form("%.4f +/- %.4f ns/cm", delayBKLM, delayBKLMError);
1271 B2INFO("Delay in BKLM scintillators:"
1272 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1273 logStr_z = Form("%.4f +/- %.4f ns/cm", delayEKLM, delayEKLMError);
1274 B2INFO("Delay in EKLM scintillators:"
1275 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1276
1277 m_timeConstants->setDelay(delayEKLM, KLMTimeConstants::c_EKLM);
1278 m_timeConstants->setDelay(delayBKLM, KLMTimeConstants::c_BKLM);
1279 m_timeConstants->setDelay(delayRPCPhi, KLMTimeConstants::c_RPCPhi);
1280 m_timeConstants->setDelay(delayRPCZ, KLMTimeConstants::c_RPCZ);
1281
1282 /**********************************
1283 * THIRD LOOP (BATCHED)
1284 * Fill per-channel distributions and fit
1285 **********************************/
1286 B2INFO("Third loop: Time distribution filling (batched processing)...");
1287
1288 for (const auto& batch : batches) {
1289 B2INFO("Processing batch: " << batch.first);
1290 readCalibrationDataBatch(batch.second);
1291
1292 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1293 channelId = klmChannel.getKLMChannelNumber();
1294
1295 if (!batch.second(klmChannel))
1296 continue;
1297
1298 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1299 continue;
1300
1301 if (m_evts.find(channelId) == m_evts.end())
1302 continue;
1303
1304 eventsChannel = m_evts[channelId];
1305 int iSub = klmChannel.getSubdetector();
1306 int iF, iS, iL, iP, iC;
1307
1308 if (iSub == KLMElementNumbers::c_BKLM) {
1309 iF = klmChannel.getSection();
1310 iS = klmChannel.getSector() - 1;
1311 iL = klmChannel.getLayer() - 1;
1312 iP = klmChannel.getPlane();
1313 iC = klmChannel.getStrip() - 1;
1314 } else {
1315 iF = klmChannel.getSection() - 1;
1316 iS = klmChannel.getSector() - 1;
1317 iL = klmChannel.getLayer() - 1;
1318 iP = klmChannel.getPlane() - 1;
1319 iC = klmChannel.getStrip() - 1;
1320 }
1321
1322 // Create per-channel histogram
1323 TString hn, ht;
1324 TH1F* h_temp = nullptr;
1325
1326 if (iSub == KLMElementNumbers::c_BKLM) {
1327 if (iL > 1) {
1328 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1329 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1330 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1331 h_temp = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryRPC, m_UpperTimeBoundaryRPC);
1332 } else {
1333 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1334 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1335 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1336 h_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsBKLM,
1338 }
1339 } else {
1340 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1341 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1342 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1343 h_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryScintillatorsEKLM,
1345 }
1346
1347 // Fill histogram
1348 for (const Event& event : eventsChannel) {
1349 double timeHit = event.time();
1350 if (m_useEventT0)
1351 timeHit = timeHit - event.t0;
1352 if (timeHit <= -400e3)
1353 continue;
1354
1355 if (iSub == KLMElementNumbers::c_BKLM) {
1356 if (iL > 1) {
1357 double propgationT;
1359 propgationT = event.dist * delayRPCZ;
1360 else
1361 propgationT = event.dist * delayRPCPhi;
1362 double time = timeHit - propgationT;
1363
1364 h_time_rpc->Fill(time);
1365 h_temp->Fill(time);
1366
1367 if (m_saveAllPlots) {
1368 h_timeF_rpc[iF]->Fill(time);
1369 h_timeFS_rpc[iF][iS]->Fill(time);
1370 h_timeFSL[iF][iS][iL]->Fill(time);
1371 h_timeFSLP[iF][iS][iL][iP]->Fill(time);
1372 h2_timeF_rpc[iF]->Fill(iS, time);
1373 h2_timeFS[iF][iS]->Fill(iL, time);
1374 h2_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1375 }
1376 } else {
1377 double propgationT = event.dist * delayBKLM;
1378 double time = timeHit - propgationT;
1379
1380 h_time_scint->Fill(time);
1381 h_temp->Fill(time);
1382
1383 if (m_saveAllPlots) {
1384 h_timeF_scint[iF]->Fill(time);
1385 h_timeFS_scint[iF][iS]->Fill(time);
1386 h_timeFSL[iF][iS][iL]->Fill(time);
1387 h_timeFSLP[iF][iS][iL][iP]->Fill(time);
1388 h2_timeF_scint[iF]->Fill(iS, time);
1389 h2_timeFS[iF][iS]->Fill(iL, time);
1390 h2_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1391 }
1392 }
1393 } else {
1394 double propgationT = event.dist * delayEKLM;
1395 double time = timeHit - propgationT;
1396
1397 h_time_scint_end->Fill(time);
1398 h_temp->Fill(time);
1399
1400 if (m_saveAllPlots) {
1401 h_timeF_scint_end[iF]->Fill(time);
1402 h_timeFS_scint_end[iF][iS]->Fill(time);
1403 h_timeFSL_end[iF][iS][iL]->Fill(time);
1404 h_timeFSLP_end[iF][iS][iL][iP]->Fill(time);
1405 h2_timeF_scint_end[iF]->Fill(iS, time);
1406 h2_timeFS_end[iF][iS]->Fill(iL, time);
1407 h2_timeFSLP_end[iF][iS][iL][iP]->Fill(iC, time);
1408 }
1409 }
1410 }
1411
1412 TFitResultPtr r = h_temp->Fit(fcn_gaus, "LESQ");
1413 if (int(r) == 0) {
1414 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1415 m_time_channel[channelId] = fcn_gaus->GetParameter(1);
1416 m_etime_channel[channelId] = fcn_gaus->GetParError(1);
1417 }
1418
1420 }
1421
1422 m_evts.clear();
1423 B2INFO("Batch processed and cleared: " << batch.first);
1424 }
1425
1426 B2INFO("Original filling done.");
1427
1428 // Fill TGraphs with extracted parameters
1429 int iChannel_rpc = 0;
1430 int iChannel = 0;
1431 int iChannel_end = 0;
1432 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1433 channelId = klmChannel.getKLMChannelNumber();
1434 if (m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1435 continue;
1436
1437 int iSub = klmChannel.getSubdetector();
1438 if (iSub == KLMElementNumbers::c_BKLM) {
1439 int iL = klmChannel.getLayer() - 1;
1440 if (iL > 1) {
1441 gre_time_channel_rpc->SetPoint(iChannel_rpc, channelId, m_time_channel[channelId]);
1442 gre_time_channel_rpc->SetPointError(iChannel_rpc, 0., m_etime_channel[channelId]);
1443 iChannel_rpc++;
1444 } else {
1445 gre_time_channel_scint->SetPoint(iChannel, channelId, m_time_channel[channelId]);
1446 gre_time_channel_scint->SetPointError(iChannel, 0., m_etime_channel[channelId]);
1447 iChannel++;
1448 }
1449 } else {
1450 gre_time_channel_scint_end->SetPoint(iChannel_end, channelId, m_time_channel[channelId]);
1451 gre_time_channel_scint_end->SetPointError(iChannel_end, 0., m_etime_channel[channelId]);
1452 iChannel_end++;
1453 }
1454 }
1455
1456 gre_time_channel_scint->Fit("fcn_const", "EMQ");
1457 m_time_channelAvg_scint = fcn_const->GetParameter(0);
1458 m_etime_channelAvg_scint = fcn_const->GetParError(0);
1459
1460 gre_time_channel_scint_end->Fit("fcn_const", "EMQ");
1461 m_time_channelAvg_scint_end = fcn_const->GetParameter(0);
1462 m_etime_channelAvg_scint_end = fcn_const->GetParError(0);
1463
1464 gre_time_channel_rpc->Fit("fcn_const", "EMQ");
1465 m_time_channelAvg_rpc = fcn_const->GetParameter(0);
1466 m_etime_channelAvg_rpc = fcn_const->GetParError(0);
1467
1468 B2INFO("Channel's time distribution fitting done.");
1469 B2DEBUG(20, LogVar("Average time (RPC)", m_time_channelAvg_rpc)
1470 << LogVar("Average time (BKLM scintillators)", m_time_channelAvg_scint)
1471 << LogVar("Average time (EKLM scintillators)", m_time_channelAvg_scint_end));
1472
1473 B2INFO("Calibrated channel's time distribution filling begins.");
1474
1475 m_timeShift.clear();
1476 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1477 channelId = klmChannel.getKLMChannelNumber();
1478 h_calibrated->Fill(m_cFlag[channelId]);
1479 if (m_time_channel.find(channelId) == m_time_channel.end())
1480 continue;
1481 double timeShift = m_time_channel[channelId];
1482 m_timeShift[channelId] = timeShift;
1483 m_timeCableDelay->setTimeDelay(channelId, m_timeShift[channelId]);
1484 }
1485
1486 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1487 channelId = klmChannel.getKLMChannelNumber();
1488 if (m_timeShift.find(channelId) != m_timeShift.end())
1489 continue;
1490 m_timeShift[channelId] = esti_timeShift(klmChannel);
1491 m_timeCableDelay->setTimeDelay(channelId, m_timeShift[channelId]);
1492 B2DEBUG(20, "Uncalibrated Estimation " << LogVar("Channel", channelId) << LogVar("Estimated value", m_timeShift[channelId]));
1493 }
1494
1495 iChannel_rpc = 0;
1496 iChannel = 0;
1497 iChannel_end = 0;
1498 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1499 channelId = klmChannel.getKLMChannelNumber();
1500 if (m_timeShift.find(channelId) == m_timeShift.end()) {
1501 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
1502 continue;
1503 }
1504 int iSub = klmChannel.getSubdetector();
1505 if (iSub == KLMElementNumbers::c_BKLM) {
1506 int iL = klmChannel.getLayer();
1507 if (iL > 2) {
1508 gr_timeShift_channel_rpc->SetPoint(iChannel_rpc, channelId, m_timeShift[channelId]);
1509 iChannel_rpc++;
1510 } else {
1511 gr_timeShift_channel_scint->SetPoint(iChannel, channelId, m_timeShift[channelId]);
1512 iChannel++;
1513 }
1514 } else {
1515 gr_timeShift_channel_scint_end->SetPoint(iChannel_end, channelId, m_timeShift[channelId]);
1516 iChannel_end++;
1517 }
1518 }
1519
1520 // NOTE: This also needs batching
1525
1526 /**********************************
1527 * FOURTH LOOP (BATCHED)
1528 * Fill calibrated per-channel histograms
1529 **********************************/
1530 B2INFO("Fourth loop: Calibrated time distribution filling (batched processing)...");
1531
1532 for (const auto& batch : batches) {
1533 B2INFO("Processing batch: " << batch.first);
1534 readCalibrationDataBatch(batch.second);
1535
1536 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1537 channelId = klmChannel.getKLMChannelNumber();
1538
1539 if (!batch.second(klmChannel))
1540 continue;
1541
1542 if (m_evts.find(channelId) == m_evts.end())
1543 continue;
1544
1545 eventsChannel = m_evts[channelId];
1546 int iSub = klmChannel.getSubdetector();
1547 int iF, iS, iL, iP, iC;
1548
1549 if (iSub == KLMElementNumbers::c_BKLM) {
1550 iF = klmChannel.getSection();
1551 iS = klmChannel.getSector() - 1;
1552 iL = klmChannel.getLayer() - 1;
1553 iP = klmChannel.getPlane();
1554 iC = klmChannel.getStrip() - 1;
1555 } else {
1556 iF = klmChannel.getSection() - 1;
1557 iS = klmChannel.getSector() - 1;
1558 iL = klmChannel.getLayer() - 1;
1559 iP = klmChannel.getPlane() - 1;
1560 iC = klmChannel.getStrip() - 1;
1561 }
1562
1563 TString hn, ht;
1564 TH1F* hc_temp = nullptr;
1565
1566 if (iSub == KLMElementNumbers::c_BKLM) {
1567 if (iL > 1) {
1568 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1569 ht = Form("Calibrated time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1570 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1571 hc_temp = new TH1F(hn.Data(), ht.Data(), nBin, m_LowerTimeBoundaryCalibratedRPC,
1573 } else {
1574 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1575 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1576 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1577 hc_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsBKLM,
1579 }
1580 } else {
1581 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1582 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1583 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1584 hc_temp = new TH1F(hn.Data(), ht.Data(), nBin_scint, m_LowerTimeBoundaryCalibratedScintillatorsEKLM,
1586 }
1587
1588 for (const Event& event : eventsChannel) {
1589 double timeHit = event.time();
1590 if (m_useEventT0)
1591 timeHit = timeHit - event.t0;
1592 if (timeHit <= -400e3)
1593 continue;
1594
1595 if (iSub == KLMElementNumbers::c_BKLM) {
1596 if (iL > 1) {
1597 double propgationT;
1599 propgationT = event.dist * delayRPCZ;
1600 else
1601 propgationT = event.dist * delayRPCPhi;
1602 double time = timeHit - propgationT - m_timeShift[channelId];
1603
1604 hc_time_rpc->Fill(time);
1605 hc_temp->Fill(time);
1606
1607 if (m_saveAllPlots) {
1608 hc_timeF_rpc[iF]->Fill(time);
1609 hc_timeFS_rpc[iF][iS]->Fill(time);
1610 hc_timeFSL[iF][iS][iL]->Fill(time);
1611 hc_timeFSLP[iF][iS][iL][iP]->Fill(time);
1612 h2c_timeF_rpc[iF]->Fill(iS, time);
1613 h2c_timeFS[iF][iS]->Fill(iL, time);
1614 h2c_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1615 }
1616 } else {
1617 double propgationT = event.dist * delayBKLM;
1618 double time = timeHit - propgationT - m_timeShift[channelId];
1619
1620 hc_time_scint->Fill(time);
1621 hc_temp->Fill(time);
1622
1623 if (m_saveAllPlots) {
1624 hc_timeF_scint[iF]->Fill(time);
1625 hc_timeFS_scint[iF][iS]->Fill(time);
1626 hc_timeFSL[iF][iS][iL]->Fill(time);
1627 hc_timeFSLP[iF][iS][iL][iP]->Fill(time);
1628 h2c_timeF_scint[iF]->Fill(iS, time);
1629 h2c_timeFS[iF][iS]->Fill(iL, time);
1630 h2c_timeFSLP[iF][iS][iL][iP]->Fill(iC, time);
1631 }
1632 }
1633 } else {
1634 double propgationT = event.dist * delayEKLM;
1635 double time = timeHit - propgationT - m_timeShift[channelId];
1636
1637 hc_time_scint_end->Fill(time);
1638 hc_temp->Fill(time);
1639
1640 if (m_saveAllPlots) {
1641 hc_timeF_scint_end[iF]->Fill(time);
1642 hc_timeFS_scint_end[iF][iS]->Fill(time);
1643 hc_timeFSL_end[iF][iS][iL]->Fill(time);
1644 hc_timeFSLP_end[iF][iS][iL][iP]->Fill(time);
1645 h2c_timeF_scint_end[iF]->Fill(iS, time);
1646 h2c_timeFS_end[iF][iS]->Fill(iL, time);
1647 h2c_timeFSLP_end[iF][iS][iL][iP]->Fill(iC, time);
1648 }
1649 }
1650 }
1651
1652 if (m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData) {
1653 delete hc_temp;
1654 continue;
1655 }
1656
1657 TFitResultPtr rc = hc_temp->Fit(fcn_gaus, "LESQ");
1658 if (int(rc) == 0) {
1659 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1660 m_ctime_channel[channelId] = fcn_gaus->GetParameter(1);
1661 mc_etime_channel[channelId] = fcn_gaus->GetParError(1);
1662 }
1663
1665 }
1666
1667 m_evts.clear();
1668 B2INFO("Batch processed and cleared: " << batch.first);
1669 }
1670
1671 // Fill TGraphs with calibrated parameters
1672 int icChannel_rpc = 0;
1673 int icChannel = 0;
1674 int icChannel_end = 0;
1675 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1676 channelId = klmChannel.getKLMChannelNumber();
1677 if (m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1678 continue;
1679
1680 int iSub = klmChannel.getSubdetector();
1681 if (iSub == KLMElementNumbers::c_BKLM) {
1682 int iL = klmChannel.getLayer() - 1;
1683 if (iL > 1) {
1684 gre_ctime_channel_rpc->SetPoint(icChannel_rpc, channelId, m_ctime_channel[channelId]);
1685 gre_ctime_channel_rpc->SetPointError(icChannel_rpc, 0., mc_etime_channel[channelId]);
1686 icChannel_rpc++;
1687 } else {
1688 gre_ctime_channel_scint->SetPoint(icChannel, channelId, m_ctime_channel[channelId]);
1689 gre_ctime_channel_scint->SetPointError(icChannel, 0., mc_etime_channel[channelId]);
1690 icChannel++;
1691 }
1692 } else {
1693 gre_ctime_channel_scint_end->SetPoint(icChannel_end, channelId, m_ctime_channel[channelId]);
1694 gre_ctime_channel_scint_end->SetPointError(icChannel_end, 0., mc_etime_channel[channelId]);
1695 icChannel_end++;
1696 }
1697 }
1698
1699 gre_ctime_channel_scint->Fit("fcn_const", "EMQ");
1700 m_ctime_channelAvg_scint = fcn_const->GetParameter(0);
1701 mc_etime_channelAvg_scint = fcn_const->GetParError(0);
1702
1703 gre_ctime_channel_scint_end->Fit("fcn_const", "EMQ");
1704 m_ctime_channelAvg_scint_end = fcn_const->GetParameter(0);
1705 mc_etime_channelAvg_scint_end = fcn_const->GetParError(0);
1706
1707 gre_ctime_channel_rpc->Fit("fcn_const", "EMQ");
1708 m_ctime_channelAvg_rpc = fcn_const->GetParameter(0);
1709 mc_etime_channelAvg_rpc = fcn_const->GetParError(0);
1710
1711 B2INFO("Channel's time distribution fitting done.");
1712 B2DEBUG(20, LogVar("Average calibrated time (RPC)", m_ctime_channelAvg_rpc)
1713 << LogVar("Average calibrated time (BKLM scintillators)", m_ctime_channelAvg_scint)
1714 << LogVar("Average calibrated time (EKLM scintillators)", m_ctime_channelAvg_scint_end));
1715
1716 B2INFO("Calibrated channel's time distribution filling begins.");
1717
1718 m_timeRes.clear();
1719 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1720 channelId = klmChannel.getKLMChannelNumber();
1721 hc_calibrated->Fill(m_cFlag[channelId]);
1722 if (m_ctime_channel.find(channelId) == m_ctime_channel.end())
1723 continue;
1724 double timeRes = m_ctime_channel[channelId];
1725 m_timeRes[channelId] = timeRes;
1726 m_timeResolution->setTimeResolution(channelId, m_timeRes[channelId]);
1727 }
1728
1729 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1730 channelId = klmChannel.getKLMChannelNumber();
1731 if (m_timeRes.find(channelId) != m_timeRes.end())
1732 continue;
1733 m_timeRes[channelId] = esti_timeRes(klmChannel);
1734 m_timeResolution->setTimeResolution(channelId, m_timeRes[channelId]);
1735 B2DEBUG(20, "Calibrated Estimation " << LogVar("Channel", channelId) << LogVar("Estimated value", m_timeRes[channelId]));
1736 }
1737
1738 icChannel_rpc = 0;
1739 icChannel = 0;
1740 icChannel_end = 0;
1741 for (KLMChannelIndex klmChannel = m_klmChannels.begin(); klmChannel != m_klmChannels.end(); ++klmChannel) {
1742 channelId = klmChannel.getKLMChannelNumber();
1743 if (m_timeRes.find(channelId) == m_timeRes.end()) {
1744 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
1745 continue;
1746 }
1747 int iSub = klmChannel.getSubdetector();
1748 if (iSub == KLMElementNumbers::c_BKLM) {
1749 int iL = klmChannel.getLayer();
1750 if (iL > 2) {
1751 gr_timeRes_channel_rpc->SetPoint(icChannel_rpc, channelId, m_timeRes[channelId]);
1752 icChannel_rpc++;
1753 } else {
1754 gr_timeRes_channel_scint->SetPoint(icChannel, channelId, m_timeRes[channelId]);
1755 icChannel++;
1756 }
1757 } else {
1758 gr_timeRes_channel_scint_end->SetPoint(icChannel_end, channelId, m_timeRes[channelId]);
1759 icChannel_end++;
1760 }
1761 }
1762
1763 delete fcn_const;
1764 m_evts.clear();
1765 m_timeShift.clear();
1766 m_timeRes.clear();
1767 m_cFlag.clear();
1768
1769 saveHist();
1770
1771 saveCalibration(m_timeCableDelay, "KLMTimeCableDelay");
1772 saveCalibration(m_timeConstants, "KLMTimeConstants");
1773 saveCalibration(m_timeResolution, "KLMTimeResolution");
1775}
1776
1778{
1779 m_outFile->cd();
1780 B2INFO("Save Histograms into Files.");
1781
1782 // ===================================================================
1783 // VITAL PLOTS - Always saved
1784 // ===================================================================
1785 TDirectory* dir_monitor = m_outFile->mkdir("monitor_Hists", "", true);
1786 dir_monitor->cd();
1787 h_calibrated->SetDirectory(dir_monitor);
1788 hc_calibrated->SetDirectory(dir_monitor);
1789 h_diff->SetDirectory(dir_monitor);
1790
1791 m_outFile->cd();
1792 TDirectory* dir_effC = m_outFile->mkdir("effC_Hists", "", true);
1793 dir_effC->cd();
1794 m_ProfileRpcPhi->SetDirectory(dir_effC);
1795 m_ProfileRpcZ->SetDirectory(dir_effC);
1796 m_ProfileBKLMScintillatorPhi->SetDirectory(dir_effC);
1797 m_ProfileBKLMScintillatorZ->SetDirectory(dir_effC);
1798 m_ProfileEKLMScintillatorPlane1->SetDirectory(dir_effC);
1799 m_ProfileEKLMScintillatorPlane2->SetDirectory(dir_effC);
1800 m_Profile2RpcPhi->SetDirectory(dir_effC);
1801 m_Profile2RpcZ->SetDirectory(dir_effC);
1802 m_Profile2BKLMScintillatorPhi->SetDirectory(dir_effC);
1803 m_Profile2BKLMScintillatorZ->SetDirectory(dir_effC);
1804 m_Profile2EKLMScintillatorPlane1->SetDirectory(dir_effC);
1805 m_Profile2EKLMScintillatorPlane2->SetDirectory(dir_effC);
1806
1807 m_outFile->cd();
1808 TDirectory* dir_time = m_outFile->mkdir("time", "", true);
1809 dir_time->cd();
1810
1811 h_time_scint->SetDirectory(dir_time);
1812 hc_time_scint->SetDirectory(dir_time);
1813
1814 h_time_scint_end->SetDirectory(dir_time);
1815 hc_time_scint_end->SetDirectory(dir_time);
1816
1817 h_time_rpc->SetDirectory(dir_time);
1818 hc_time_rpc->SetDirectory(dir_time);
1819
1820 gre_time_channel_rpc->Write("gre_time_channel_rpc");
1821 gre_time_channel_scint->Write("gre_time_channel_scint");
1822 gre_time_channel_scint_end->Write("gre_time_channel_scint_end");
1823 gr_timeShift_channel_rpc->Write("gr_timeShift_channel_rpc");
1824 gr_timeShift_channel_scint->Write("gr_timeShift_channel_scint");
1825 gr_timeShift_channel_scint_end->Write("gr_timeShift_channel_scint_end");
1826 gre_ctime_channel_rpc->Write("gre_ctime_channel_rpc");
1827 gre_ctime_channel_scint->Write("gre_ctime_channel_scint");
1828 gre_ctime_channel_scint_end->Write("gre_ctime_channel_scint_end");
1829 gr_timeRes_channel_rpc->Write("gr_timeRes_channel_rpc");
1830 gr_timeRes_channel_scint->Write("gr_timeRes_channel_scint");
1831 gr_timeRes_channel_scint_end->Write("gr_timeRes_channel_scint_end");
1832
1833 B2INFO("Top file setup Done.");
1834
1835 // ===================================================================
1836 // DEBUG PLOTS - Only saved if m_saveAllPlots is true
1837 // ===================================================================
1838 if (!m_saveAllPlots) {
1839 B2INFO("Skipping debug histogram directory creation (m_saveAllPlots = false)");
1840 m_outFile->cd();
1841 m_outFile->Write();
1842 m_outFile->Close();
1843 B2INFO("File Write and Close. Done.");
1844 return;
1845 }
1846
1847 TDirectory* dir_time_F[2];
1848 TDirectory* dir_time_FS[2][8];
1849 TDirectory* dir_time_FSL[2][8][15];
1850 TDirectory* dir_time_FSLP[2][8][15][2];
1851 TDirectory* dir_time_F_end[2];
1852 TDirectory* dir_time_FS_end[2][4];
1853 TDirectory* dir_time_FSL_end[2][4][14];
1854 TDirectory* dir_time_FSLP_end[2][4][14][2];
1855 char dirname[50];
1856 B2INFO("Sub files declare Done.");
1857 for (int iF = 0; iF < 2; ++iF) {
1858 h_timeF_rpc[iF]->SetDirectory(dir_time);
1859 hc_timeF_rpc[iF]->SetDirectory(dir_time);
1860
1861 h2_timeF_rpc[iF]->SetDirectory(dir_time);
1862 h2c_timeF_rpc[iF]->SetDirectory(dir_time);
1863
1864 h_timeF_scint[iF]->SetDirectory(dir_time);
1865 hc_timeF_scint[iF]->SetDirectory(dir_time);
1866
1867 h2_timeF_scint[iF]->SetDirectory(dir_time);
1868 h2c_timeF_scint[iF]->SetDirectory(dir_time);
1869
1870 h_timeF_scint_end[iF]->SetDirectory(dir_time);
1871 hc_timeF_scint_end[iF]->SetDirectory(dir_time);
1872
1873 h2_timeF_scint_end[iF]->SetDirectory(dir_time);
1874 h2c_timeF_scint_end[iF]->SetDirectory(dir_time);
1875
1876 sprintf(dirname, "isForward_%d", iF);
1877 dir_time_F[iF] = dir_time->mkdir(dirname, "", true);
1878 dir_time_F[iF]->cd();
1879
1880 for (int iS = 0; iS < 8; ++iS) {
1881 h_timeFS_rpc[iF][iS]->SetDirectory(dir_time_F[iF]);
1882 hc_timeFS_rpc[iF][iS]->SetDirectory(dir_time_F[iF]);
1883
1884 h_timeFS_scint[iF][iS]->SetDirectory(dir_time_F[iF]);
1885 hc_timeFS_scint[iF][iS]->SetDirectory(dir_time_F[iF]);
1886
1887 h2_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
1888 h2c_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
1889
1890 sprintf(dirname, "Sector_%d", iS + 1);
1891 dir_time_FS[iF][iS] = dir_time_F[iF]->mkdir(dirname, "", true);
1892 dir_time_FS[iF][iS]->cd();
1893
1894 for (int iL = 0; iL < 15; ++iL) {
1895 h_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
1896 hc_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
1897
1898 sprintf(dirname, "Layer_%d", iL + 1);
1899 dir_time_FSL[iF][iS][iL] = dir_time_FS[iF][iS]->mkdir(dirname, "", true);
1900 dir_time_FSL[iF][iS][iL]->cd();
1901 for (int iP = 0; iP < 2; ++iP) {
1902 h_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1903 hc_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1904 h2_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1905 h2c_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1906
1907 sprintf(dirname, "Plane_%d", iP);
1908 dir_time_FSLP[iF][iS][iL][iP] = dir_time_FSL[iF][iS][iL]->mkdir(dirname, "", true);
1909 dir_time_FSLP[iF][iS][iL][iP]->cd();
1910
1911 }
1912 }
1913 }
1914
1915 sprintf(dirname, "isForward_%d_end", iF + 1);
1916 dir_time_F_end[iF] = dir_time->mkdir(dirname, "", true);
1917 dir_time_F_end[iF]->cd();
1918 int maxLayer = 12 + 2 * iF;
1919 for (int iS = 0; iS < 4; ++iS) {
1920 h_timeFS_scint_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
1921 hc_timeFS_scint_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
1922
1923 h2_timeFS_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
1924 h2c_timeFS_end[iF][iS]->SetDirectory(dir_time_F_end[iF]);
1925
1926 sprintf(dirname, "Sector_%d_end", iS + 1);
1927 dir_time_FS_end[iF][iS] = dir_time_F_end[iF]->mkdir(dirname, "", true);
1928 dir_time_FS_end[iF][iS]->cd();
1929 for (int iL = 0; iL < maxLayer; ++iL) {
1930 h_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
1931 hc_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
1932
1933 sprintf(dirname, "Layer_%d_end", iL + 1);
1934 dir_time_FSL_end[iF][iS][iL] = dir_time_FS_end[iF][iS]->mkdir(dirname, "", true);
1935 dir_time_FSL_end[iF][iS][iL]->cd();
1936 for (int iP = 0; iP < 2; ++iP) {
1937 h_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1938 hc_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1939 h2_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1940 h2c_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1941
1942 sprintf(dirname, "plane_%d_end", iP);
1943 dir_time_FSLP_end[iF][iS][iL][iP] = dir_time_FSL_end[iF][iS][iL]->mkdir(dirname, "", true);
1944 dir_time_FSLP_end[iF][iS][iL][iP]->cd();
1945
1946 }
1947 }
1948 }
1949 }
1950 m_outFile->cd();
1951 m_outFile->Write();
1952 m_outFile->Close();
1953 B2INFO("File Write and Close. Done.");
1954}
1955
1957{
1958 double tS = 0.0;
1959 int iSub = klmChannel.getSubdetector();
1960 int iF = klmChannel.getSection();
1961 int iS = klmChannel.getSector();
1962 int iL = klmChannel.getLayer();
1963 int iP = klmChannel.getPlane();
1964 int iC = klmChannel.getStrip();
1966 if (iSub == KLMElementNumbers::c_BKLM)
1967 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
1968 if (iC == 1) {
1969 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
1970 tS = tS_upperStrip(kCIndex_upper).second;
1971 } else if (iC == totNStrips) {
1972 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
1973 tS = tS_lowerStrip(kCIndex_lower).second;
1974 } else {
1975 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
1976 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
1977 std::pair<int, double> tS_upper = tS_upperStrip(kCIndex_upper);
1978 std::pair<int, double> tS_lower = tS_lowerStrip(kCIndex_lower);
1979 unsigned int td_upper = tS_upper.first - iC;
1980 unsigned int td_lower = iC - tS_lower.first;
1981 unsigned int td = tS_upper.first - tS_lower.first;
1982 tS = (double(td_upper) * tS_lower.second + double(td_lower) * tS_upper.second) / double(td);
1983 }
1984 return tS;
1985}
1986
1987std::pair<int, double> KLMTimeAlgorithm::tS_upperStrip(const KLMChannelIndex& klmChannel)
1988{
1989 std::pair<int, double> tS;
1990 int cId = klmChannel.getKLMChannelNumber();
1991 int iSub = klmChannel.getSubdetector();
1992 int iF = klmChannel.getSection();
1993 int iS = klmChannel.getSector();
1994 int iL = klmChannel.getLayer();
1995 int iP = klmChannel.getPlane();
1996 int iC = klmChannel.getStrip();
1998 if (iSub == KLMElementNumbers::c_BKLM)
1999 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2000 if (m_timeShift.find(cId) != m_timeShift.end()) {
2001 tS.first = iC;
2002 tS.second = m_timeShift[cId];
2003 } else if (iC == totNStrips) {
2004 tS.first = iC;
2005 tS.second = 0.0;
2006 } else {
2007 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC + 1);
2008 tS = tS_upperStrip(kCIndex);
2009 }
2010 return tS;
2011}
2012
2013std::pair<int, double> KLMTimeAlgorithm::tS_lowerStrip(const KLMChannelIndex& klmChannel)
2014{
2015 std::pair<int, double> tS;
2016 int cId = klmChannel.getKLMChannelNumber();
2017 int iSub = klmChannel.getSubdetector();
2018 int iF = klmChannel.getSection();
2019 int iS = klmChannel.getSector();
2020 int iL = klmChannel.getLayer();
2021 int iP = klmChannel.getPlane();
2022 int iC = klmChannel.getStrip();
2023 if (m_timeShift.find(cId) != m_timeShift.end()) {
2024 tS.first = iC;
2025 tS.second = m_timeShift[cId];
2026 } else if (iC == 1) {
2027 tS.first = iC;
2028 tS.second = 0.0;
2029 } else {
2030 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC - 1);
2031 tS = tS_lowerStrip(kCIndex);
2032 }
2033 return tS;
2034}
2035
2037{
2038 double tR = 0.0;
2039 int iSub = klmChannel.getSubdetector();
2040 int iF = klmChannel.getSection();
2041 int iS = klmChannel.getSector();
2042 int iL = klmChannel.getLayer();
2043 int iP = klmChannel.getPlane();
2044 int iC = klmChannel.getStrip();
2046 if (iSub == KLMElementNumbers::c_BKLM)
2047 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2048 if (iC == 1) {
2049 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2050 tR = tR_upperStrip(kCIndex_upper).second;
2051 } else if (iC == totNStrips) {
2052 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2053 tR = tR_lowerStrip(kCIndex_lower).second;
2054 } else {
2055 KLMChannelIndex kCIndex_upper(iSub, iF, iS, iL, iP, iC + 1);
2056 KLMChannelIndex kCIndex_lower(iSub, iF, iS, iL, iP, iC - 1);
2057 std::pair<int, double> tR_upper = tR_upperStrip(kCIndex_upper);
2058 std::pair<int, double> tR_lower = tR_lowerStrip(kCIndex_lower);
2059 unsigned int tr_upper = tR_upper.first - iC;
2060 unsigned int tr_lower = iC - tR_lower.first;
2061 unsigned int tr = tR_upper.first - tR_lower.first;
2062 tR = (double(tr_upper) * tR_lower.second + double(tr_lower) * tR_upper.second) / double(tr);
2063 }
2064 return tR;
2065}
2066
2067std::pair<int, double> KLMTimeAlgorithm::tR_upperStrip(const KLMChannelIndex& klmChannel)
2068{
2069 std::pair<int, double> tR;
2070 int cId = klmChannel.getKLMChannelNumber();
2071 int iSub = klmChannel.getSubdetector();
2072 int iF = klmChannel.getSection();
2073 int iS = klmChannel.getSector();
2074 int iL = klmChannel.getLayer();
2075 int iP = klmChannel.getPlane();
2076 int iC = klmChannel.getStrip();
2078 if (iSub == KLMElementNumbers::c_BKLM)
2079 totNStrips = BKLMElementNumbers::getNStrips(iF, iS, iL, iP);
2080 if (m_timeRes.find(cId) != m_timeRes.end()) {
2081 tR.first = iC;
2082 tR.second = m_timeRes[cId];
2083 } else if (iC == totNStrips) {
2084 tR.first = iC;
2085 tR.second = 0.0;
2086 } else {
2087 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC + 1);
2088 tR = tR_upperStrip(kCIndex);
2089 }
2090 return tR;
2091}
2092
2093std::pair<int, double> KLMTimeAlgorithm::tR_lowerStrip(const KLMChannelIndex& klmChannel)
2094{
2095 std::pair<int, double> tR;
2096 int cId = klmChannel.getKLMChannelNumber();
2097 int iSub = klmChannel.getSubdetector();
2098 int iF = klmChannel.getSection();
2099 int iS = klmChannel.getSector();
2100 int iL = klmChannel.getLayer();
2101 int iP = klmChannel.getPlane();
2102 int iC = klmChannel.getStrip();
2103 if (m_timeRes.find(cId) != m_timeRes.end()) {
2104 tR.first = iC;
2105 tR.second = m_timeRes[cId];
2106 } else if (iC == 1) {
2107 tR.first = iC;
2108 tR.second = 0.0;
2109 } else {
2110 KLMChannelIndex kCIndex(iSub, iF, iS, iL, iP, iC - 1);
2111 tR = tR_lowerStrip(kCIndex);
2112 }
2113 return tR;
2114}
@ c_FirstRPCLayer
First RPC layer.
static int getNStrips(int section, int sector, int layer, int plane)
Get number of strips.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
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.
@ c_NotEnoughData
Needs more data =2 in Python.
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
Class for accessing objects in the database.
Definition DBObjPtr.h:21
Singleton class to cache database objects.
Definition DBStore.h:31
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
static constexpr int getMaximalStripNumber()
Get maximal strip number.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
KLM channel index.
int getSubdetector() const
Get subdetector.
int getLayer() const
Get layer.
int getSection() const
Get section.
int getPlane() const
Get plane.
int getStrip() const
Get strip.
int getSector() const
Get sector.
KLMChannelNumber getKLMChannelNumber() const
Get KLM channel number.
static const KLMElementNumbers & Instance()
Instantiation.
TProfile * m_Profile2EKLMScintillatorPlane2
For EKLM scintillator plane2.
double mc_etime_channelAvg_rpc
Calibrated central value error of the global time distribution (BKLM RPC part).
TH2F * h2c_timeF_scint_end[2]
EKLM part.
KLMTimeResolution * m_timeResolution
DBObject of time resolution.
TH1F * h_time_scint_tc_end
EKLM part.
void createHistograms()
Create histograms.
TGraphErrors * gre_time_channel_scint
BKLM Scintillator.
TH1F * h_timeFSL[2][8][15]
BKLM part.
TH1F * hc_timeFSL_end[2][4][14]
EKLM part.
TH1F * h_timeFSLP_end[2][4][14][2]
EKLM part.
TGraph * gr_timeRes_channel_rpc
BKLM RPC.
TH1F * hc_timeFSLP_end[2][4][14][2]
EKLM part.
TH1F * h_timeFSLP[2][8][15][2]
BKLM part.
TH1F * hc_timeF_scint_end[2]
EKLM part.
std::map< KLMChannelNumber, double > m_timeShift
Shift values of each channel.
TH1F * h_time_scint
BKLM scintillator part.
double m_time_channelAvg_scint
Central value of the global time distribution (BKLM scintillator part).
TH1F * hc_timeFS_scint_end[2][4]
EKLM part.
double esti_timeRes(const KLMChannelIndex &klmChannel)
Estimate value of calibration constant for calibrated channels.
double m_UpperTimeBoundaryCalibratedRPC
Upper time boundary for RPC (calibrated data).
double m_ctime_channelAvg_rpc
Calibrated central value of the global time distribution (BKLM RPC part).
KLMTimeConstants * m_timeConstants
DBObject of time cost on some parts of the detector.
void setupDatabase()
Setup the database.
TH1F * hc_timeFS_scint[2][8]
BKLM scintillator part.
std::map< KLMChannelNumber, double > m_time_channel
Time distribution central value of each channel.
double m_ctime_channelAvg_scint_end
Calibrated central value of the global time distribution (EKLM scintillator part).
CalibrationAlgorithm::EResult readCalibrationData()
Read calibration data.
TGraph * gr_timeShift_channel_scint_end
EKLM.
TGraph * gr_timeRes_channel_scint
BKLM scintillator.
TH1F * hc_timeF_scint[2]
BKLM scintillator part.
TH1F * h_timeFS_scint[2][8]
BKLM scintillator part.
bool m_saveChannelHists
Write per-channel temporary histograms (tc/raw/hc) in minimal mode.
double m_UpperTimeBoundaryScintillatorsBKLM
Upper time boundary for BKLM scintillators.
const KLMElementNumbers * m_ElementNumbers
Element numbers.
std::pair< int, double > tR_upperStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with increasing strip number.
TH1F * hc_timeF_rpc[2]
BKLM RPC part.
TH2F * h2c_timeFS_end[2][4]
EKLM part.
const EKLM::GeometryData * m_EKLMGeometry
EKLM geometry data.
TGraphErrors * gre_ctime_channel_scint_end
EKLM.
TProfile * m_Profile2BKLMScintillatorPhi
For BKLM scintillator phi plane.
TH1F * hc_time_scint_end
EKLM part.
TGraphErrors * gre_time_channel_scint_end
EKLM.
TH2F * h2_timeFSLP[2][8][15][2]
BKLM part.
double m_UpperTimeBoundaryCalibratedScintillatorsEKLM
Upper time boundary for BKLM scintillators (calibrated data).
TGraph * gr_timeShift_channel_scint
BKLM scintillator.
double m_time_channelAvg_scint_end
Central value of the global time distribution (EKLM scintillator part).
TProfile * m_Profile2EKLMScintillatorPlane1
For EKLM scintillator plane1.
TH1F * hc_timeFS_rpc[2][8]
BKLM RPC part.
double m_UpperTimeBoundaryScintillatorsEKLM
Upper time boundary for BKLM scintillators.
void fillTimeDistanceProfiles(TProfile *profileRpcPhi, TProfile *profileRpcZ, TProfile *profileBKLMScintillatorPhi, TProfile *profileBKLMScintillatorZ, TProfile *profileEKLMScintillatorPlane1, TProfile *profileEKLMScintillatorPlane2, bool fill2dHistograms)
Fill profiles of time versus distance.
TFile * m_outFile
Output file.
double esti_timeShift(const KLMChannelIndex &klmChannel)
Estimate value of calibration constant for uncalibrated channels.
std::pair< int, double > tS_upperStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with increasing strip number.
double m_LowerTimeBoundaryCalibratedScintillatorsEKLM
Lower time boundary for EKLM scintillators (calibrated data).
TH1F * hc_timeFSLP[2][8][15][2]
BKLM part.
TGraphErrors * gre_ctime_channel_rpc
BKLM RPC.
void saveHist()
Save histograms to file.
const bklm::GeometryPar * m_BKLMGeometry
BKLM geometry data.
bool m_saveAllPlots
Default minimal unless you set true in your header script.
TH2F * h2c_timeFSLP[2][8][15][2]
BKLM part.
double m_ctime_channelAvg_scint
Calibrated central value of the global time distribution (BKLM scintillator part).
TF1 * fcn_const
Const function.
double m_UpperTimeBoundaryCalibratedScintillatorsBKLM
Upper time boundary for BKLM scintillators (calibrated data).
TProfile * m_Profile2RpcZ
For BKLM RPC z plane.
TH2F * h2_timeFSLP_end[2][4][14][2]
EKLM part.
TH1I * hc_calibrated
Calibration statistics for each channel.
void timeDistance2dFit(const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channels, double &delay, double &delayError)
Two-dimensional fit for individual channels.
TGraph * gr_timeRes_channel_scint_end
EKLM.
TH1I * h_calibrated
Calibration statistics for each channel.
TProfile * m_ProfileBKLMScintillatorZ
For BKLM scintillator z plane.
double m_LowerTimeBoundaryScintillatorsBKLM
Lower time boundary for BKLM scintillators.
TH1F * h_time_rpc_tc
BKLM RPC part.
TH1F * h_time_scint_end
EKLM part.
TH2F * h2c_timeF_scint[2]
BKLM scintillator part.
TF1 * fcn_pol1
Pol1 function.
double m_etime_channelAvg_scint_end
Central value error of the global time distribution (EKLM scintillator part).
TH1F * hc_time_rpc
BKLM RPC part.
double mc_etime_channelAvg_scint
Calibrated central value error of the global time distribution (BKLM scintillator part).
TH2F * h2c_timeFSLP_end[2][4][14][2]
EKLM part.
double mc_etime_channelAvg_scint_end
Calibrated central value error of the global time distribution (EKLM scintillator part).
void writeThenDelete_(TH1 *h, bool write)
Optionally write a histogram, then delete it to free memory.
TH2F * h2_timeF_scint_end[2]
EKLM part.
TF1 * fcn_gaus
Gaussian function.
double m_LowerTimeBoundaryCalibratedScintillatorsBKLM
Lower time boundary for BKLM scintillators (calibrated data).
TH1F * h_timeF_rpc[2]
BKLM RPC part.
TProfile * m_ProfileBKLMScintillatorPhi
For BKLM scintillator phi plane.
TH1F * hc_time_scint
BKLM scintillator part.
TH2F * h2_timeFS[2][8]
BKLM part.
double m_etime_channelAvg_scint
Central value error of the global time distribution (BKLM scintillator part).
TH1F * h_timeF_scint_end[2]
EKLM part.
TProfile * m_ProfileRpcPhi
For BKLM RPC phi plane.
TGraphErrors * gre_ctime_channel_scint
BKLM Scintillator.
TProfile * m_ProfileEKLMScintillatorPlane2
For EKLM scintillator plane2.
TH1F * h_time_rpc
BKLM RPC part.
TH1F * h_timeFSL_end[2][4][14]
EKLM part.
TProfile * m_Profile2RpcPhi
For BKLM RPC phi plane.
TH1F * h_timeF_scint[2]
BKLM scintillator part.
TH1F * hc_timeFSL[2][8][15]
BKLM part.
TProfile * m_Profile2BKLMScintillatorZ
For BKLM scintillator z plane.
TH1F * h_timeFS_rpc[2][8]
BKLM RPC part.
KLMChannelIndex m_klmChannels
KLM ChannelIndex object.
TGraph * gr_timeShift_channel_rpc
BKLM RPC.
std::map< KLMChannelNumber, double > m_timeRes
Resolution values of each channel.
TH1F * h_diff
Distance between global and local position.
TH2F * h2_timeF_scint[2]
BKLM scintillator part.
TH1F * h_time_scint_tc
BKLM scintillator part.
double m_LowerTimeBoundaryRPC
Lower time boundary for RPC.
virtual EResult calibrate() override
Run algorithm on data.
std::map< KLMChannelNumber, double > m_ctime_channel
Calibrated time distribution central value of each channel.
double m_LowerTimeBoundaryCalibratedRPC
Lower time boundary for RPC (calibrated data).
bool m_useEventT0
Whether to use event T0 from CDC.
int m_MinimalDigitNumber
Minimal digit number (total).
TProfile * m_ProfileEKLMScintillatorPlane1
For EKLM scintillator plane1.
double m_UpperTimeBoundaryRPC
Upper time boundary for RPC.
TH2F * h2c_timeF_rpc[2]
BKLM RPC part.
TF1 * fcn_land
Landau function.
KLMTimeCableDelay * m_timeCableDelay
DBObject of the calibration constant of each channel due to cable decay.
std::pair< int, double > tS_lowerStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with decreasing strip number.
TProfile * m_ProfileRpcZ
For BKLM RPC z plane.
std::map< KLMChannelNumber, double > mc_etime_channel
Calibrated time distribution central value Error of each channel.
std::pair< int, double > tR_lowerStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with decreasing strip number.
void readCalibrationDataBatch(std::function< bool(const KLMChannelIndex &)> channelFilter)
Load calibration data for a specific batch of channels.
ROOT::Math::MinimizerOptions m_minimizerOptions
Minimization options.
std::map< KLMChannelNumber, int > m_cFlag
Calibration flag if the channel has enough hits collected and fitted OK.
TGraphErrors * gre_time_channel_rpc
BKLM RPC.
TH2F * h2_timeFS_end[2][4]
EKLM part.
TH2F * h2_timeF_rpc[2]
BKLM RPC part.
std::map< KLMChannelNumber, std::vector< struct Event > > m_evts
Container of hit information.
TH1F * h_timeFS_scint_end[2][4]
EKLM part.
double m_time_channelAvg_rpc
Central value of the global time distribution (BKLM RPC part).
TH2F * h2c_timeFS[2][8]
BKLM part.
double m_etime_channelAvg_rpc
Central value error of the global time distribution (BKLM RPC part).
double m_LowerTimeBoundaryScintillatorsEKLM
Lower time boundary for EKLM scintillators.
void readCalibrationDataCounts(std::map< KLMChannelNumber, unsigned int > &eventCounts)
Count events per channel (lightweight scan without loading full data).
std::map< KLMChannelNumber, double > m_etime_channel
Time distribution central value Error of each channel.
int m_lower_limit_counts
Lower limit of hits collected for on single channel.
void readCalibrationDataFor2DFit(const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsBKLM, const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsEKLM)
Load calibration data only for channels needed for 2D fit.
Class to store BKLM delay time coused by cable in the database.
Class to store KLM constants related to time.
@ c_BKLM
BKLM scintillator.
@ c_EKLM
EKLM scintillator.
Class to store KLM time resolution in the database.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
static const double cm
Standard units with the value = 1.
Definition Unit.h:47
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Definition Module.h:76
Class to store variables with their name which were sent to the logging service.
STL class.
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 updateEvent()
Updates all intra-run dependent objects.
Definition DBStore.cc:140
void update()
Updates all objects that are outside their interval of validity.
Definition DBStore.cc:77
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
uint16_t KLMChannelNumber
Channel number.
Abstract base class for different kinds of events.