Belle II Software development
eclTimeShiftsAlgorithm.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 <ecl/calibration/eclTimeShiftsAlgorithm.h>
11
12/* ECL headers. */
13#include <ecl/dbobjects/ECLCrystalCalib.h>
14#include <ecl/dbobjects/ECLReferenceCrystalPerCrateCalib.h>
15#include <ecl/digitization/EclConfiguration.h>
16#include <ecl/mapper/ECLChannelMapper.h>
17
18/* Basf2 headers. */
19#include <framework/dbobjects/HardwareClockSettings.h>
20
21/* ROOT headers. */
22#include <TCanvas.h>
23#include <TDirectory.h>
24#include <TFile.h>
25#include <TGraphErrors.h>
26#include <TH1F.h>
27#include <TLatex.h>
28#include <TString.h>
29
30/* C++ headers. */
31#include <iomanip>
32#include <sstream>
33
34using namespace std;
35using namespace Belle2;
36using namespace ECL;
37using namespace Calibration;
38
40//eclTimeShiftsAlgorithm::eclTimeShiftsAlgorithm(): CalibrationAlgorithm("DummyCollector"),
42 CalibrationAlgorithm("eclTimeShiftsPlottingCollector"),
43 debugFilenameBase("ECL_time_offsets"),
44 timeShiftForPlotStyle{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
48 m_ECLCrystalTimeOffset("ECLCrystalTimeOffset"),
49 m_ECLCrateTimeOffset("ECLCrateTimeOffset"),
50 m_refCrysIDzeroingCrate("ECLReferenceCrystalPerCrateCalib")//,
51{
53 "Plots the ecl crystal and crate time calibations."
54 );
55}
56
58{
60 gROOT->SetBatch();
61
62 B2INFO("eclTimeShiftsAlgorithm parameters:");
63 B2INFO("debugFilenameBase = " << debugFilenameBase);
64 B2INFO("algorithmReadPayloads = " << algorithmReadPayloads);
65 B2INFO("timeShiftForPlotStyle = {");
66 for (int crateTest = 0; crateTest < 51; crateTest++) {
67 B2INFO(timeShiftForPlotStyle[crateTest] << ",");
68 }
69 B2INFO(timeShiftForPlotStyle[51] << "}");
70
71
72 //------------------------------------------------------------------------
73 /* Conversion coefficient from ADC ticks to nanoseconds
74 1/(4fRF) = 0.4913 ns/clock tick, where fRF is the accelerator RF frequency.
75 Same for all crystals. */
76
77 //..First need to set event, run, exp number
78 const auto expRunList = getRunList();
79 const int iEvt = 1;
80 const int iRun = expRunList[0].second;
81 const int iExp = expRunList[0].first;
82 DBObjPtr<Belle2::HardwareClockSettings> clock_info("HardwareClockSettings");
83 updateDBObjPtrs(iEvt, iRun, iExp);
84 const double TICKS_TO_NS = 1.0 / (4.0 * EclConfiguration::getRF()) * 1e3;
85
86
87 //------------------------------------------------------------------------
88 /* Set up variables for storing timing information and cutting on
89 timing quality */
90
91 vector< vector<double> > allCrates_crate_times ;
92 vector< vector<double> > allCrates_run_nums ; // not an integer for plotting purposes
93 vector< vector<double> > allCrates_time_unc ;
94 vector< vector<double> > allCrates_crystalCrate_times ;
95 vector< vector<double> > allCrates_crystalCrate_times_unc ;
96
97 vector<int> allRunNums;
98
99 vector<double> mean_crystalCrate_time_ns(m_numCrates, 0);
100
101 vector< double > blank_vector = {} ;
102 for (int temp_crate_id = 0; temp_crate_id < m_numCrates; temp_crate_id++) {
103 allCrates_crate_times.push_back(blank_vector) ;
104 allCrates_run_nums.push_back(blank_vector) ;
105 allCrates_time_unc.push_back(blank_vector) ;
106 allCrates_crystalCrate_times.push_back(blank_vector) ;
107 allCrates_crystalCrate_times_unc.push_back(blank_vector) ;
108 }
109 // This results in : allCrates_crate_time[index for crate number][index for run number]
110
111
112
113 //------------------------------------------------------------------------
114 /* Extract the crystal and crate calibration constant information from the
115 tree as extracted by the collector. */
116
117 // Pulling in data from collector output. It now returns shared_ptr<T> so the underlying pointer
118 // will delete itself automatically at the end of this scope unless you do something
119 auto tree_perCrys = getObjectPtr<TTree>("tree_perCrystal");
120 if (!tree_perCrys) {
121 B2ERROR("Tree of calibration constants does not exist.");
122 return c_Failure;
123 }
124 B2INFO("Number of Entries in tree_perCrystal was " << tree_perCrys->GetEntries());
125 B2INFO("Number of Entries in tree_perCrystal / 8736 = " << float(tree_perCrys->GetEntries()) / ECLElementNumbers::c_NCrystals);
126
127
128 // Define the variables to be read in from the tree
129 tree_perCrys->SetBranchAddress("run", &m_run_perCrystal);
130 tree_perCrys->SetBranchAddress("exp", &m_exp_perCrystal);
131 tree_perCrys->SetBranchAddress("crystalID", &m_crystalID);
132 tree_perCrys->SetBranchAddress("crateID", &m_crateID);
133 tree_perCrys->SetBranchAddress("crateTimeConst", &m_crateTimeConst);
134 tree_perCrys->SetBranchAddress("crateTimeUnc", &m_crateTimeUnc);
135 tree_perCrys->SetBranchAddress("crystalTimeConst", &m_crystalTimeConst);
136 tree_perCrys->SetBranchAddress("crystalTimeUnc", &m_crystalTimeUnc);
137 tree_perCrys->SetBranchAddress("refCrystalID", &m_refCrystalID);
138
139
140 int referenceRunNum = -1;
141 int referenceExpNum = -1;
142 //int numAnalysedRuns = 0 ;
143 int previousRunNumTree = -1 ;
144 vector<double> Crate_time_ns_tree(m_numCrates) ;
145 vector<double> Crate_time_tick_tree(m_numCrates) ;
146 vector<double> Crate_time_unc_ns_tree(m_numCrates) ;
147 vector<double> crystalCrate_time_ns_tree(m_numCrates);
148 vector<double> crystalCrate_time_unc_ns_tree(m_numCrates);
149
150
151 Int_t numEntriesCrysTree = (Int_t)tree_perCrys->GetEntries();
152
153 // Loop through the entire tree
154 for (Int_t tree_crys_i = 0; tree_crys_i < numEntriesCrysTree; tree_crys_i++) {
155 for (Int_t tree_crys_j = 0; tree_crys_j < m_numCrystals; tree_crys_j++) {
156 tree_perCrys->GetEntry(tree_crys_i);
157 //B2INFO("tree_crys_i, tree_crys_j = " << tree_crys_i << ", " << tree_crys_j);
158 if (tree_crys_j != m_numCrystals - 1) {
159 tree_crys_i++;
160 }
161
162 // Make sure that all the information read in for 8736 crystals are all from one (exp,run).
163 if (tree_crys_j == 0) {
164 referenceExpNum = m_exp_perCrystal;
165 referenceRunNum = m_run_perCrystal;
166 B2INFO("Looking at exp,run " << m_exp_perCrystal << ", " << m_run_perCrystal);
167 }
168 if ((m_exp_perCrystal != referenceExpNum) or
169 (m_run_perCrystal != referenceRunNum) or
170 (m_run_perCrystal == previousRunNumTree)) {
171
172 B2ERROR("m_exp_perCrystal, referenceExpNum" << m_exp_perCrystal << ", " << referenceExpNum);
173 B2ERROR("m_run_perCrystal, referenceRunNum" << m_run_perCrystal << ", " << referenceRunNum);
174 B2ERROR("m_run_perCrystal, previousRunNumTree" << m_run_perCrystal << ", " << previousRunNumTree);
175 B2ERROR("Exp/run number problem");
176 return c_Failure;
177 }
178
179
180 int crateID_temp = m_crateID;
181 Crate_time_ns_tree[crateID_temp - 1] = m_crateTimeConst * TICKS_TO_NS ;
182 Crate_time_tick_tree[crateID_temp - 1] = m_crateTimeConst ;
183 Crate_time_unc_ns_tree[crateID_temp - 1] = m_crateTimeUnc * TICKS_TO_NS ;
184
186 B2INFO("exp, run, cell ID (0..8735), m_crateID, m_crateTimeConst = " << m_exp_perCrystal << ", " <<
187 m_run_perCrystal << ", " << tree_crys_j << ", " << m_crateID << ", " << m_crateTimeConst << " +/- " << m_crateTimeUnc << " ticks") ;
188 crystalCrate_time_ns_tree[crateID_temp - 1] = (m_crystalTimeConst + m_crateTimeConst) * TICKS_TO_NS;
189
190 crystalCrate_time_unc_ns_tree[crateID_temp - 1] = TICKS_TO_NS * sqrt(
193 } else if (tree_crys_j == 0 || tree_crys_j == 8735) {
194 B2INFO("m_exp_perCrystal, m_run_perCrystal, cell ID (0..8735), m_crateID, m_crateTimeConst = " << m_exp_perCrystal << ", " <<
195 m_run_perCrystal << ", " << tree_crys_j << ", " << m_crateID << ", " << m_crateTimeConst << " ns") ;
196 } else {
197 B2DEBUG(22, "m_exp_perCrystal, m_run_perCrystal, cell ID (0..8735), m_crateID, m_crateTimeConst = " << m_exp_perCrystal << ", " <<
198 m_run_perCrystal << ", " << tree_crys_j << ", " << m_crateID << ", " << m_crateTimeConst << " ns") ;
199 }
200
201 }
202
203 //------------------------------------------------------------------------
205
206 bool savedThisRunNum = false;
207 for (int iCrate = 0; iCrate < m_numCrates; iCrate++) {
208 double tcrate = Crate_time_ns_tree[iCrate] ;
209 double tcrate_unc = Crate_time_unc_ns_tree[iCrate];
210 if ((tcrate < m_tcrate_max_cut) &&
211 (tcrate > m_tcrate_min_cut) &&
212 (fabs(tcrate_unc) > m_tcrate_unc_min_cut) &&
213 (fabs(tcrate_unc) < m_tcrate_unc_max_cut)) {
214 double tcrystalCrate = crystalCrate_time_ns_tree[iCrate];
215 double tcrystalCrate_unc = crystalCrate_time_unc_ns_tree[iCrate];
216 allCrates_crate_times[iCrate].push_back(tcrate) ;
217 allCrates_run_nums[iCrate].push_back(m_run_perCrystal) ;
218 allCrates_time_unc[iCrate].push_back(tcrate_unc) ;
219 allCrates_crystalCrate_times[iCrate].push_back(tcrystalCrate) ;
220 allCrates_crystalCrate_times_unc[iCrate].push_back(tcrystalCrate_unc) ;
221
222 mean_crystalCrate_time_ns[iCrate] += tcrystalCrate ;
223
224 if (!savedThisRunNum) {
225 allRunNums.push_back(m_run_perCrystal);
226 savedThisRunNum = true;
227 }
228 }
229 }
230
231 //------------------------------------------------------------------------
233 for (int ic = 0; ic < m_numCrates; ic++) {
234 B2INFO("Crate " << ic + 1 << ", t_crate = " << Crate_time_tick_tree[ic] << " ticks = "
235 << Crate_time_ns_tree[ic] << " +- " << Crate_time_unc_ns_tree[ic]
236 << " ns; t crys+crate (no shifts) = " << crystalCrate_time_ns_tree[ic] << " +- "
237 << crystalCrate_time_unc_ns_tree[ic] << " ns") ;
238 }
239
240 previousRunNumTree = m_run_perCrystal;
241
242 }
243
244
245 B2INFO("Finished reading tree calibration constants. Now extracting here by stepping through runs.");
246
247
248
249
250
251 //------------------------------------------------------------------------
253
254
255 bool minRunNumBool = false;
256 bool maxRunNumBool = false;
257 int minRunNum = -1;
258 int maxRunNum = -1;
259 int minExpNum = -1;
260 int maxExpNum = -1;
261 for (auto expRun : getRunList()) {
262 int expNumber = expRun.first;
263 int runNumber = expRun.second;
264 if (!minRunNumBool) {
265 minExpNum = expNumber;
266 minRunNum = runNumber;
267 minRunNumBool = true;
268 }
269 if (!maxRunNumBool) {
270 maxExpNum = expNumber;
271 maxRunNum = runNumber;
272 maxRunNumBool = true;
273 }
274 if (((minRunNum > runNumber) && (minExpNum >= expNumber)) ||
275 (minExpNum > expNumber)) {
276 minExpNum = expNumber;
277 minRunNum = runNumber;
278 }
279 if (((maxRunNum < runNumber) && (maxExpNum <= expNumber)) ||
280 (maxExpNum < expNumber)) {
281 maxExpNum = expNumber;
282 maxRunNum = runNumber;
283 }
284 }
285
286 B2INFO("minExpNum = " << minExpNum) ;
287 B2INFO("minRunNum = " << minRunNum) ;
288 B2INFO("maxExpNum = " << maxExpNum) ;
289 B2INFO("maxRunNum = " << maxRunNum) ;
290
291
292 if (minExpNum != maxExpNum) {
293 B2ERROR("The runs must all come from the same experiment");
294 return c_Failure;
295 }
296
297 int experiment = minExpNum;
298
299
300 //------------------------------------------------------------------------
301 //------------------------------------------------------------------------
302 //------------------------------------------------------------------------
303 //------------------------------------------------------------------------
304 /* Extract out the time offset information from the database directly.
305 This method loops over all run numbers so it can more easily pick up
306 old payloads. It is not the preferred method to use if the payloads
307 have iov gaps.*/
308
310 //------------------------------------------------------------------------
311 // Get the input run list (should be only 1) for us to use to update the DBObjectPtrs
312 auto runs = getRunList();
313 /* Take the first run. For the crystal cosmic calibrations, because of the crate
314 calibrations, there is not a known correct run to use within the range. */
315 ExpRun chosenRun = runs.front();
316 B2INFO("merging using the ExpRun (" << chosenRun.second << "," << chosenRun.first << ")");
317 // After here your DBObjPtrs are correct
318 updateDBObjPtrs(1, chosenRun.second, chosenRun.first);
319
320 //------------------------------------------------------------------------
321 // Test the DBObjects we want to exist and fail if not all of them do.
322 bool allObjectsFound = true;
323
325 // Check that the payloads we want to merge are sufficiently loaded
327 allObjectsFound = false;
328 B2ERROR("No valid DBObject found for 'ECLCrystalTimeOffset'");
329 }
330
331 // Check that the crate payload is loaded (used for transforming cosmic payload)
333 allObjectsFound = false;
334 B2ERROR("No valid DBObject found for 'ECLCrateTimeOffset'");
335 }
336
338 allObjectsFound = false;
339 B2ERROR("No valid DBObject found for 'refCrysIDzeroingCrate'");
340 }
341
342
343 if (allObjectsFound) {
344 B2INFO("Valid objects found for 'ECLCrystalTimeOffset'");
345 B2INFO("Valid object found for 'ECLCrateTimeOffset'");
346 B2INFO("Valid object found for 'refCrysIDzeroingCrate'");
347 } else {
348 B2INFO("eclTimeShiftsAlgorithm: Exiting with failure. Some missing valid objects.");
349 return c_Failure;
350 }
351
352
353 //------------------------------------------------------------------------
355 vector<float> crystalCalib = m_ECLCrystalTimeOffset->getCalibVector();
356 B2INFO("Loaded 'ECLCrystalTimeOffset' calibrations");
357
358 vector<float> crateCalib = m_ECLCrateTimeOffset->getCalibVector();
359
360 B2INFO("Loaded 'ECLCrateTimeOffset' calibration with default exp/run");
361
362 B2INFO("eclTimeShiftsAlgorithm:: loaded ECLCrateTimeOffset from the database"
363 << LogVar("IoV", m_ECLCrateTimeOffset.getIoV())
364 << LogVar("Checksum", m_ECLCrateTimeOffset.getChecksum()));
365
366 for (int cellID = 1; cellID <= m_numCrystals; cellID += 511) {
367 B2INFO("crystalCalib = " << crystalCalib[cellID - 1]);
368 B2INFO("crateCalib = " << crateCalib[cellID - 1]);
369 }
370
371 vector<short> refCrystals = m_refCrysIDzeroingCrate->getReferenceCrystals();
372 for (int icrate = 0; icrate < m_numCrates; icrate++) {
373 B2INFO("reference crystal for crate " << icrate + 1 << " = " << refCrystals[icrate]);
374 }
375
376
377
378 //------------------------------------------------------------------------
380 for (int run = minRunNum; run <= maxRunNum; run++) {
381 B2INFO("---------") ;
382 B2INFO("Looking at run " << run) ;
383
384 vector<int>::iterator it = find(allRunNums.begin(), allRunNums.end(), run);
385 if (it != allRunNums.end()) {
386 int pos = it - allRunNums.begin() ;
387 B2INFO("allRunNums[" << pos << "] = " << allRunNums[pos]);
388 B2INFO("Run " << run << " already processed so skipping it.");
389 continue;
390 } else {
391 B2INFO("New run. Starting to extract information");
392 }
393
394 // Forloading database for a specific run
395 int eventNumberForCrates = 1;
396
398 // simulate the initialize() phase where we can register objects in the DataStore
400 evtPtr.registerInDataStore();
402 // now construct the event metadata
403 evtPtr.construct(eventNumberForCrates, run, experiment);
404 // and update the database contents
405 DBStore& dbstore = DBStore::Instance();
406 dbstore.update();
407 // this is only needed it the payload might be intra-run dependent,
408 // that is if it might change during one run as well
409 dbstore.updateEvent();
410 updateDBObjPtrs(eventNumberForCrates, run, experiment);
411
412
413 //------------------------------------------------------------------------
415 shared_ptr< ECL::ECLChannelMapper > crystalMapper(new ECL::ECLChannelMapper()) ;
416 crystalMapper->initFromDB();
417
419 B2INFO("eclTimeShiftsAlgorithm:: loaded ECLCrystalTimeOffset from the database"
420 << LogVar("IoV", m_ECLCrystalTimeOffset.getIoV())
421 << LogVar("Checksum", m_ECLCrystalTimeOffset.getChecksum()));
422 B2INFO("eclTimeShiftsAlgorithm:: loaded ECLCrateTimeOffset from the database"
423 << LogVar("IoV", m_ECLCrateTimeOffset.getIoV())
424 << LogVar("Checksum", m_ECLCrateTimeOffset.getChecksum()));
425
426
427 //------------------------------------------------------------------------
429
430 vector<float> crystalTimeOffsetsCalib;
431 vector<float> crystalTimeOffsetsCalibUnc;
432 crystalTimeOffsetsCalib = m_ECLCrystalTimeOffset->getCalibVector();
433 crystalTimeOffsetsCalibUnc = m_ECLCrystalTimeOffset->getCalibUncVector();
434
435 vector<float> crateTimeOffsetsCalib;
436 vector<float> crateTimeOffsetsCalibUnc;
437 crateTimeOffsetsCalib = m_ECLCrateTimeOffset->getCalibVector();
438 crateTimeOffsetsCalibUnc = m_ECLCrateTimeOffset->getCalibUncVector();
439
440 //------------------------------------------------------------------------
444 vector<double> Crate_time_ns(m_numCrates) ;
445 vector<double> Crate_time_tick(m_numCrates) ;
446 vector<double> Crate_time_unc_ns(m_numCrates) ;
447 vector<double> crystalCrate_time_ns(m_numCrates);
448 vector<double> crystalCrate_time_unc_ns(m_numCrates);
449
450 for (int crysID = 1; crysID <= m_numCrystals; crysID++) {
451 int crateID_temp = crystalMapper->getCrateID(crysID) ;
452 Crate_time_ns[crateID_temp - 1] = crateTimeOffsetsCalib[crysID - 1] * TICKS_TO_NS ;
453 Crate_time_tick[crateID_temp - 1] = crateTimeOffsetsCalib[crysID - 1] ;
454 Crate_time_unc_ns[crateID_temp - 1] = crateTimeOffsetsCalibUnc[crysID - 1] * TICKS_TO_NS ;
455
456 if (crysID == refCrystals[crateID_temp - 1]) {
457 crystalCrate_time_ns[crateID_temp - 1] = (crystalTimeOffsetsCalib[crysID - 1] +
458 crateTimeOffsetsCalib[crysID - 1]) * TICKS_TO_NS;
459
460 crystalCrate_time_unc_ns[crateID_temp - 1] = TICKS_TO_NS * sqrt(
461 (crateTimeOffsetsCalibUnc[crysID - 1] * crateTimeOffsetsCalibUnc[crysID - 1]) +
462 (crystalTimeOffsetsCalibUnc[crysID - 1] * crystalTimeOffsetsCalibUnc[crysID - 1])) ;
463 }
464 }
465
466
467 for (int iCrate = 0; iCrate < m_numCrates; iCrate++) {
468 double tcrate = Crate_time_ns[iCrate] ;
469 double tcrate_unc = Crate_time_unc_ns[iCrate];
470 if ((tcrate < m_tcrate_max_cut) &&
471 (tcrate > m_tcrate_min_cut) &&
472 (fabs(tcrate_unc) > m_tcrate_unc_min_cut) &&
473 (fabs(tcrate_unc) < m_tcrate_unc_max_cut)) {
474 double tcrystalCrate = crystalCrate_time_ns[iCrate];
475 double tcrystalCrate_unc = crystalCrate_time_unc_ns[iCrate];
476 allCrates_crate_times[iCrate].push_back(tcrate) ;
477 allCrates_run_nums[iCrate].push_back(run) ;
478 allCrates_time_unc[iCrate].push_back(tcrate_unc) ;
479 allCrates_crystalCrate_times[iCrate].push_back(tcrystalCrate) ;
480 allCrates_crystalCrate_times_unc[iCrate].push_back(tcrystalCrate_unc) ;
481
482 mean_crystalCrate_time_ns[iCrate] += tcrystalCrate ;
483 }
484 }
485
486
487 //------------------------------------------------------------------------
489 for (int ic = 0; ic < m_numCrates; ic++) {
490 B2INFO("Crate " << ic + 1 << ", t_crate = " << Crate_time_tick[ic] << " ticks = "
491 << Crate_time_ns[ic] << " +- " << Crate_time_unc_ns[ic]
492 << " ns; t crys+crate (no shift) = " << crystalCrate_time_ns[ic] << " +- "
493 << crystalCrate_time_unc_ns[ic] << " ns") ;
494 }
495
496 /* Shift the run number to the end of the iov so that we can skip runs
497 that have the payload with the same revision number */
498 int IOV_exp_high = m_ECLCrateTimeOffset.getIoV().getExperimentHigh() ;
499 int IOV_run_high = m_ECLCrateTimeOffset.getIoV().getRunHigh() ;
500 B2INFO(LogVar("IOV_exp_high", IOV_exp_high));
501 B2INFO(LogVar("IOV_run_high", IOV_run_high));
502 if (IOV_run_high == -1) {
503 B2INFO("IOV_run_high is -1 so stop looping over all runs");
504 break;
505 } else {
506 B2INFO("Set run number to higher iov run number");
507 run = IOV_run_high;
508 }
509 B2INFO("now set run = " << run);
510 }
511 }
512
513
514
515
516 //------------------------------------------------------------------------
517 //------------------------------------------------------------------------
518 //------------------------------------------------------------------------
519 //------------------------------------------------------------------------
522 B2INFO("Shift all run crys+crate+off times. Show the results for a subset of crates/runs:");
523 for (int iCrate = 0; iCrate < m_numCrates; iCrate++) {
524 double mean_time = mean_crystalCrate_time_ns[iCrate] / allCrates_crate_times[iCrate].size() ;
525 B2INFO("Mean crys+crate times for all runs used as offset (crate " << iCrate + 1 << ") = " << mean_time);
526
527 for (long unsigned int jRun = 0; jRun < allCrates_crate_times[iCrate].size(); jRun++) {
528 allCrates_crystalCrate_times[iCrate][jRun] += -mean_time + timeShiftForPlotStyle[iCrate] ;
529 if (jRun < 50 || iCrate == 1 || iCrate == 40 || iCrate == 51) {
530 B2INFO("allCrates_crystalCrate_times(crate " << iCrate + 1 << ", run counter " << jRun + 1 << ", runNum " <<
531 allCrates_run_nums[iCrate][jRun] << " | after shifting mean) = " <<
532 allCrates_crystalCrate_times[iCrate][jRun]);
533 }
534 }
535 }
536
537
538
539 //------------------------------------------------------------------------
540 //------------------------------------------------------------------------
543 TFile* tcratefile = 0;
544
545 B2INFO("Debug output rootfile: " << debugFilenameBase);
546 string runNumsString = string("_") + to_string(minExpNum) + "_" + to_string(minRunNum) + string("-") +
547 to_string(maxExpNum) + "_" + to_string(maxRunNum);
548 string debugFilename = debugFilenameBase + runNumsString + string(".root");
549 TString fname = debugFilename;
550
551 tcratefile = new TFile(fname, "recreate");
552 tcratefile->cd();
553 B2INFO("Debugging histograms written to " << fname);
554
555 for (int i = 0; i < m_numCrates; i++) {
556 B2INFO("Starting to make crate time jump plots for crate " << i + 1);
557 shared_ptr< TCanvas > cSmart(new TCanvas);
558
559 Double_t* single_crate_crate_times = &allCrates_crate_times[i][0] ;
560 Double_t* single_crate_run_nums = &allCrates_run_nums[i][0] ;
561 Double_t* single_crate_time_unc = &allCrates_time_unc[i][0] ;
562 Double_t* single_crate_crystalCrate_times = &allCrates_crystalCrate_times[i][0] ;
563 Double_t* single_crate_crystalCrate_times_unc = &allCrates_crystalCrate_times_unc[i][0] ;
564 B2INFO("Done setting up the arrays for the crate " << i + 1);
565
566 ostringstream ss;
567 ss << setw(2) << setfill('0') << i + 1 ;
568 string paddedCrateID(ss.str());
569
570 // ----- crate time constants vs run number ------
571 shared_ptr< TGraphErrors > g_tcrate_vs_runNum(new TGraphErrors(allCrates_crate_times[i].size(), single_crate_run_nums,
572 single_crate_crate_times, NULL, single_crate_time_unc)) ;
573 // NULL for run number errors = 0 for all
574
575 string tgraph_title = string("e") + to_string(minExpNum) + string("r") + to_string(minRunNum) +
576 string("-e") + to_string(maxExpNum) + string("r") + to_string(maxRunNum) ;
577
578 string tgraph_name_short = "crateTimeVSrunNum_" ;
579 tgraph_name_short = tgraph_name_short + runNumsString + "_crate";
580
581 tgraph_title = tgraph_title + string("_crate") + paddedCrateID ;
582 tgraph_name_short = tgraph_name_short + paddedCrateID ;
583 tgraph_title = tgraph_title + string(" (") + to_string(m_tcrate_min_cut) + string(" < tcrate < ") +
584 to_string(m_tcrate_max_cut) + string(" ns, ") + to_string(m_tcrate_unc_min_cut) +
585 string(" < tcrate unc. < ") + to_string(m_tcrate_unc_max_cut) + string(" ns cuts)") ;
586
587 g_tcrate_vs_runNum->SetName(tgraph_name_short.c_str()) ;
588 g_tcrate_vs_runNum->SetTitle(tgraph_title.c_str()) ;
589 g_tcrate_vs_runNum->GetXaxis()->SetTitle("Run number") ;
590 g_tcrate_vs_runNum->GetYaxis()->SetTitle("Crate time [ns]") ;
591
592 g_tcrate_vs_runNum->GetYaxis()->SetRangeUser(m_tcrate_min_cut, m_tcrate_max_cut) ;
593
594 g_tcrate_vs_runNum->Draw("AP") ;
595 g_tcrate_vs_runNum->SetMarkerSize(0.8) ;
596 g_tcrate_vs_runNum->Draw("AP") ;
597
598 shared_ptr< TLatex > Leg1(new TLatex);
599 Leg1->SetNDC();
600 Leg1->SetTextAlign(11);
601 Leg1->SetTextFont(42);
602 Leg1->SetTextSize(0.035);
603 Leg1->SetTextColor(1);
604 Leg1->AppendPad();
605
606 g_tcrate_vs_runNum->Write() ;
607 cSmart->SaveAs((tgraph_name_short + string(".pdf")).c_str()) ;
608
609 B2INFO("Saved pdf: " << tgraph_name_short << ".pdf");
610
611
612 // ----- crystal + crate time constants + offset vs run number ------
613 shared_ptr< TGraphErrors > g_crateCrystalTime_vs_runNum(new TGraphErrors(allCrates_crystalCrate_times[i].size(),
614 single_crate_run_nums,
615 single_crate_crystalCrate_times, NULL, single_crate_crystalCrate_times_unc)) ;
616
617 tgraph_title = string("e") + to_string(minExpNum) + string("r") + to_string(minRunNum) +
618 string("-e") + to_string(maxExpNum) + string("r") + to_string(maxRunNum) ;
619
620 tgraph_name_short = "crystalCrateTimeVSrunNum_" ;
621 tgraph_name_short = tgraph_name_short + runNumsString + "_crate";
622
623 tgraph_title = tgraph_title + string("_crate") + paddedCrateID ;
624 tgraph_name_short = tgraph_name_short + paddedCrateID ;
625 tgraph_title = tgraph_title + string(" (") + to_string(m_tcrate_min_cut) + string(" < tcrate < ") +
626 to_string(m_tcrate_max_cut) + string(" ns, ") + to_string(m_tcrate_unc_min_cut) +
627 string(" < tcrate unc. < ") + to_string(m_tcrate_unc_max_cut) + string(" ns cuts)") ;
628
629
630 g_crateCrystalTime_vs_runNum->SetName(tgraph_name_short.c_str()) ;
631 g_crateCrystalTime_vs_runNum->SetTitle(tgraph_title.c_str()) ;
632 g_crateCrystalTime_vs_runNum->GetXaxis()->SetTitle("Run number") ;
633 g_crateCrystalTime_vs_runNum->GetYaxis()->SetTitle("Crate time + Crystal time + centring overall offset [ns]") ;
634
635 g_crateCrystalTime_vs_runNum->GetYaxis()->SetRangeUser(crysCrateShift_min, crysCrateShift_max) ;
636
637 g_crateCrystalTime_vs_runNum->Draw("AP") ;
638 g_crateCrystalTime_vs_runNum->SetMarkerSize(0.8) ;
639 g_crateCrystalTime_vs_runNum->Draw("AP") ;
640
641 g_crateCrystalTime_vs_runNum->Write() ;
642 cSmart->SaveAs((tgraph_name_short + string(".pdf")).c_str()) ;
643
644 B2INFO("Saved pdf: " << tgraph_name_short << ".pdf");
645
646 // ----- crystal + crate time constants + offset vs run counter------
647 // This will remove gaps and ignore the actual run number
648
649 /* Define a vector to store a renumbering of the run numbers, incrementing
650 by +1 so that there are no gaps. The runs are not in order so the
651 run numbers&indices first have to be sorted before the "run counter"
652 numbers can used.*/
653 int numRunsWithCrateTimes = allCrates_crystalCrate_times[i].size();
654 vector<Double_t> counterVec(numRunsWithCrateTimes);
655
656
657 // Vector to store element
658 // with respective present index
659 vector<pair<int, double> > runNum_index_pairs;
660
661 // Inserting element in pair vector
662 // to keep track of previous indexes
663 for (int pairIndex = 0; pairIndex < numRunsWithCrateTimes; pairIndex++) {
664 runNum_index_pairs.push_back(make_pair(allCrates_run_nums[i][pairIndex], pairIndex));
665 }
666
667 B2INFO("Crate id = " << i + 1);
668 B2INFO("Unsorted run numbers");
669 for (int runCounter = 0; runCounter < numRunsWithCrateTimes; runCounter++) {
670 B2INFO("Run number, run number vector index = " << runNum_index_pairs[runCounter].first << ", " <<
671 runNum_index_pairs[runCounter].second);
672 }
673
674 // Sorting pair vector
675 sort(runNum_index_pairs.begin(), runNum_index_pairs.end());
676
677 // Fill the run counter vector
678 for (int runCounter = 0; runCounter < numRunsWithCrateTimes; runCounter++) {
679 counterVec[runNum_index_pairs[runCounter].second] = runCounter + 1;
680 }
681
682 B2INFO("Run numbers with index and times");
683 for (int runCounter = 0; runCounter < numRunsWithCrateTimes; runCounter++) {
684 int idx = (int) round(counterVec[runCounter]);
685 B2INFO("Vector index, Run number, run number sorting order index, tcrystal+tcrate+shifts = " << runCounter << ", " <<
686 allCrates_run_nums[i][runCounter] << ", " << idx << ", " << single_crate_crystalCrate_times[idx - 1] << " ns");
687 }
688
689
690 if (numRunsWithCrateTimes > 0) {
691 shared_ptr< TGraphErrors > g_crateCrystalTime_vs_runCounter(new TGraphErrors(numRunsWithCrateTimes, &counterVec[0],
692 single_crate_crystalCrate_times, NULL, single_crate_crystalCrate_times_unc)) ;
693
694 tgraph_title = string("e") + to_string(minExpNum) + string("r") + to_string(minRunNum) +
695 string("-e") + to_string(maxExpNum) + string("r") + to_string(maxRunNum) ;
696
697
698 tgraph_name_short = "crystalCrateTimeVSrunCounter_" ;
699 tgraph_name_short = tgraph_name_short + runNumsString + "_crate";
700
701
702 tgraph_title = tgraph_title + string("_crate") + paddedCrateID ;
703 tgraph_name_short = tgraph_name_short + paddedCrateID ;
704 tgraph_title = tgraph_title + string(" (") + to_string(m_tcrate_min_cut) + string(" < tcrate < ") +
705 to_string(m_tcrate_max_cut) + string(" ns, ") + to_string(m_tcrate_unc_min_cut) +
706 string(" < tcrate unc. < ") + to_string(m_tcrate_unc_max_cut) + string(" ns cuts)") ;
707
708
709 g_crateCrystalTime_vs_runCounter->SetName(tgraph_name_short.c_str()) ;
710 g_crateCrystalTime_vs_runCounter->SetTitle(tgraph_title.c_str()) ;
711 g_crateCrystalTime_vs_runCounter->GetXaxis()->SetTitle("Run counter (remove gaps from run numbers)") ;
712 g_crateCrystalTime_vs_runCounter->GetYaxis()->SetTitle("Crate time + Crystal time + centring overall offset [ns]") ;
713
714 g_crateCrystalTime_vs_runCounter->GetYaxis()->SetRangeUser(crysCrateShift_min, crysCrateShift_max) ;
715 g_crateCrystalTime_vs_runCounter->GetXaxis()->SetRangeUser(0, numRunsWithCrateTimes + 1) ;
716
717 g_crateCrystalTime_vs_runCounter->Draw("AP") ;
718 g_crateCrystalTime_vs_runCounter->SetMarkerSize(0.8) ;
719 g_crateCrystalTime_vs_runCounter->Draw("AP") ;
720
721 g_crateCrystalTime_vs_runCounter->Write() ;
722 cSmart->SaveAs((tgraph_name_short + string(".pdf")).c_str()) ;
723 B2INFO("Saved pdf: " << tgraph_name_short << ".pdf");
724
725 B2INFO("Finished making crate time jump plots for crate " << i + 1);
726 } else {
727 B2INFO("Crate " << i + 1 << " has no entries that pass all the cuts so no crystalCrateTimeVSrunCounter_crate plot will be made.");
728 }
729 }
730
731
732
733
734 /* Loop over all the runs and crates and let the user know when a crate time jump
735 has occurred. Jumps can be of various sizes so have different thresholds. */
736 double smallThreshold = 1 ; //ns
737 double largeThreshold = 6.5 ; //ns
738
739 B2INFO("======================= Crate time jumps =========================");
740 B2INFO("======================= Small threshold jumps ====================");
741 B2INFO("Crate ID = 1..52");
742 B2INFO("==================================================================");
743
744 for (int i = 0; i < m_numCrates; i++) {
745 int numRunsWithCrateTimes = allCrates_crystalCrate_times[i].size();
746 for (int runCounter = 0; runCounter < numRunsWithCrateTimes - 1; runCounter++) {
747 int run_i = allCrates_run_nums[i][runCounter] ;
748 int run_f = allCrates_run_nums[i][runCounter + 1] ;
749 double time_i = allCrates_crystalCrate_times[i][runCounter] ;
750 double time_f = allCrates_crystalCrate_times[i][runCounter + 1] ;
751
752 if (fabs(time_f - time_i) > smallThreshold) {
753 B2INFO("Crate " << i + 1 << " has crate time jump > " << smallThreshold << " ns: t(run " << run_f << ") = " << time_f <<
754 " ns - t(run " << run_i << ") = " << time_i << " ns = " << time_f - time_i);
755 }
756 }
757 }
758
759
760 B2INFO("~~~~~~~~~~~~~~~~~~~~~~~ Large threshold jumps ~~~~~~~~~~~~~~~~~~~~");
761 B2INFO("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
762
763 for (int i = 0; i < m_numCrates; i++) {
764 int numRunsWithCrateTimes = allCrates_crystalCrate_times[i].size();
765 for (int runCounter = 0; runCounter < numRunsWithCrateTimes - 1; runCounter++) {
766 int run_i = allCrates_run_nums[i][runCounter] ;
767 int run_f = allCrates_run_nums[i][runCounter + 1] ;
768 double time_i = allCrates_crystalCrate_times[i][runCounter] ;
769 double time_f = allCrates_crystalCrate_times[i][runCounter + 1] ;
770
771 if (fabs(time_f - time_i) > largeThreshold) {
772 B2INFO("WARNING: Crate " << i + 1 << " has crate time jump > " << largeThreshold << " ns: t(run " << run_f << ") = " << time_f <<
773 " ns - t(run " << run_i << ") = " << time_i << " ns = " << time_f - time_i);
774 }
775 }
776 }
777
778
779
780
781 // Just in case, we remember the current TDirectory so we can return to it
782 TDirectory* executeDir = gDirectory;
783
784 tcratefile->Write();
785 tcratefile->Close();
786 // Go back to original TDirectory
787 executeDir->cd();
788
789 return c_OK;
790}
static void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
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
This class provides access to ECL channel map that is either a) Loaded from the database (see ecl/dbo...
static double getRF()
See m_rf.
Double_t m_crateTimeConst
Crate time calibration constant.
double m_tcrate_unc_min_cut
Minimum value cut for the crate time calibration constant uncertainty for plotting.
bool algorithmReadPayloads
Whether or not to have the algorithm code to loop over all the runs and read the payloads itself.
const int m_numCrates
Number of Crates expected.
double m_tcrate_max_cut
Maximum value cut for the crate time calibration constant for plotting.
double m_tcrate_min_cut
Minimum value cut for the crate time calibration constant for plotting.
const int m_numCrystals
Number of Crystals expected.
Double_t m_crystalTimeUnc
Uncertainty on the crystal time calibration constant.
Double_t m_crateTimeUnc
Uncertainty on the crate time calibration constant.
DBObjPtr< ECLReferenceCrystalPerCrateCalib > m_refCrysIDzeroingCrate
payload that we want to read from the DB
double m_tcrate_unc_max_cut
Maximum value cut for the crate time calibration constant uncertainty for plotting.
DBObjPtr< ECLCrystalCalib > m_ECLCrateTimeOffset
ECLCrateTimeOffset payload that we want to read from the DB.
Double_t m_crystalTimeConst
Crystal time calibration constant.
Int_t m_refCrystalID
Crystal ID number for the reference crystal.
EResult calibrate() override
..Run algorithm
double crysCrateShift_max
Plotting time max for crystal+crate shift plots.
double crysCrateShift_min
Plotting time min for crystal+crate shift plots.
std::string debugFilenameBase
Name of file with debug output, eclTimeShiftsAlgorithm.root by default.
DBObjPtr< ECLCrystalCalib > m_ECLCrystalTimeOffset
ECLCrystalTimeOffset payload that we want to read from the DB.
double timeShiftForPlotStyle[52]
List of time offsets, one per crate, used just to centre the time constants around zero.
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 construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
Class to store variables with their name which were sent to the logging service.
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
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.
STL namespace.
Struct containing exp number and run number.
Definition Splitter.h:51