Run algorithm on data.
1119{
1120 int channelId;
1121 gROOT->SetBatch(kTRUE);
1127
1128 fcn_gaus =
new TF1(
"fcn_gaus",
"gaus");
1129 fcn_land =
new TF1(
"fcn_land",
"landau");
1130 fcn_pol1 =
new TF1(
"fcn_pol1",
"pol1");
1131 fcn_const =
new TF1(
"fcn_const",
"pol0");
1132
1133
1136 return result;
1137
1138
1139 std::string name = "time_calibration.root";
1140 int i = 1;
1141 while (1) {
1142 struct stat buffer;
1143 if (stat(name.c_str(), &buffer) != 0)
1144 break;
1145 name = "time_calibration_" + std::to_string(i) + ".root";
1146 i = i + 1;
1147 if (i < 0)
1148 break;
1149 }
1150 m_outFile =
new TFile(name.c_str(),
"recreate");
1152
1153 std::vector<struct Event> eventsChannel;
1154 eventsChannel.clear();
1157
1158 B2INFO("Counting events per channel...");
1159 std::map<KLMChannelNumber, unsigned int> eventCounts;
1161
1162
1163 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsBKLM;
1164 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsEKLM;
1165 KLMChannelIndex klmChannels;
1166
1167 for (KLMChannelIndex& klmChannel : klmChannels) {
1169 m_cFlag[channel] = ChannelCalibrationStatus::c_NotEnoughData;
1170
1171 if (eventCounts.find(channel) == eventCounts.end())
1172 continue;
1173
1174 int nEvents = eventCounts[channel];
1176 B2WARNING("Not enough calibration data collected."
1177 << LogVar("channel", channel)
1178 << LogVar("number of digit", nEvents));
1179 continue;
1180 }
1181
1182 m_cFlag[channel] = ChannelCalibrationStatus::c_FailedFit;
1183
1186 channelsBKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1187 }
1189 channelsEKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1190 }
1191 }
1192
1193 std::sort(channelsBKLM.begin(), channelsBKLM.end(), compareEventNumber);
1194 std::sort(channelsEKLM.begin(), channelsEKLM.end(), compareEventNumber);
1195
1196
1197 double delayBKLM, delayBKLMError;
1198 double delayEKLM, delayEKLMError;
1199
1200
1205
1206 B2INFO("2D fits complete, data cleared.");
1207
1208
1209 auto isRPCBackward = [](const KLMChannelIndex & ch) {
1213 };
1214
1215 auto isRPCForward = [](const KLMChannelIndex & ch) {
1219 };
1220
1221 auto isBKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1225 };
1226
1227 auto isBKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1231 };
1232
1233 auto isEKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1236 };
1237
1238 auto isEKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1241 };
1242
1243 std::vector<std::pair<std::string, std::function<bool(const KLMChannelIndex&)>>> batches = {
1244 {"RPC Backward", isRPCBackward},
1245 {"RPC Forward", isRPCForward},
1246 {"BKLM Scintillator Backward", isBKLMScintillatorBackward},
1247 {"BKLM Scintillator Forward", isBKLMScintillatorForward},
1248 {"EKLM Scintillator Backward", isEKLMScintillatorBackward},
1249 {"EKLM Scintillator Forward", isEKLMScintillatorForward}
1250 };
1251
1252
1253
1254
1255
1256 B2INFO("First loop: Computing global statistics (batched processing)...");
1257
1258 TString iFstring[2] = {"Backward", "Forward"};
1259 TString iPstring[2] = {"ZReadout", "PhiReadout"};
1260 int nBin = 80;
1261 int nBin_scint = 80;
1262
1263 for (const auto& batch : batches) {
1264 B2INFO("Processing batch for global stats: " << batch.first);
1266
1268 channelId = klmChannel.getKLMChannelNumber();
1269
1270 if (!batch.second(klmChannel))
1271 continue;
1272
1273 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1274 continue;
1275
1277 continue;
1278
1279 eventsChannel =
m_evts[channelId];
1280 int iSub = klmChannel.getSubdetector();
1282
1283
1284 for (
const Event& event : eventsChannel) {
1285
1287 continue;
1288
1289 XYZVector diffD = XYZVector(event.diffDistX, event.diffDistY, event.diffDistZ);
1291
1292 double timeHit = event.time();
1294 timeHit = timeHit - event.t0;
1295
1296 if (timeHit <= -400e3)
1297 continue;
1298
1300
1303 } else {
1305 }
1306 } else {
1308 }
1309 }
1310 }
1311
1313 B2INFO("Batch processed and cleared: " << batch.first);
1314 }
1315
1316
1321
1322 B2INFO("Global Mean for Raw." << LogVar("RPC", tmpMean_rpc_global)
1323 << LogVar("Scint BKLM", tmpMean_scint_global)
1324 << LogVar("Scint EKLM", tmpMean_scint_global_end));
1325
1326
1327
1328
1329
1330 B2INFO("Second pass: Computing per-channel time shifts (batched processing)...");
1331
1332 for (const auto& batch : batches) {
1333 B2INFO("Processing batch for time shifts: " << batch.first);
1335
1337 channelId = klmChannel.getKLMChannelNumber();
1338
1339 if (!batch.second(klmChannel))
1340 continue;
1341
1342 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1343 continue;
1344
1346 continue;
1347
1348 eventsChannel =
m_evts[channelId];
1349 int iSub = klmChannel.getSubdetector();
1350 int iF, iS, iL, iP, iC;
1351
1353 iF = klmChannel.getSection();
1354 iS = klmChannel.getSector() - 1;
1355 iL = klmChannel.getLayer() - 1;
1356 iP = klmChannel.getPlane();
1357 iC = klmChannel.getStrip() - 1;
1358 } else {
1359 iF = klmChannel.getSection() - 1;
1360 iS = klmChannel.getSector() - 1;
1361 iL = klmChannel.getLayer() - 1;
1362 iP = klmChannel.getPlane() - 1;
1363 iC = klmChannel.getStrip() - 1;
1364 }
1365
1366
1367 TString hn, ht;
1368 TH1F* h_temp_tc = nullptr;
1369
1371
1373 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1374 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1375 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1377 } else {
1378 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1379 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1380 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1383 }
1384 } else {
1385 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc_end", iF, iS, iL, iP, iC);
1386 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1387 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1390 }
1391
1392 for (
const Event& event : eventsChannel) {
1393
1395 continue;
1396
1397 double timeHit = event.time();
1399 timeHit = timeHit - event.t0;
1400 if (timeHit <= -400e3)
1401 continue;
1402 h_temp_tc->Fill(timeHit);
1403 }
1404
1406 double tmpMean_channel =
fcn_gaus->GetParameter(1);
1407
1409
1411 m_timeShift[channelId] = tmpMean_channel - tmpMean_rpc_global;
1412 } else {
1413 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global;
1414 }
1415 } else {
1416 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global_end;
1417 }
1418
1419 delete h_temp_tc;
1420 }
1421
1423 B2INFO("Batch processed and cleared: " << batch.first);
1424 }
1425
1429 B2INFO("Effective Light m_timeShift obtained.");
1430
1431
1436
1437 B2INFO("Effective light speed fitting.");
1438
1439
1441 double fittedDelayRPCPhi =
fcn_pol1->GetParameter(1);
1442 double e_slope_rpc_phi =
fcn_pol1->GetParError(1);
1443
1445 double fittedDelayRPCZ =
fcn_pol1->GetParameter(1);
1446 double e_slope_rpc_z =
fcn_pol1->GetParError(1);
1447
1448
1449 double delayRPCPhi, delayRPCZ;
1453 B2INFO(
"Using fixed RPC propagation delay: " <<
m_fixedRPCDelay <<
" ns/cm (c_eff = 0.5c)"
1454 << LogVar("Fitted phi (not used)", fittedDelayRPCPhi)
1455 << LogVar("Fitted Z (not used)", fittedDelayRPCZ));
1456 } else {
1457 delayRPCPhi = fittedDelayRPCPhi;
1458 delayRPCZ = fittedDelayRPCZ;
1459 }
1460
1462 double slope_scint_phi =
fcn_pol1->GetParameter(1);
1463 double e_slope_scint_phi =
fcn_pol1->GetParError(1);
1464
1466 double slope_scint_z =
fcn_pol1->GetParameter(1);
1467 double e_slope_scint_z =
fcn_pol1->GetParError(1);
1468
1470 double slope_scint_plane1_end =
fcn_pol1->GetParameter(1);
1471 double e_slope_scint_plane1_end =
fcn_pol1->GetParError(1);
1472
1474 double slope_scint_plane2_end =
fcn_pol1->GetParameter(1);
1475 double e_slope_scint_plane2_end =
fcn_pol1->GetParError(1);
1476
1477 TString logStr_phi, logStr_z;
1479 logStr_phi = Form("%.4f ns/cm (fixed)", delayRPCPhi);
1480 logStr_z = Form("%.4f ns/cm (fixed)", delayRPCZ);
1481 B2INFO("Delay in RPCs (using fixed value):"
1482 << LogVar("Used Value (phi readout)", logStr_phi.Data())
1483 << LogVar("Used Value (z readout)", logStr_z.Data()));
1484 } else {
1485 logStr_phi = Form("%.4f +/- %.4f ns/cm", delayRPCPhi, e_slope_rpc_phi);
1486 logStr_z = Form("%.4f +/- %.4f ns/cm", delayRPCZ, e_slope_rpc_z);
1487 B2INFO("Delay in RPCs:"
1488 << LogVar("Fitted Value (phi readout)", logStr_phi.Data())
1489 << LogVar("Fitted Value (z readout)", logStr_z.Data()));
1490 }
1491 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_phi, e_slope_scint_phi);
1492 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_z, e_slope_scint_z);
1493 B2INFO("Delay in BKLM scintillators:"
1494 << LogVar("Fitted Value (phi readout) ", logStr_phi.Data())
1495 << LogVar("Fitted Value (z readout) ", logStr_z.Data()));
1496 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_plane1_end,
1497 e_slope_scint_plane1_end);
1498 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_plane2_end,
1499 e_slope_scint_plane2_end);
1500 B2INFO("Delay in EKLM scintillators:"
1501 << LogVar("Fitted Value (plane1 readout) ", logStr_phi.Data())
1502 << LogVar("Fitted Value (plane2 readout) ", logStr_z.Data()));
1503
1504 logStr_z = Form("%.4f +/- %.4f ns/cm", delayBKLM, delayBKLMError);
1505 B2INFO("Delay in BKLM scintillators:"
1506 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1507 logStr_z = Form("%.4f +/- %.4f ns/cm", delayEKLM, delayEKLMError);
1508 B2INFO("Delay in EKLM scintillators:"
1509 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1510
1515
1516
1517
1518
1519
1520 B2INFO("Third loop: Time distribution filling (batched processing)...");
1521
1522 for (const auto& batch : batches) {
1523 B2INFO("Processing batch: " << batch.first);
1525
1527 channelId = klmChannel.getKLMChannelNumber();
1528
1529 if (!batch.second(klmChannel))
1530 continue;
1531
1532 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1533 continue;
1534
1536 continue;
1537
1538 eventsChannel =
m_evts[channelId];
1539 int iSub = klmChannel.getSubdetector();
1540 int iF, iS, iL, iP, iC;
1541
1543 iF = klmChannel.getSection();
1544 iS = klmChannel.getSector() - 1;
1545 iL = klmChannel.getLayer() - 1;
1546 iP = klmChannel.getPlane();
1547 iC = klmChannel.getStrip() - 1;
1548 } else {
1549 iF = klmChannel.getSection() - 1;
1550 iS = klmChannel.getSector() - 1;
1551 iL = klmChannel.getLayer() - 1;
1552 iP = klmChannel.getPlane() - 1;
1553 iC = klmChannel.getStrip() - 1;
1554 }
1555
1556
1557 TString hn, ht;
1558 TH1F* h_temp = nullptr;
1559
1561
1563 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1564 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1565 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1567 } else {
1568 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1569 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1570 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1573 }
1574 } else {
1575 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1576 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1577 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1580 }
1581
1582
1583 for (
const Event& event : eventsChannel) {
1584
1586 continue;
1587
1588 double timeHit = event.time();
1590 timeHit = timeHit - event.t0;
1591 if (timeHit <= -400e3)
1592 continue;
1593
1595
1597 double propgationT;
1599 propgationT = event.dist * delayRPCZ;
1600 else
1601 propgationT = event.dist * delayRPCPhi;
1602 double time = timeHit - propgationT;
1603
1605 h_temp->Fill(time);
1606
1615 }
1616 } else {
1617 double propgationT = event.dist * delayBKLM;
1618 double time = timeHit - propgationT;
1619
1621 h_temp->Fill(time);
1622
1631 }
1632 }
1633 } else {
1634 double propgationT = event.dist * delayEKLM;
1635 double time = timeHit - propgationT;
1636
1638 h_temp->Fill(time);
1639
1648 }
1649 }
1650 }
1651
1652 TFitResultPtr r = h_temp->Fit(
fcn_gaus,
"LESQ");
1653 if (int(r) == 0) {
1654 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1657 }
1658
1659
1664 }
1665
1667 B2INFO("Batch processed and cleared: " << batch.first);
1668 }
1669
1670 B2INFO("Original filling done.");
1671
1672
1673 int iChannel_rpc = 0;
1674 int iChannel = 0;
1675 int iChannel_end = 0;
1677 channelId = klmChannel.getKLMChannelNumber();
1678 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1679 continue;
1680
1681 int iSub = klmChannel.getSubdetector();
1683 int iL = klmChannel.getLayer() - 1;
1684
1688 iChannel_rpc++;
1689 } else {
1692 iChannel++;
1693 }
1694 } else {
1697 iChannel_end++;
1698 }
1699 }
1700
1704
1708
1712
1713 B2INFO("Channel's time distribution fitting done.");
1717
1718 B2INFO("Calibrated channel's time distribution filling begins.");
1719
1722 channelId = klmChannel.getKLMChannelNumber();
1725 continue;
1729 }
1730
1732 channelId = klmChannel.getKLMChannelNumber();
1734 continue;
1737 B2DEBUG(20,
"Uncalibrated Estimation " << LogVar(
"Channel", channelId) << LogVar(
"Estimated value",
m_timeShift[channelId]));
1738 }
1739
1740 iChannel_rpc = 0;
1741 iChannel = 0;
1742 iChannel_end = 0;
1744 channelId = klmChannel.getKLMChannelNumber();
1746 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
1747 continue;
1748 }
1749 int iSub = klmChannel.getSubdetector();
1751
1752 int iL = klmChannel.getLayer() - 1;
1755 iChannel_rpc++;
1756 } else {
1758 iChannel++;
1759 }
1760 } else {
1762 iChannel_end++;
1763 }
1764 }
1765
1766
1771
1772
1773
1774
1775
1776 B2INFO("Fourth loop: Calibrated time distribution filling (batched processing)...");
1777
1778 for (const auto& batch : batches) {
1779 B2INFO("Processing batch: " << batch.first);
1781
1783 channelId = klmChannel.getKLMChannelNumber();
1784
1785 if (!batch.second(klmChannel))
1786 continue;
1787
1789 continue;
1790
1791 eventsChannel =
m_evts[channelId];
1792 int iSub = klmChannel.getSubdetector();
1793 int iF, iS, iL, iP, iC;
1794
1796 iF = klmChannel.getSection();
1797 iS = klmChannel.getSector() - 1;
1798 iL = klmChannel.getLayer() - 1;
1799 iP = klmChannel.getPlane();
1800 iC = klmChannel.getStrip() - 1;
1801 } else {
1802 iF = klmChannel.getSection() - 1;
1803 iS = klmChannel.getSector() - 1;
1804 iL = klmChannel.getLayer() - 1;
1805 iP = klmChannel.getPlane() - 1;
1806 iC = klmChannel.getStrip() - 1;
1807 }
1808
1809 TString hn, ht;
1810 TH1F* hc_temp = nullptr;
1811
1813
1815 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1816 ht = Form("Calibrated time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1817 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1820 } else {
1821 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1822 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1823 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1826 }
1827 } else {
1828 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1829 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1830 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1833 }
1834
1835 for (
const Event& event : eventsChannel) {
1836
1838 continue;
1839
1840 double timeHit = event.time();
1842 timeHit = timeHit - event.t0;
1843 if (timeHit <= -400e3)
1844 continue;
1845
1847
1849 double propgationT;
1851 propgationT = event.dist * delayRPCZ;
1852 else
1853 propgationT = event.dist * delayRPCPhi;
1854 double time = timeHit - propgationT -
m_timeShift[channelId];
1855
1857 hc_temp->Fill(time);
1858
1867 }
1868 } else {
1869 double propgationT = event.dist * delayBKLM;
1870 double time = timeHit - propgationT -
m_timeShift[channelId];
1871
1873 hc_temp->Fill(time);
1874
1883 }
1884 }
1885 } else {
1886 double propgationT = event.dist * delayEKLM;
1887 double time = timeHit - propgationT -
m_timeShift[channelId];
1888
1890 hc_temp->Fill(time);
1891
1900 }
1901 }
1902 }
1903
1904 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData) {
1905 delete hc_temp;
1906 continue;
1907 }
1908
1909 TFitResultPtr rc = hc_temp->Fit(
fcn_gaus,
"LESQ");
1910 if (int(rc) == 0) {
1911 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1914 }
1915
1916
1921 }
1922
1924 B2INFO("Batch processed and cleared: " << batch.first);
1925 }
1926
1927
1928 int icChannel_rpc = 0;
1929 int icChannel = 0;
1930 int icChannel_end = 0;
1932 channelId = klmChannel.getKLMChannelNumber();
1933 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1934 continue;
1935
1936 int iSub = klmChannel.getSubdetector();
1938 int iL = klmChannel.getLayer() - 1;
1939
1943 icChannel_rpc++;
1944 } else {
1947 icChannel++;
1948 }
1949 } else {
1952 icChannel_end++;
1953 }
1954 }
1955
1959
1963
1967
1968 B2INFO("Channel's time distribution fitting done.");
1972
1973 B2INFO("Calibrated channel's time distribution filling begins.");
1974
1977 channelId = klmChannel.getKLMChannelNumber();
1980 continue;
1984 }
1985
1987 channelId = klmChannel.getKLMChannelNumber();
1989 continue;
1992 B2DEBUG(20,
"Calibrated Estimation " << LogVar(
"Channel", channelId) << LogVar(
"Estimated value",
m_timeRes[channelId]));
1993 }
1994
1995 icChannel_rpc = 0;
1996 icChannel = 0;
1997 icChannel_end = 0;
1999 channelId = klmChannel.getKLMChannelNumber();
2001 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
2002 continue;
2003 }
2004 int iSub = klmChannel.getSubdetector();
2006
2007 int iL = klmChannel.getLayer() - 1;
2010 icChannel_rpc++;
2011 } else {
2013 icChannel++;
2014 }
2015 } else {
2017 icChannel_end++;
2018 }
2019 }
2020
2021
2022
2023
2024 B2INFO("Fifth pass: Computing di-muon ΔT0 for EventT0 hit resolution calibration...");
2025
2026
2027 struct TrackT0Info {
2028 int charge;
2029 int nHits_BKLM_Scint;
2030 int nHits_BKLM_RPC_Phi;
2031 int nHits_BKLM_RPC_Z;
2032 int nHits_EKLM_Scint;
2033 double sumT0_BKLM_Scint;
2034 double sumT0_BKLM_RPC_Phi;
2035 double sumT0_BKLM_RPC_Z;
2036 double sumT0_EKLM_Scint;
2037
2038 TrackT0Info() : charge(0),
2039 nHits_BKLM_Scint(0),
2040 nHits_BKLM_RPC_Phi(0),
2041 nHits_BKLM_RPC_Z(0),
2042 nHits_EKLM_Scint(0),
2043 sumT0_BKLM_Scint(0.0),
2044 sumT0_BKLM_RPC_Phi(0.0),
2045 sumT0_BKLM_RPC_Z(0.0),
2046 sumT0_EKLM_Scint(0.0) {}
2047 };
2048
2049
2050 std::map<std::pair<int, int>, std::map<int, TrackT0Info>> eventTrackMap;
2051
2052
2053 for (const auto& batch : batches) {
2054 B2INFO("Processing batch for di-muon analysis: " << batch.first);
2056
2057 for (
const auto& channelPair :
m_evts) {
2059 const std::vector<Event>& chEvents = channelPair.second;
2060
2061
2062 int subdetector, section, sector, layer, plane, strip;
2064 chId, &subdetector, §ion, §or, &layer, &plane, &strip);
2065
2066
2067 int iSub = subdetector;
2068 int iL = layer - 1;
2069
2070 for (
const Event& event : chEvents) {
2071
2073 continue;
2074
2075
2076 std::pair<int, int> eventKey(event.Run, event.Events);
2077 int trackIdx = event.nTrack;
2078 int charge = event.Track_Charge;
2079
2080
2081 double timeHit =
event.time() -
m_timeShift[chId];
2082
2083 if (timeHit <= -400e3)
2084 continue;
2085
2086
2087 double propT = 0.0;
2090
2092 propT = event.dist * delayRPCZ;
2093 else
2094 propT = event.dist * delayRPCPhi;
2095 } else {
2096
2097 propT = event.dist * delayBKLM;
2098 }
2099 } else {
2100
2101 propT = event.dist * delayEKLM;
2102 }
2103
2104 double t0_estimate = timeHit - propT;
2105
2106
2107 TrackT0Info& trackInfo = eventTrackMap[eventKey][trackIdx];
2108 trackInfo.charge = charge;
2109
2112
2114 trackInfo.nHits_BKLM_RPC_Z++;
2115 trackInfo.sumT0_BKLM_RPC_Z += t0_estimate;
2116 } else {
2117 trackInfo.nHits_BKLM_RPC_Phi++;
2118 trackInfo.sumT0_BKLM_RPC_Phi += t0_estimate;
2119 }
2120 } else {
2121
2122 trackInfo.nHits_BKLM_Scint++;
2123 trackInfo.sumT0_BKLM_Scint += t0_estimate;
2124 }
2125 } else {
2126 trackInfo.nHits_EKLM_Scint++;
2127 trackInfo.sumT0_EKLM_Scint += t0_estimate;
2128 }
2129 }
2130 }
2131
2133 }
2134
2135 B2INFO("Event-track map built. Processing events for EventT0 histograms...");
2136
2137
2138
2139 double sum_delta2_over_v_BKLM_Scint = 0.0;
2140 double sum_delta2_over_v_BKLM_RPC_Phi = 0.0;
2141 double sum_delta2_over_v_BKLM_RPC_Z = 0.0;
2142 double sum_delta2_over_v_EKLM_Scint = 0.0;
2143
2144 int nDimuon_BKLM_Scint = 0;
2145 int nDimuon_BKLM_RPC_Phi = 0;
2146 int nDimuon_BKLM_RPC_Z = 0;
2147 int nDimuon_EKLM_Scint = 0;
2148
2149 for (const auto& eventPair : eventTrackMap) {
2150 const auto& trackMap = eventPair.second;
2151
2152
2153 if (trackMap.size() != 2)
2154 continue;
2155
2156 auto it1 = trackMap.begin();
2157 auto it2 = trackMap.begin();
2158 ++it2;
2159 const TrackT0Info& track1 = it1->second;
2160 const TrackT0Info& track2 = it2->second;
2161
2162
2163 if (track1.charge * track2.charge >= 0)
2164 continue;
2165
2166
2167 const TrackT0Info& muPlus = (track1.charge > 0) ? track1 : track2;
2168 const TrackT0Info& muMinus = (track1.charge > 0) ? track2 : track1;
2169
2170
2171 if (muPlus.nHits_BKLM_Scint > 0 && muMinus.nHits_BKLM_Scint > 0) {
2172 double t0_plus = muPlus.sumT0_BKLM_Scint / muPlus.nHits_BKLM_Scint;
2173 double t0_minus = muMinus.sumT0_BKLM_Scint / muMinus.nHits_BKLM_Scint;
2174 double deltaT0 = t0_plus - t0_minus;
2175
2176
2177 double v = 1.0 / muPlus.nHits_BKLM_Scint + 1.0 / muMinus.nHits_BKLM_Scint;
2178 int nTotal = muPlus.nHits_BKLM_Scint + muMinus.nHits_BKLM_Scint;
2179
2180 if (v <= 0.0)
2181 continue;
2182
2183
2184 sum_delta2_over_v_BKLM_Scint += (deltaT0 * deltaT0) / v;
2185 nDimuon_BKLM_Scint++;
2186
2187
2191
2192
2198
2199
2200 if (nTotal < 5) {
2202 } else if (nTotal < 15) {
2204 } else {
2206 }
2207 }
2208
2209
2210 if (muPlus.nHits_BKLM_RPC_Phi > 0 && muMinus.nHits_BKLM_RPC_Phi > 0) {
2211 double t0_plus = muPlus.sumT0_BKLM_RPC_Phi / muPlus.nHits_BKLM_RPC_Phi;
2212 double t0_minus = muMinus.sumT0_BKLM_RPC_Phi / muMinus.nHits_BKLM_RPC_Phi;
2213 double deltaT0 = t0_plus - t0_minus;
2214
2215 double v = 1.0 / muPlus.nHits_BKLM_RPC_Phi + 1.0 / muMinus.nHits_BKLM_RPC_Phi;
2216 int nTotal = muPlus.nHits_BKLM_RPC_Phi + muMinus.nHits_BKLM_RPC_Phi;
2217
2218 if (v <= 0.0)
2219 continue;
2220
2221 sum_delta2_over_v_BKLM_RPC_Phi += (deltaT0 * deltaT0) / v;
2222 nDimuon_BKLM_RPC_Phi++;
2223
2227
2228
2234
2235 if (nTotal < 10) {
2237 } else if (nTotal < 30) {
2239 } else {
2241 }
2242 }
2243
2244
2245 if (muPlus.nHits_BKLM_RPC_Z > 0 && muMinus.nHits_BKLM_RPC_Z > 0) {
2246 double t0_plus = muPlus.sumT0_BKLM_RPC_Z / muPlus.nHits_BKLM_RPC_Z;
2247 double t0_minus = muMinus.sumT0_BKLM_RPC_Z / muMinus.nHits_BKLM_RPC_Z;
2248 double deltaT0 = t0_plus - t0_minus;
2249
2250 double v = 1.0 / muPlus.nHits_BKLM_RPC_Z + 1.0 / muMinus.nHits_BKLM_RPC_Z;
2251 int nTotal = muPlus.nHits_BKLM_RPC_Z + muMinus.nHits_BKLM_RPC_Z;
2252
2253 if (v <= 0.0)
2254 continue;
2255
2256 sum_delta2_over_v_BKLM_RPC_Z += (deltaT0 * deltaT0) / v;
2257 nDimuon_BKLM_RPC_Z++;
2258
2262
2263
2269
2270 if (nTotal < 10) {
2272 } else if (nTotal < 30) {
2274 } else {
2276 }
2277 }
2278
2279
2280 if (muPlus.nHits_EKLM_Scint > 0 && muMinus.nHits_EKLM_Scint > 0) {
2281 double t0_plus = muPlus.sumT0_EKLM_Scint / muPlus.nHits_EKLM_Scint;
2282 double t0_minus = muMinus.sumT0_EKLM_Scint / muMinus.nHits_EKLM_Scint;
2283 double deltaT0 = t0_plus - t0_minus;
2284
2285 double v = 1.0 / muPlus.nHits_EKLM_Scint + 1.0 / muMinus.nHits_EKLM_Scint;
2286 int nTotal = muPlus.nHits_EKLM_Scint + muMinus.nHits_EKLM_Scint;
2287
2288 if (v <= 0.0)
2289 continue;
2290
2291 sum_delta2_over_v_EKLM_Scint += (deltaT0 * deltaT0) / v;
2292 nDimuon_EKLM_Scint++;
2293
2297
2298
2304
2305
2306 if (nTotal < 5) {
2308 } else if (nTotal < 15) {
2310 } else {
2312 }
2313 }
2314 }
2315
2316 B2INFO("Di-muon ΔT0 data collected."
2317 << LogVar("BKLM Scint di-muon events", nDimuon_BKLM_Scint)
2318 << LogVar("BKLM RPC Phi di-muon events", nDimuon_BKLM_RPC_Phi)
2319 << LogVar("BKLM RPC Z di-muon events", nDimuon_BKLM_RPC_Z)
2320 << LogVar("EKLM Scint di-muon events", nDimuon_EKLM_Scint));
2321
2322
2323
2324
2325 float sigma_BKLM_Scint = 10.0f;
2326 float sigma_BKLM_Scint_err = 1.0f;
2327 if (nDimuon_BKLM_Scint > 0) {
2328 double sigma2 = sum_delta2_over_v_BKLM_Scint / static_cast<double>(nDimuon_BKLM_Scint);
2329 sigma_BKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2330
2331 sigma_BKLM_Scint_err = sigma_BKLM_Scint / std::sqrt(2.0 * nDimuon_BKLM_Scint);
2332 }
2333
2334 float sigma_RPC_Phi = 10.0f;
2335 float sigma_RPC_Phi_err = 1.0f;
2336 if (nDimuon_BKLM_RPC_Phi > 0) {
2337 double sigma2 = sum_delta2_over_v_BKLM_RPC_Phi / static_cast<double>(nDimuon_BKLM_RPC_Phi);
2338 sigma_RPC_Phi = static_cast<float>(std::sqrt(sigma2));
2339 sigma_RPC_Phi_err = sigma_RPC_Phi / std::sqrt(2.0 * nDimuon_BKLM_RPC_Phi);
2340 }
2341
2342 float sigma_RPC_Z = 10.0f;
2343 float sigma_RPC_Z_err = 1.0f;
2344 if (nDimuon_BKLM_RPC_Z > 0) {
2345 double sigma2 = sum_delta2_over_v_BKLM_RPC_Z / static_cast<double>(nDimuon_BKLM_RPC_Z);
2346 sigma_RPC_Z = static_cast<float>(std::sqrt(sigma2));
2347 sigma_RPC_Z_err = sigma_RPC_Z / std::sqrt(2.0 * nDimuon_BKLM_RPC_Z);
2348 }
2349
2350
2351 float sigma_RPC = 10.0f;
2352 float sigma_RPC_err = 1.0f;
2353 int nDimuon_RPC_total = nDimuon_BKLM_RPC_Phi + nDimuon_BKLM_RPC_Z;
2354 if (nDimuon_RPC_total > 0) {
2355
2356 double w_phi = static_cast<double>(nDimuon_BKLM_RPC_Phi) / nDimuon_RPC_total;
2357 double w_z = static_cast<double>(nDimuon_BKLM_RPC_Z) / nDimuon_RPC_total;
2358 sigma_RPC = w_phi * sigma_RPC_Phi + w_z * sigma_RPC_Z;
2359
2360 sigma_RPC_err = std::sqrt(w_phi * w_phi * sigma_RPC_Phi_err * sigma_RPC_Phi_err +
2361 w_z * w_z * sigma_RPC_Z_err * sigma_RPC_Z_err);
2362 }
2363
2364 float sigma_EKLM_Scint = 10.0f;
2365 float sigma_EKLM_Scint_err = 1.0f;
2366 if (nDimuon_EKLM_Scint > 0) {
2367 double sigma2 = sum_delta2_over_v_EKLM_Scint / static_cast<double>(nDimuon_EKLM_Scint);
2368 sigma_EKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2369 sigma_EKLM_Scint_err = sigma_EKLM_Scint / std::sqrt(2.0 * nDimuon_EKLM_Scint);
2370 }
2371
2372 B2INFO("Extracted per-hit resolutions using event-by-event weighting:"
2373 << LogVar("σ_BKLM_Scint [ns]", sigma_BKLM_Scint) << LogVar("±", sigma_BKLM_Scint_err)
2374 << LogVar("σ_RPC_Phi [ns]", sigma_RPC_Phi) << LogVar("±", sigma_RPC_Phi_err)
2375 << LogVar("σ_RPC_Z [ns]", sigma_RPC_Z) << LogVar("±", sigma_RPC_Z_err)
2376 << LogVar("σ_RPC_combined [ns]", sigma_RPC) << LogVar("±", sigma_RPC_err)
2377 << LogVar("σ_EKLM_Scint [ns]", sigma_EKLM_Scint) << LogVar("±", sigma_EKLM_Scint_err));
2378
2379
2385
2386 B2INFO("EventT0 hit resolution calibration complete and stored in payload.");
2387
2388
2389 eventTrackMap.clear();
2390
2396
2398
2403
2405}
@ c_FirstRPCLayer
First RPC layer.
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
TProfile * m_Profile2EKLMScintillatorPlane2
For EKLM scintillator plane2.
TDirectory * m_channelHistDir_BKLM[2][8][15][2]
Directory structure for per-channel histograms (BKLM).
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 * hc_eventT0_scint_end_highN
Corrected EventT0 for EKLM scintillator with high hit count.
TProfile * prof_deltaT0_rms_vs_v_scint_end
DeltaT0 RMS vs inverse hit count profile for EKLM scintillator.
TH1F * h_time_scint_tc_end
EKLM part.
TH1F * hc_eventT0_scint_midN
Corrected EventT0 for BKLM scintillator with medium hit count.
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.
TProfile * prof_deltaT0_rms_vs_v_rpc
DeltaT0 RMS vs inverse hit count profile for RPC.
TH1F * h_eventT0_scint
EventT0 seen by BKLM scintillator hits.
TH1F * hc_timeFS_scint[2][8]
BKLM scintillator part.
std::map< KLMChannelNumber, double > m_time_channel
Time distribution central value of each channel.
TH1F * hc_eventT0_rpc_lowN
Corrected EventT0 for RPC with low hit count.
double m_ctime_channelAvg_scint_end
Calibrated central value of the global time distribution (EKLM scintillator part).
CalibrationAlgorithm::EResult readCalibrationData()
Read calibration data.
TH1F * hc_eventT0_scint_lowN
Corrected EventT0 for BKLM scintillator with low hit count.
TGraph * gr_timeShift_channel_scint_end
EKLM.
TGraph * gr_timeRes_channel_scint
BKLM scintillator.
TH2F * h2_deltaT0_vs_v_scint
DeltaT0 vs inverse hit count for 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.
void writeThenDelete_(TH1 *h, bool write, TDirectory *dir=nullptr)
Optionally write a histogram, then delete it to free memory.
TH1F * hc_timeF_rpc[2]
BKLM RPC part.
TH2F * h2c_timeFS_end[2][4]
EKLM part.
TGraphErrors * gre_ctime_channel_scint_end
EKLM.
TH1F * h_nHits_plus_scint_end
Number of EKLM scintillator hits per mu+ track.
TProfile * m_Profile2BKLMScintillatorPhi
For BKLM scintillator phi plane.
TH1F * hc_time_scint_end
EKLM part.
TH1F * hc_eventT0_scint
Corrected EventT0 for BKLM scintillator hits.
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.
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.
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.
TH1F * h_nHits_minus_rpc
Number of RPC hits per mu- track.
TH2F * h2_timeFSLP_end[2][4][14][2]
EKLM part.
TH1I * hc_calibrated
Calibration statistics for each channel.
TH1F * h_eventT0_rpc
EventT0 seen by RPC hits.
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 * hc_eventT0_scint_end_midN
Corrected EventT0 for EKLM scintillator with medium hit count.
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).
bool passesADCCut(const Event &event, int subdetector, int layer) const
Check if event passes ADC count cuts for quality selection.
TH2F * h2_timeF_scint_end[2]
EKLM part.
KLMEventT0HitResolution * m_eventT0HitResolution
DBObject of per-hit time resolution for EventT0.
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_fixedRPCDelay
Fixed propagation delay for RPCs (ns/cm).
double m_etime_channelAvg_scint
Central value error of the global time distribution (BKLM scintillator part).
TH1F * h_timeF_scint_end[2]
EKLM part.
TH1F * hc_eventT0_scint_end
Corrected EventT0 for EKLM scintillator hits.
TProfile * m_ProfileRpcPhi
For BKLM RPC phi plane.
TGraphErrors * gre_ctime_channel_scint
BKLM Scintillator.
TH2F * h2_deltaT0_vs_nhits_scint
DeltaT0 vs total hit count for BKLM scintillator.
TH2F * h2_deltaT0_vs_nhits_rpc
DeltaT0 vs total hit count for RPC.
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.
TH2F * h2_deltaT0_vs_v_scint_end
DeltaT0 vs inverse hit count for EKLM scintillator.
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_eventT0_scint_end
EventT0 seen by EKLM scintillator hits.
TH1F * h_diff
Distance between global and local position.
TH1F * hc_eventT0_rpc_highN
Corrected EventT0 for RPC with high hit count.
TH1F * h_nHits_plus_scint
Number of BKLM scintillator hits per mu+ track.
TH2F * h2_timeF_scint[2]
BKLM scintillator part.
TH1F * h_time_scint_tc
BKLM scintillator part.
double m_LowerTimeBoundaryRPC
Lower time boundary for RPC.
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).
TH2F * h2_deltaT0_vs_nhits_scint_end
DeltaT0 vs total hit count for EKLM scintillator.
bool m_useEventT0
Whether to use event T0 from CDC.
TProfile * m_ProfileEKLMScintillatorPlane1
For EKLM scintillator plane1.
double m_UpperTimeBoundaryRPC
Upper time boundary for RPC.
TH2F * h2c_timeF_rpc[2]
BKLM RPC part.
TH1F * hc_eventT0_scint_highN
Corrected EventT0 for BKLM scintillator with high hit count.
TF1 * fcn_land
Landau function.
KLMTimeCableDelay * m_timeCableDelay
DBObject of the calibration constant of each channel due to cable decay.
TH2F * h2_deltaT0_vs_v_rpc
DeltaT0 vs inverse hit count for RPC.
TProfile * m_ProfileRpcZ
For BKLM RPC z plane.
bool m_useFixedRPCDelay
Whether to use fixed propagation delay for RPCs.
std::map< KLMChannelNumber, double > mc_etime_channel
Calibrated time distribution central value Error of each channel.
void readCalibrationDataBatch(std::function< bool(const KLMChannelIndex &)> channelFilter)
Load calibration data for a specific batch of channels.
TH1F * hc_eventT0_rpc_midN
Corrected EventT0 for RPC with medium hit count.
TH1F * h_nHits_minus_scint
Number of BKLM scintillator hits per mu- track.
TProfile * prof_deltaT0_rms_vs_v_scint
DeltaT0 RMS vs inverse hit count profile for BKLM scintillator.
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.
TH1F * h_nHits_plus_rpc
Number of RPC hits per mu+ track.
std::map< KLMChannelNumber, std::vector< struct Event > > m_evts
Container of hit information.
TDirectory * m_channelHistDir_EKLM[2][4][14][2]
Directory structure for per-channel histograms (EKLM).
TH1F * hc_eventT0_rpc
Corrected EventT0 for RPC hits.
TH1F * h_nHits_minus_scint_end
Number of EKLM scintillator hits per mu- track.
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.
TH1F * hc_eventT0_scint_end_lowN
Corrected EventT0 for EKLM scintillator with low hit count.
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.
@ c_BKLM
BKLM scintillator.
@ c_EKLM
EKLM scintillator.
uint16_t KLMChannelNumber
Channel number.