Run algorithm on data.
1121{
1122 int channelId;
1123 gROOT->SetBatch(kTRUE);
1129
1130 fcn_gaus =
new TF1(
"fcn_gaus",
"gaus");
1131 fcn_land =
new TF1(
"fcn_land",
"landau");
1132 fcn_pol1 =
new TF1(
"fcn_pol1",
"pol1");
1133 fcn_const =
new TF1(
"fcn_const",
"pol0");
1134
1135
1138 return result;
1139
1140
1141 std::string name = "time_calibration.root";
1142 int i = 1;
1143 while (1) {
1144 struct stat buffer;
1145 if (stat(name.c_str(), &buffer) != 0)
1146 break;
1147 name = "time_calibration_" + std::to_string(i) + ".root";
1148 i = i + 1;
1149 if (i < 0)
1150 break;
1151 }
1152 m_outFile =
new TFile(name.c_str(),
"recreate");
1154
1155 std::vector<struct Event> eventsChannel;
1156 eventsChannel.clear();
1159
1160 B2INFO("Counting events per channel...");
1161 std::map<KLMChannelNumber, unsigned int> eventCounts;
1163
1164
1165 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsBKLM;
1166 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsEKLM;
1167 KLMChannelIndex klmChannels;
1168
1169 for (const KLMChannelIndex& klmChannel : klmChannels) {
1171 m_cFlag[channel] = ChannelCalibrationStatus::c_NotEnoughData;
1172
1173 if (eventCounts.find(channel) == eventCounts.end())
1174 continue;
1175
1176 int nEvents = eventCounts[channel];
1178 B2WARNING("Not enough calibration data collected."
1179 << LogVar("channel", channel)
1180 << LogVar("number of digit", nEvents));
1181 continue;
1182 }
1183
1184 m_cFlag[channel] = ChannelCalibrationStatus::c_FailedFit;
1185
1188 channelsBKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1189 }
1191 channelsEKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1192 }
1193 }
1194
1195 std::sort(channelsBKLM.begin(), channelsBKLM.end(), compareEventNumber);
1196 std::sort(channelsEKLM.begin(), channelsEKLM.end(), compareEventNumber);
1197
1198
1199 double delayBKLM, delayBKLMError;
1200 double delayEKLM, delayEKLMError;
1201
1202
1207
1208 B2INFO("2D fits complete, data cleared.");
1209
1210
1211 auto isRPCBackward = [](const KLMChannelIndex & ch) {
1215 };
1216
1217 auto isRPCForward = [](const KLMChannelIndex & ch) {
1221 };
1222
1223 auto isBKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1227 };
1228
1229 auto isBKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1233 };
1234
1235 auto isEKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1238 };
1239
1240 auto isEKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1243 };
1244
1245 std::vector<std::pair<std::string, std::function<bool(const KLMChannelIndex&)>>> batches = {
1246 {"RPC Backward", isRPCBackward},
1247 {"RPC Forward", isRPCForward},
1248 {"BKLM Scintillator Backward", isBKLMScintillatorBackward},
1249 {"BKLM Scintillator Forward", isBKLMScintillatorForward},
1250 {"EKLM Scintillator Backward", isEKLMScintillatorBackward},
1251 {"EKLM Scintillator Forward", isEKLMScintillatorForward}
1252 };
1253
1254
1255
1256
1257
1258 B2INFO("First loop: Computing global statistics (batched processing)...");
1259
1260 TString iFstring[2] = {"Backward", "Forward"};
1261 TString iPstring[2] = {"ZReadout", "PhiReadout"};
1262 int nBin = 80;
1263 int nBin_scint = 80;
1264
1265 for (const auto& batch : batches) {
1266 B2INFO("Processing batch for global stats: " << batch.first);
1268
1270 channelId = klmChannel.getKLMChannelNumber();
1271
1272 if (!batch.second(klmChannel))
1273 continue;
1274
1275 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1276 continue;
1277
1279 continue;
1280
1281 eventsChannel =
m_evts[channelId];
1282 int iSub = klmChannel.getSubdetector();
1284
1285
1286 for (
const Event& event : eventsChannel) {
1287
1289 continue;
1290
1291 XYZVector diffD = XYZVector(event.diffDistX, event.diffDistY, event.diffDistZ);
1293
1294 double timeHit = event.time();
1296 timeHit = timeHit - event.t0;
1297
1298 if (timeHit <= -400e3)
1299 continue;
1300
1302
1305 } else {
1307 }
1308 } else {
1310 }
1311 }
1312 }
1313
1315 B2INFO("Batch processed and cleared: " << batch.first);
1316 }
1317
1318
1323
1324 B2INFO("Global Mean for Raw." << LogVar("RPC", tmpMean_rpc_global)
1325 << LogVar("Scint BKLM", tmpMean_scint_global)
1326 << LogVar("Scint EKLM", tmpMean_scint_global_end));
1327
1328
1329
1330
1331
1332 B2INFO("Second pass: Computing per-channel time shifts (batched processing)...");
1333
1334 for (const auto& batch : batches) {
1335 B2INFO("Processing batch for time shifts: " << batch.first);
1337
1339 channelId = klmChannel.getKLMChannelNumber();
1340
1341 if (!batch.second(klmChannel))
1342 continue;
1343
1344 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1345 continue;
1346
1348 continue;
1349
1350 eventsChannel =
m_evts[channelId];
1351 int iSub = klmChannel.getSubdetector();
1352 int iF, iS, iL, iP, iC;
1353
1355 iF = klmChannel.getSection();
1356 iS = klmChannel.getSector() - 1;
1357 iL = klmChannel.getLayer() - 1;
1358 iP = klmChannel.getPlane();
1359 iC = klmChannel.getStrip() - 1;
1360 } else {
1361 iF = klmChannel.getSection() - 1;
1362 iS = klmChannel.getSector() - 1;
1363 iL = klmChannel.getLayer() - 1;
1364 iP = klmChannel.getPlane() - 1;
1365 iC = klmChannel.getStrip() - 1;
1366 }
1367
1368
1369 TString hn, ht;
1370 TH1F* h_temp_tc = nullptr;
1371
1373
1375 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1376 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1377 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1379 } else {
1380 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1381 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1382 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1385 }
1386 } else {
1387 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc_end", iF, iS, iL, iP, iC);
1388 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1389 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1392 }
1393
1394 for (
const Event& event : eventsChannel) {
1395
1397 continue;
1398
1399 double timeHit = event.time();
1401 timeHit = timeHit - event.t0;
1402 if (timeHit <= -400e3)
1403 continue;
1404 h_temp_tc->Fill(timeHit);
1405 }
1406
1408 double tmpMean_channel =
fcn_gaus->GetParameter(1);
1409
1411
1413 m_timeShift[channelId] = tmpMean_channel - tmpMean_rpc_global;
1414 } else {
1415 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global;
1416 }
1417 } else {
1418 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global_end;
1419 }
1420
1421 delete h_temp_tc;
1422 }
1423
1425 B2INFO("Batch processed and cleared: " << batch.first);
1426 }
1427
1431 B2INFO("Effective Light m_timeShift obtained.");
1432
1433
1438
1439 B2INFO("Effective light speed fitting.");
1440
1441
1443 double fittedDelayRPCPhi =
fcn_pol1->GetParameter(1);
1444 double e_slope_rpc_phi =
fcn_pol1->GetParError(1);
1445
1447 double fittedDelayRPCZ =
fcn_pol1->GetParameter(1);
1448 double e_slope_rpc_z =
fcn_pol1->GetParError(1);
1449
1450
1451 double delayRPCPhi, delayRPCZ;
1455 B2INFO(
"Using fixed RPC propagation delay: " <<
m_fixedRPCDelay <<
" ns/cm (c_eff = 0.5c)"
1456 << LogVar("Fitted phi (not used)", fittedDelayRPCPhi)
1457 << LogVar("Fitted Z (not used)", fittedDelayRPCZ));
1458 } else {
1459 delayRPCPhi = fittedDelayRPCPhi;
1460 delayRPCZ = fittedDelayRPCZ;
1461 }
1462
1464 double slope_scint_phi =
fcn_pol1->GetParameter(1);
1465 double e_slope_scint_phi =
fcn_pol1->GetParError(1);
1466
1468 double slope_scint_z =
fcn_pol1->GetParameter(1);
1469 double e_slope_scint_z =
fcn_pol1->GetParError(1);
1470
1472 double slope_scint_plane1_end =
fcn_pol1->GetParameter(1);
1473 double e_slope_scint_plane1_end =
fcn_pol1->GetParError(1);
1474
1476 double slope_scint_plane2_end =
fcn_pol1->GetParameter(1);
1477 double e_slope_scint_plane2_end =
fcn_pol1->GetParError(1);
1478
1479 TString logStr_phi, logStr_z;
1481 logStr_phi = Form("%.4f ns/cm (fixed)", delayRPCPhi);
1482 logStr_z = Form("%.4f ns/cm (fixed)", delayRPCZ);
1483 B2INFO("Delay in RPCs (using fixed value):"
1484 << LogVar("Used Value (phi readout)", logStr_phi.Data())
1485 << LogVar("Used Value (z readout)", logStr_z.Data()));
1486 } else {
1487 logStr_phi = Form("%.4f +/- %.4f ns/cm", delayRPCPhi, e_slope_rpc_phi);
1488 logStr_z = Form("%.4f +/- %.4f ns/cm", delayRPCZ, e_slope_rpc_z);
1489 B2INFO("Delay in RPCs:"
1490 << LogVar("Fitted Value (phi readout)", logStr_phi.Data())
1491 << LogVar("Fitted Value (z readout)", logStr_z.Data()));
1492 }
1493 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_phi, e_slope_scint_phi);
1494 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_z, e_slope_scint_z);
1495 B2INFO("Delay in BKLM scintillators:"
1496 << LogVar("Fitted Value (phi readout) ", logStr_phi.Data())
1497 << LogVar("Fitted Value (z readout) ", logStr_z.Data()));
1498 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_plane1_end,
1499 e_slope_scint_plane1_end);
1500 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_plane2_end,
1501 e_slope_scint_plane2_end);
1502 B2INFO("Delay in EKLM scintillators:"
1503 << LogVar("Fitted Value (plane1 readout) ", logStr_phi.Data())
1504 << LogVar("Fitted Value (plane2 readout) ", logStr_z.Data()));
1505
1506 logStr_z = Form("%.4f +/- %.4f ns/cm", delayBKLM, delayBKLMError);
1507 B2INFO("Delay in BKLM scintillators:"
1508 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1509 logStr_z = Form("%.4f +/- %.4f ns/cm", delayEKLM, delayEKLMError);
1510 B2INFO("Delay in EKLM scintillators:"
1511 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1512
1517
1518
1519
1520
1521
1522 B2INFO("Third loop: Time distribution filling (batched processing)...");
1523
1524 for (const auto& batch : batches) {
1525 B2INFO("Processing batch: " << batch.first);
1527
1529 channelId = klmChannel.getKLMChannelNumber();
1530
1531 if (!batch.second(klmChannel))
1532 continue;
1533
1534 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1535 continue;
1536
1538 continue;
1539
1540 eventsChannel =
m_evts[channelId];
1541 int iSub = klmChannel.getSubdetector();
1542 int iF, iS, iL, iP, iC;
1543
1545 iF = klmChannel.getSection();
1546 iS = klmChannel.getSector() - 1;
1547 iL = klmChannel.getLayer() - 1;
1548 iP = klmChannel.getPlane();
1549 iC = klmChannel.getStrip() - 1;
1550 } else {
1551 iF = klmChannel.getSection() - 1;
1552 iS = klmChannel.getSector() - 1;
1553 iL = klmChannel.getLayer() - 1;
1554 iP = klmChannel.getPlane() - 1;
1555 iC = klmChannel.getStrip() - 1;
1556 }
1557
1558
1559 TString hn, ht;
1560 TH1F* h_temp = nullptr;
1561
1563
1565 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1566 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1567 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1569 } else {
1570 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1571 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1572 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1575 }
1576 } else {
1577 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1578 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1579 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1582 }
1583
1584
1585 for (
const Event& event : eventsChannel) {
1586
1588 continue;
1589
1590 double timeHit = event.time();
1592 timeHit = timeHit - event.t0;
1593 if (timeHit <= -400e3)
1594 continue;
1595
1597
1599 double propgationT;
1601 propgationT = event.dist * delayRPCZ;
1602 else
1603 propgationT = event.dist * delayRPCPhi;
1604 double time = timeHit - propgationT;
1605
1607 h_temp->Fill(time);
1608
1617 }
1618 } else {
1619 double propgationT = event.dist * delayBKLM;
1620 double time = timeHit - propgationT;
1621
1623 h_temp->Fill(time);
1624
1633 }
1634 }
1635 } else {
1636 double propgationT = event.dist * delayEKLM;
1637 double time = timeHit - propgationT;
1638
1640 h_temp->Fill(time);
1641
1650 }
1651 }
1652 }
1653
1654 TFitResultPtr r = h_temp->Fit(
fcn_gaus,
"LESQ");
1655 if (int(r) == 0) {
1656 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1659 }
1660
1661
1666 }
1667
1669 B2INFO("Batch processed and cleared: " << batch.first);
1670 }
1671
1672 B2INFO("Original filling done.");
1673
1674
1675 int iChannel_rpc = 0;
1676 int iChannel = 0;
1677 int iChannel_end = 0;
1679 channelId = klmChannel.getKLMChannelNumber();
1680 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1681 continue;
1682
1683 int iSub = klmChannel.getSubdetector();
1685 int iL = klmChannel.getLayer() - 1;
1686
1690 iChannel_rpc++;
1691 } else {
1694 iChannel++;
1695 }
1696 } else {
1699 iChannel_end++;
1700 }
1701 }
1702
1706
1710
1714
1715 B2INFO("Channel's time distribution fitting done.");
1719
1720 B2INFO("Calibrated channel's time distribution filling begins.");
1721
1724 channelId = klmChannel.getKLMChannelNumber();
1727 continue;
1731 }
1732
1734 channelId = klmChannel.getKLMChannelNumber();
1736 continue;
1739 B2DEBUG(20,
"Uncalibrated Estimation " << LogVar(
"Channel", channelId) << LogVar(
"Estimated value",
m_timeShift[channelId]));
1740 }
1741
1742 iChannel_rpc = 0;
1743 iChannel = 0;
1744 iChannel_end = 0;
1746 channelId = klmChannel.getKLMChannelNumber();
1748 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
1749 continue;
1750 }
1751 int iSub = klmChannel.getSubdetector();
1753
1754 int iL = klmChannel.getLayer() - 1;
1757 iChannel_rpc++;
1758 } else {
1760 iChannel++;
1761 }
1762 } else {
1764 iChannel_end++;
1765 }
1766 }
1767
1768
1773
1774
1775
1776
1777
1778 B2INFO("Fourth loop: Calibrated time distribution filling (batched processing)...");
1779
1780 for (const auto& batch : batches) {
1781 B2INFO("Processing batch: " << batch.first);
1783
1785 channelId = klmChannel.getKLMChannelNumber();
1786
1787 if (!batch.second(klmChannel))
1788 continue;
1789
1791 continue;
1792
1793 eventsChannel =
m_evts[channelId];
1794 int iSub = klmChannel.getSubdetector();
1795 int iF, iS, iL, iP, iC;
1796
1798 iF = klmChannel.getSection();
1799 iS = klmChannel.getSector() - 1;
1800 iL = klmChannel.getLayer() - 1;
1801 iP = klmChannel.getPlane();
1802 iC = klmChannel.getStrip() - 1;
1803 } else {
1804 iF = klmChannel.getSection() - 1;
1805 iS = klmChannel.getSector() - 1;
1806 iL = klmChannel.getLayer() - 1;
1807 iP = klmChannel.getPlane() - 1;
1808 iC = klmChannel.getStrip() - 1;
1809 }
1810
1811 TString hn, ht;
1812 TH1F* hc_temp = nullptr;
1813
1815
1817 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1818 ht = Form("Calibrated time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1819 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1822 } else {
1823 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1824 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1825 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1828 }
1829 } else {
1830 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1831 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1832 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1835 }
1836
1837 for (
const Event& event : eventsChannel) {
1838
1840 continue;
1841
1842 double timeHit = event.time();
1844 timeHit = timeHit - event.t0;
1845 if (timeHit <= -400e3)
1846 continue;
1847
1849
1851 double propgationT;
1853 propgationT = event.dist * delayRPCZ;
1854 else
1855 propgationT = event.dist * delayRPCPhi;
1856 double time = timeHit - propgationT -
m_timeShift[channelId];
1857
1859 hc_temp->Fill(time);
1860
1869 }
1870 } else {
1871 double propgationT = event.dist * delayBKLM;
1872 double time = timeHit - propgationT -
m_timeShift[channelId];
1873
1875 hc_temp->Fill(time);
1876
1885 }
1886 }
1887 } else {
1888 double propgationT = event.dist * delayEKLM;
1889 double time = timeHit - propgationT -
m_timeShift[channelId];
1890
1892 hc_temp->Fill(time);
1893
1902 }
1903 }
1904 }
1905
1906 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData) {
1907 delete hc_temp;
1908 continue;
1909 }
1910
1911 TFitResultPtr rc = hc_temp->Fit(
fcn_gaus,
"LESQ");
1912 if (int(rc) == 0) {
1913 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1916 }
1917
1918
1923 }
1924
1926 B2INFO("Batch processed and cleared: " << batch.first);
1927 }
1928
1929
1930 int icChannel_rpc = 0;
1931 int icChannel = 0;
1932 int icChannel_end = 0;
1934 channelId = klmChannel.getKLMChannelNumber();
1935 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1936 continue;
1937
1938 int iSub = klmChannel.getSubdetector();
1940 int iL = klmChannel.getLayer() - 1;
1941
1945 icChannel_rpc++;
1946 } else {
1949 icChannel++;
1950 }
1951 } else {
1954 icChannel_end++;
1955 }
1956 }
1957
1961
1965
1969
1970 B2INFO("Channel's time distribution fitting done.");
1974
1975 B2INFO("Calibrated channel's time distribution filling begins.");
1976
1979 channelId = klmChannel.getKLMChannelNumber();
1982 continue;
1986 }
1987
1989 channelId = klmChannel.getKLMChannelNumber();
1991 continue;
1994 B2DEBUG(20,
"Calibrated Estimation " << LogVar(
"Channel", channelId) << LogVar(
"Estimated value",
m_timeRes[channelId]));
1995 }
1996
1997 icChannel_rpc = 0;
1998 icChannel = 0;
1999 icChannel_end = 0;
2001 channelId = klmChannel.getKLMChannelNumber();
2003 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
2004 continue;
2005 }
2006 int iSub = klmChannel.getSubdetector();
2008
2009 int iL = klmChannel.getLayer() - 1;
2012 icChannel_rpc++;
2013 } else {
2015 icChannel++;
2016 }
2017 } else {
2019 icChannel_end++;
2020 }
2021 }
2022
2023
2024
2025
2026 B2INFO("Fifth pass: Computing di-muon ΔT0 for EventT0 hit resolution calibration...");
2027
2028
2029 struct TrackT0Info {
2030 int charge;
2031 int nHits_BKLM_Scint;
2032 int nHits_BKLM_RPC_Phi;
2033 int nHits_BKLM_RPC_Z;
2034 int nHits_EKLM_Scint;
2035 double sumT0_BKLM_Scint;
2036 double sumT0_BKLM_RPC_Phi;
2037 double sumT0_BKLM_RPC_Z;
2038 double sumT0_EKLM_Scint;
2039
2040 TrackT0Info() : charge(0),
2041 nHits_BKLM_Scint(0),
2042 nHits_BKLM_RPC_Phi(0),
2043 nHits_BKLM_RPC_Z(0),
2044 nHits_EKLM_Scint(0),
2045 sumT0_BKLM_Scint(0.0),
2046 sumT0_BKLM_RPC_Phi(0.0),
2047 sumT0_BKLM_RPC_Z(0.0),
2048 sumT0_EKLM_Scint(0.0) {}
2049 };
2050
2051
2052 std::map<std::pair<int, int>, std::map<int, TrackT0Info>> eventTrackMap;
2053
2054
2055 for (const auto& batch : batches) {
2056 B2INFO("Processing batch for di-muon analysis: " << batch.first);
2058
2059 for (
const auto& channelPair :
m_evts) {
2061 const std::vector<Event>& chEvents = channelPair.second;
2062
2063
2064 int subdetector, section, sector, layer, plane, strip;
2066 chId, &subdetector, §ion, §or, &layer, &plane, &strip);
2067
2068
2069 int iSub = subdetector;
2070 int iL = layer - 1;
2071
2072 for (
const Event& event : chEvents) {
2073
2075 continue;
2076
2077
2078 std::pair<int, int> eventKey(event.Run, event.Events);
2079 int trackIdx = event.nTrack;
2080 int charge = event.Track_Charge;
2081
2082
2083 double timeHit =
event.time() -
m_timeShift[chId];
2084
2085 if (timeHit <= -400e3)
2086 continue;
2087
2088
2089 double propT = 0.0;
2092
2094 propT = event.dist * delayRPCZ;
2095 else
2096 propT = event.dist * delayRPCPhi;
2097 } else {
2098
2099 propT = event.dist * delayBKLM;
2100 }
2101 } else {
2102
2103 propT = event.dist * delayEKLM;
2104 }
2105
2106 double t0_estimate = timeHit - propT;
2107
2108
2109 TrackT0Info& trackInfo = eventTrackMap[eventKey][trackIdx];
2110 trackInfo.charge = charge;
2111
2114
2116 trackInfo.nHits_BKLM_RPC_Z++;
2117 trackInfo.sumT0_BKLM_RPC_Z += t0_estimate;
2118 } else {
2119 trackInfo.nHits_BKLM_RPC_Phi++;
2120 trackInfo.sumT0_BKLM_RPC_Phi += t0_estimate;
2121 }
2122 } else {
2123
2124 trackInfo.nHits_BKLM_Scint++;
2125 trackInfo.sumT0_BKLM_Scint += t0_estimate;
2126 }
2127 } else {
2128 trackInfo.nHits_EKLM_Scint++;
2129 trackInfo.sumT0_EKLM_Scint += t0_estimate;
2130 }
2131 }
2132 }
2133
2135 }
2136
2137 B2INFO("Event-track map built. Processing events for EventT0 histograms...");
2138
2139
2140
2141 double sum_delta2_over_v_BKLM_Scint = 0.0;
2142 double sum_delta2_over_v_BKLM_RPC_Phi = 0.0;
2143 double sum_delta2_over_v_BKLM_RPC_Z = 0.0;
2144 double sum_delta2_over_v_EKLM_Scint = 0.0;
2145
2146 int nDimuon_BKLM_Scint = 0;
2147 int nDimuon_BKLM_RPC_Phi = 0;
2148 int nDimuon_BKLM_RPC_Z = 0;
2149 int nDimuon_EKLM_Scint = 0;
2150
2151 for (const auto& eventPair : eventTrackMap) {
2152 const auto& trackMap = eventPair.second;
2153
2154
2155 if (trackMap.size() != 2)
2156 continue;
2157
2158 auto it1 = trackMap.begin();
2159 auto it2 = trackMap.begin();
2160 ++it2;
2161 const TrackT0Info& track1 = it1->second;
2162 const TrackT0Info& track2 = it2->second;
2163
2164
2165 if (track1.charge * track2.charge >= 0)
2166 continue;
2167
2168
2169 const TrackT0Info& muPlus = (track1.charge > 0) ? track1 : track2;
2170 const TrackT0Info& muMinus = (track1.charge > 0) ? track2 : track1;
2171
2172
2173 if (muPlus.nHits_BKLM_Scint > 0 && muMinus.nHits_BKLM_Scint > 0) {
2174 double t0_plus = muPlus.sumT0_BKLM_Scint / muPlus.nHits_BKLM_Scint;
2175 double t0_minus = muMinus.sumT0_BKLM_Scint / muMinus.nHits_BKLM_Scint;
2176 double deltaT0 = t0_plus - t0_minus;
2177
2178
2179 double v = 1.0 / muPlus.nHits_BKLM_Scint + 1.0 / muMinus.nHits_BKLM_Scint;
2180 int nTotal = muPlus.nHits_BKLM_Scint + muMinus.nHits_BKLM_Scint;
2181
2182 if (v <= 0.0)
2183 continue;
2184
2185
2186 sum_delta2_over_v_BKLM_Scint += (deltaT0 * deltaT0) / v;
2187 nDimuon_BKLM_Scint++;
2188
2189
2193
2194
2200
2201
2202 if (nTotal < 5) {
2204 } else if (nTotal < 15) {
2206 } else {
2208 }
2209 }
2210
2211
2212 if (muPlus.nHits_BKLM_RPC_Phi > 0 && muMinus.nHits_BKLM_RPC_Phi > 0) {
2213 double t0_plus = muPlus.sumT0_BKLM_RPC_Phi / muPlus.nHits_BKLM_RPC_Phi;
2214 double t0_minus = muMinus.sumT0_BKLM_RPC_Phi / muMinus.nHits_BKLM_RPC_Phi;
2215 double deltaT0 = t0_plus - t0_minus;
2216
2217 double v = 1.0 / muPlus.nHits_BKLM_RPC_Phi + 1.0 / muMinus.nHits_BKLM_RPC_Phi;
2218 int nTotal = muPlus.nHits_BKLM_RPC_Phi + muMinus.nHits_BKLM_RPC_Phi;
2219
2220 if (v <= 0.0)
2221 continue;
2222
2223 sum_delta2_over_v_BKLM_RPC_Phi += (deltaT0 * deltaT0) / v;
2224 nDimuon_BKLM_RPC_Phi++;
2225
2229
2230
2236
2237 if (nTotal < 10) {
2239 } else if (nTotal < 30) {
2241 } else {
2243 }
2244 }
2245
2246
2247 if (muPlus.nHits_BKLM_RPC_Z > 0 && muMinus.nHits_BKLM_RPC_Z > 0) {
2248 double t0_plus = muPlus.sumT0_BKLM_RPC_Z / muPlus.nHits_BKLM_RPC_Z;
2249 double t0_minus = muMinus.sumT0_BKLM_RPC_Z / muMinus.nHits_BKLM_RPC_Z;
2250 double deltaT0 = t0_plus - t0_minus;
2251
2252 double v = 1.0 / muPlus.nHits_BKLM_RPC_Z + 1.0 / muMinus.nHits_BKLM_RPC_Z;
2253 int nTotal = muPlus.nHits_BKLM_RPC_Z + muMinus.nHits_BKLM_RPC_Z;
2254
2255 if (v <= 0.0)
2256 continue;
2257
2258 sum_delta2_over_v_BKLM_RPC_Z += (deltaT0 * deltaT0) / v;
2259 nDimuon_BKLM_RPC_Z++;
2260
2264
2265
2271
2272 if (nTotal < 10) {
2274 } else if (nTotal < 30) {
2276 } else {
2278 }
2279 }
2280
2281
2282 if (muPlus.nHits_EKLM_Scint > 0 && muMinus.nHits_EKLM_Scint > 0) {
2283 double t0_plus = muPlus.sumT0_EKLM_Scint / muPlus.nHits_EKLM_Scint;
2284 double t0_minus = muMinus.sumT0_EKLM_Scint / muMinus.nHits_EKLM_Scint;
2285 double deltaT0 = t0_plus - t0_minus;
2286
2287 double v = 1.0 / muPlus.nHits_EKLM_Scint + 1.0 / muMinus.nHits_EKLM_Scint;
2288 int nTotal = muPlus.nHits_EKLM_Scint + muMinus.nHits_EKLM_Scint;
2289
2290 if (v <= 0.0)
2291 continue;
2292
2293 sum_delta2_over_v_EKLM_Scint += (deltaT0 * deltaT0) / v;
2294 nDimuon_EKLM_Scint++;
2295
2299
2300
2306
2307
2308 if (nTotal < 5) {
2310 } else if (nTotal < 15) {
2312 } else {
2314 }
2315 }
2316 }
2317
2318 B2INFO("Di-muon ΔT0 data collected."
2319 << LogVar("BKLM Scint di-muon events", nDimuon_BKLM_Scint)
2320 << LogVar("BKLM RPC Phi di-muon events", nDimuon_BKLM_RPC_Phi)
2321 << LogVar("BKLM RPC Z di-muon events", nDimuon_BKLM_RPC_Z)
2322 << LogVar("EKLM Scint di-muon events", nDimuon_EKLM_Scint));
2323
2324
2325
2326
2327 float sigma_BKLM_Scint = 10.0f;
2328 float sigma_BKLM_Scint_err = 1.0f;
2329 if (nDimuon_BKLM_Scint > 0) {
2330 double sigma2 = sum_delta2_over_v_BKLM_Scint / static_cast<double>(nDimuon_BKLM_Scint);
2331 sigma_BKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2332
2333 sigma_BKLM_Scint_err = sigma_BKLM_Scint / std::sqrt(2.0 * nDimuon_BKLM_Scint);
2334 }
2335
2336 float sigma_RPC_Phi = 10.0f;
2337 float sigma_RPC_Phi_err = 1.0f;
2338 if (nDimuon_BKLM_RPC_Phi > 0) {
2339 double sigma2 = sum_delta2_over_v_BKLM_RPC_Phi / static_cast<double>(nDimuon_BKLM_RPC_Phi);
2340 sigma_RPC_Phi = static_cast<float>(std::sqrt(sigma2));
2341 sigma_RPC_Phi_err = sigma_RPC_Phi / std::sqrt(2.0 * nDimuon_BKLM_RPC_Phi);
2342 }
2343
2344 float sigma_RPC_Z = 10.0f;
2345 float sigma_RPC_Z_err = 1.0f;
2346 if (nDimuon_BKLM_RPC_Z > 0) {
2347 double sigma2 = sum_delta2_over_v_BKLM_RPC_Z / static_cast<double>(nDimuon_BKLM_RPC_Z);
2348 sigma_RPC_Z = static_cast<float>(std::sqrt(sigma2));
2349 sigma_RPC_Z_err = sigma_RPC_Z / std::sqrt(2.0 * nDimuon_BKLM_RPC_Z);
2350 }
2351
2352
2353 float sigma_RPC = 10.0f;
2354 float sigma_RPC_err = 1.0f;
2355 int nDimuon_RPC_total = nDimuon_BKLM_RPC_Phi + nDimuon_BKLM_RPC_Z;
2356 if (nDimuon_RPC_total > 0) {
2357
2358 double w_phi = static_cast<double>(nDimuon_BKLM_RPC_Phi) / nDimuon_RPC_total;
2359 double w_z = static_cast<double>(nDimuon_BKLM_RPC_Z) / nDimuon_RPC_total;
2360 sigma_RPC = w_phi * sigma_RPC_Phi + w_z * sigma_RPC_Z;
2361
2362 sigma_RPC_err = std::sqrt(w_phi * w_phi * sigma_RPC_Phi_err * sigma_RPC_Phi_err +
2363 w_z * w_z * sigma_RPC_Z_err * sigma_RPC_Z_err);
2364 }
2365
2366 float sigma_EKLM_Scint = 10.0f;
2367 float sigma_EKLM_Scint_err = 1.0f;
2368 if (nDimuon_EKLM_Scint > 0) {
2369 double sigma2 = sum_delta2_over_v_EKLM_Scint / static_cast<double>(nDimuon_EKLM_Scint);
2370 sigma_EKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2371 sigma_EKLM_Scint_err = sigma_EKLM_Scint / std::sqrt(2.0 * nDimuon_EKLM_Scint);
2372 }
2373
2374 B2INFO("Extracted per-hit resolutions using event-by-event weighting:"
2375 << LogVar("σ_BKLM_Scint [ns]", sigma_BKLM_Scint) << LogVar("±", sigma_BKLM_Scint_err)
2376 << LogVar("σ_RPC_Phi [ns]", sigma_RPC_Phi) << LogVar("±", sigma_RPC_Phi_err)
2377 << LogVar("σ_RPC_Z [ns]", sigma_RPC_Z) << LogVar("±", sigma_RPC_Z_err)
2378 << LogVar("σ_RPC_combined [ns]", sigma_RPC) << LogVar("±", sigma_RPC_err)
2379 << LogVar("σ_EKLM_Scint [ns]", sigma_EKLM_Scint) << LogVar("±", sigma_EKLM_Scint_err));
2380
2381
2387
2388 B2INFO("EventT0 hit resolution calibration complete and stored in payload.");
2389
2390
2391 eventTrackMap.clear();
2392
2398
2400
2405
2407}
@ 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.