Run algorithm on data.
1120{
1121 int channelId;
1122 gROOT->SetBatch(kTRUE);
1128
1129 fcn_gaus =
new TF1(
"fcn_gaus",
"gaus");
1130 fcn_land =
new TF1(
"fcn_land",
"landau");
1131 fcn_pol1 =
new TF1(
"fcn_pol1",
"pol1");
1132 fcn_const =
new TF1(
"fcn_const",
"pol0");
1133
1134
1137 return result;
1138
1139
1140 std::string name = "time_calibration.root";
1141 int i = 1;
1142 while (1) {
1143 struct stat buffer;
1144 if (stat(name.c_str(), &buffer) != 0)
1145 break;
1146 name = "time_calibration_" + std::to_string(i) + ".root";
1147 i = i + 1;
1148 if (i < 0)
1149 break;
1150 }
1151 m_outFile =
new TFile(name.c_str(),
"recreate");
1153
1154 std::vector<struct Event> eventsChannel;
1155 eventsChannel.clear();
1158
1159 B2INFO("Counting events per channel...");
1160 std::map<KLMChannelNumber, unsigned int> eventCounts;
1162
1163
1164 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsBKLM;
1165 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsEKLM;
1166 KLMChannelIndex klmChannels;
1167
1168 for (KLMChannelIndex& klmChannel : klmChannels) {
1170 m_cFlag[channel] = ChannelCalibrationStatus::c_NotEnoughData;
1171
1172 if (eventCounts.find(channel) == eventCounts.end())
1173 continue;
1174
1175 int nEvents = eventCounts[channel];
1177 B2WARNING("Not enough calibration data collected."
1178 << LogVar("channel", channel)
1179 << LogVar("number of digit", nEvents));
1180 continue;
1181 }
1182
1183 m_cFlag[channel] = ChannelCalibrationStatus::c_FailedFit;
1184
1187 channelsBKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1188 }
1190 channelsEKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
1191 }
1192 }
1193
1194 std::sort(channelsBKLM.begin(), channelsBKLM.end(), compareEventNumber);
1195 std::sort(channelsEKLM.begin(), channelsEKLM.end(), compareEventNumber);
1196
1197
1198 double delayBKLM, delayBKLMError;
1199 double delayEKLM, delayEKLMError;
1200
1201
1206
1207 B2INFO("2D fits complete, data cleared.");
1208
1209
1210 auto isRPCBackward = [](const KLMChannelIndex & ch) {
1214 };
1215
1216 auto isRPCForward = [](const KLMChannelIndex & ch) {
1220 };
1221
1222 auto isBKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1226 };
1227
1228 auto isBKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1232 };
1233
1234 auto isEKLMScintillatorBackward = [](const KLMChannelIndex & ch) {
1237 };
1238
1239 auto isEKLMScintillatorForward = [](const KLMChannelIndex & ch) {
1242 };
1243
1244 std::vector<std::pair<std::string, std::function<bool(const KLMChannelIndex&)>>> batches = {
1245 {"RPC Backward", isRPCBackward},
1246 {"RPC Forward", isRPCForward},
1247 {"BKLM Scintillator Backward", isBKLMScintillatorBackward},
1248 {"BKLM Scintillator Forward", isBKLMScintillatorForward},
1249 {"EKLM Scintillator Backward", isEKLMScintillatorBackward},
1250 {"EKLM Scintillator Forward", isEKLMScintillatorForward}
1251 };
1252
1253
1254
1255
1256
1257 B2INFO("First loop: Computing global statistics (batched processing)...");
1258
1259 TString iFstring[2] = {"Backward", "Forward"};
1260 TString iPstring[2] = {"ZReadout", "PhiReadout"};
1261 int nBin = 80;
1262 int nBin_scint = 80;
1263
1264 for (const auto& batch : batches) {
1265 B2INFO("Processing batch for global stats: " << batch.first);
1267
1269 channelId = klmChannel.getKLMChannelNumber();
1270
1271 if (!batch.second(klmChannel))
1272 continue;
1273
1274 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1275 continue;
1276
1278 continue;
1279
1280 eventsChannel =
m_evts[channelId];
1281 int iSub = klmChannel.getSubdetector();
1283
1284
1285 for (
const Event& event : eventsChannel) {
1286
1288 continue;
1289
1290 XYZVector diffD = XYZVector(event.diffDistX, event.diffDistY, event.diffDistZ);
1292
1293 double timeHit = event.time();
1295 timeHit = timeHit - event.t0;
1296
1297 if (timeHit <= -400e3)
1298 continue;
1299
1301
1304 } else {
1306 }
1307 } else {
1309 }
1310 }
1311 }
1312
1314 B2INFO("Batch processed and cleared: " << batch.first);
1315 }
1316
1317
1322
1323 B2INFO("Global Mean for Raw." << LogVar("RPC", tmpMean_rpc_global)
1324 << LogVar("Scint BKLM", tmpMean_scint_global)
1325 << LogVar("Scint EKLM", tmpMean_scint_global_end));
1326
1327
1328
1329
1330
1331 B2INFO("Second pass: Computing per-channel time shifts (batched processing)...");
1332
1333 for (const auto& batch : batches) {
1334 B2INFO("Processing batch for time shifts: " << batch.first);
1336
1338 channelId = klmChannel.getKLMChannelNumber();
1339
1340 if (!batch.second(klmChannel))
1341 continue;
1342
1343 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1344 continue;
1345
1347 continue;
1348
1349 eventsChannel =
m_evts[channelId];
1350 int iSub = klmChannel.getSubdetector();
1351 int iF, iS, iL, iP, iC;
1352
1354 iF = klmChannel.getSection();
1355 iS = klmChannel.getSector() - 1;
1356 iL = klmChannel.getLayer() - 1;
1357 iP = klmChannel.getPlane();
1358 iC = klmChannel.getStrip() - 1;
1359 } else {
1360 iF = klmChannel.getSection() - 1;
1361 iS = klmChannel.getSector() - 1;
1362 iL = klmChannel.getLayer() - 1;
1363 iP = klmChannel.getPlane() - 1;
1364 iC = klmChannel.getStrip() - 1;
1365 }
1366
1367
1368 TString hn, ht;
1369 TH1F* h_temp_tc = nullptr;
1370
1372
1374 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1375 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1376 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1378 } else {
1379 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1380 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1381 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1384 }
1385 } else {
1386 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_tc_end", iF, iS, iL, iP, iC);
1387 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1388 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1391 }
1392
1393 for (
const Event& event : eventsChannel) {
1394
1396 continue;
1397
1398 double timeHit = event.time();
1400 timeHit = timeHit - event.t0;
1401 if (timeHit <= -400e3)
1402 continue;
1403 h_temp_tc->Fill(timeHit);
1404 }
1405
1407 double tmpMean_channel =
fcn_gaus->GetParameter(1);
1408
1410
1412 m_timeShift[channelId] = tmpMean_channel - tmpMean_rpc_global;
1413 } else {
1414 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global;
1415 }
1416 } else {
1417 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global_end;
1418 }
1419
1420 delete h_temp_tc;
1421 }
1422
1424 B2INFO("Batch processed and cleared: " << batch.first);
1425 }
1426
1430 B2INFO("Effective Light m_timeShift obtained.");
1431
1432
1437
1438 B2INFO("Effective light speed fitting.");
1439
1440
1442 double fittedDelayRPCPhi =
fcn_pol1->GetParameter(1);
1443 double e_slope_rpc_phi =
fcn_pol1->GetParError(1);
1444
1446 double fittedDelayRPCZ =
fcn_pol1->GetParameter(1);
1447 double e_slope_rpc_z =
fcn_pol1->GetParError(1);
1448
1449
1450 double delayRPCPhi, delayRPCZ;
1454 B2INFO(
"Using fixed RPC propagation delay: " <<
m_fixedRPCDelay <<
" ns/cm (c_eff = 0.5c)"
1455 << LogVar("Fitted phi (not used)", fittedDelayRPCPhi)
1456 << LogVar("Fitted Z (not used)", fittedDelayRPCZ));
1457 } else {
1458 delayRPCPhi = fittedDelayRPCPhi;
1459 delayRPCZ = fittedDelayRPCZ;
1460 }
1461
1463 double slope_scint_phi =
fcn_pol1->GetParameter(1);
1464 double e_slope_scint_phi =
fcn_pol1->GetParError(1);
1465
1467 double slope_scint_z =
fcn_pol1->GetParameter(1);
1468 double e_slope_scint_z =
fcn_pol1->GetParError(1);
1469
1471 double slope_scint_plane1_end =
fcn_pol1->GetParameter(1);
1472 double e_slope_scint_plane1_end =
fcn_pol1->GetParError(1);
1473
1475 double slope_scint_plane2_end =
fcn_pol1->GetParameter(1);
1476 double e_slope_scint_plane2_end =
fcn_pol1->GetParError(1);
1477
1478 TString logStr_phi, logStr_z;
1480 logStr_phi = Form("%.4f ns/cm (fixed)", delayRPCPhi);
1481 logStr_z = Form("%.4f ns/cm (fixed)", delayRPCZ);
1482 B2INFO("Delay in RPCs (using fixed value):"
1483 << LogVar("Used Value (phi readout)", logStr_phi.Data())
1484 << LogVar("Used Value (z readout)", logStr_z.Data()));
1485 } else {
1486 logStr_phi = Form("%.4f +/- %.4f ns/cm", delayRPCPhi, e_slope_rpc_phi);
1487 logStr_z = Form("%.4f +/- %.4f ns/cm", delayRPCZ, e_slope_rpc_z);
1488 B2INFO("Delay in RPCs:"
1489 << LogVar("Fitted Value (phi readout)", logStr_phi.Data())
1490 << LogVar("Fitted Value (z readout)", logStr_z.Data()));
1491 }
1492 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_phi, e_slope_scint_phi);
1493 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_z, e_slope_scint_z);
1494 B2INFO("Delay in BKLM scintillators:"
1495 << LogVar("Fitted Value (phi readout) ", logStr_phi.Data())
1496 << LogVar("Fitted Value (z readout) ", logStr_z.Data()));
1497 logStr_phi = Form("%.4f +/- %.4f ns/cm", slope_scint_plane1_end,
1498 e_slope_scint_plane1_end);
1499 logStr_z = Form("%.4f +/- %.4f ns/cm", slope_scint_plane2_end,
1500 e_slope_scint_plane2_end);
1501 B2INFO("Delay in EKLM scintillators:"
1502 << LogVar("Fitted Value (plane1 readout) ", logStr_phi.Data())
1503 << LogVar("Fitted Value (plane2 readout) ", logStr_z.Data()));
1504
1505 logStr_z = Form("%.4f +/- %.4f ns/cm", delayBKLM, delayBKLMError);
1506 B2INFO("Delay in BKLM scintillators:"
1507 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1508 logStr_z = Form("%.4f +/- %.4f ns/cm", delayEKLM, delayEKLMError);
1509 B2INFO("Delay in EKLM scintillators:"
1510 << LogVar("Fitted Value (2d fit) ", logStr_z.Data()));
1511
1516
1517
1518
1519
1520
1521 B2INFO("Third loop: Time distribution filling (batched processing)...");
1522
1523 for (const auto& batch : batches) {
1524 B2INFO("Processing batch: " << batch.first);
1526
1528 channelId = klmChannel.getKLMChannelNumber();
1529
1530 if (!batch.second(klmChannel))
1531 continue;
1532
1533 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1534 continue;
1535
1537 continue;
1538
1539 eventsChannel =
m_evts[channelId];
1540 int iSub = klmChannel.getSubdetector();
1541 int iF, iS, iL, iP, iC;
1542
1544 iF = klmChannel.getSection();
1545 iS = klmChannel.getSector() - 1;
1546 iL = klmChannel.getLayer() - 1;
1547 iP = klmChannel.getPlane();
1548 iC = klmChannel.getStrip() - 1;
1549 } else {
1550 iF = klmChannel.getSection() - 1;
1551 iS = klmChannel.getSector() - 1;
1552 iL = klmChannel.getLayer() - 1;
1553 iP = klmChannel.getPlane() - 1;
1554 iC = klmChannel.getStrip() - 1;
1555 }
1556
1557
1558 TString hn, ht;
1559 TH1F* h_temp = nullptr;
1560
1562
1564 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1565 ht = Form("Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1566 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1568 } else {
1569 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1570 ht = Form("time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1571 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1574 }
1575 } else {
1576 hn = Form("h_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1577 ht = Form("Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1578 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1581 }
1582
1583
1584 for (
const Event& event : eventsChannel) {
1585
1587 continue;
1588
1589 double timeHit = event.time();
1591 timeHit = timeHit - event.t0;
1592 if (timeHit <= -400e3)
1593 continue;
1594
1596
1598 double propgationT;
1600 propgationT = event.dist * delayRPCZ;
1601 else
1602 propgationT = event.dist * delayRPCPhi;
1603 double time = timeHit - propgationT;
1604
1606 h_temp->Fill(time);
1607
1616 }
1617 } else {
1618 double propgationT = event.dist * delayBKLM;
1619 double time = timeHit - propgationT;
1620
1622 h_temp->Fill(time);
1623
1632 }
1633 }
1634 } else {
1635 double propgationT = event.dist * delayEKLM;
1636 double time = timeHit - propgationT;
1637
1639 h_temp->Fill(time);
1640
1649 }
1650 }
1651 }
1652
1653 TFitResultPtr r = h_temp->Fit(
fcn_gaus,
"LESQ");
1654 if (int(r) == 0) {
1655 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1658 }
1659
1660
1665 }
1666
1668 B2INFO("Batch processed and cleared: " << batch.first);
1669 }
1670
1671 B2INFO("Original filling done.");
1672
1673
1674 int iChannel_rpc = 0;
1675 int iChannel = 0;
1676 int iChannel_end = 0;
1678 channelId = klmChannel.getKLMChannelNumber();
1679 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1680 continue;
1681
1682 int iSub = klmChannel.getSubdetector();
1684 int iL = klmChannel.getLayer() - 1;
1685
1689 iChannel_rpc++;
1690 } else {
1693 iChannel++;
1694 }
1695 } else {
1698 iChannel_end++;
1699 }
1700 }
1701
1705
1709
1713
1714 B2INFO("Channel's time distribution fitting done.");
1718
1719 B2INFO("Calibrated channel's time distribution filling begins.");
1720
1723 channelId = klmChannel.getKLMChannelNumber();
1726 continue;
1730 }
1731
1733 channelId = klmChannel.getKLMChannelNumber();
1735 continue;
1738 B2DEBUG(20,
"Uncalibrated Estimation " << LogVar(
"Channel", channelId) << LogVar(
"Estimated value",
m_timeShift[channelId]));
1739 }
1740
1741 iChannel_rpc = 0;
1742 iChannel = 0;
1743 iChannel_end = 0;
1745 channelId = klmChannel.getKLMChannelNumber();
1747 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
1748 continue;
1749 }
1750 int iSub = klmChannel.getSubdetector();
1752
1753 int iL = klmChannel.getLayer() - 1;
1756 iChannel_rpc++;
1757 } else {
1759 iChannel++;
1760 }
1761 } else {
1763 iChannel_end++;
1764 }
1765 }
1766
1767
1772
1773
1774
1775
1776
1777 B2INFO("Fourth loop: Calibrated time distribution filling (batched processing)...");
1778
1779 for (const auto& batch : batches) {
1780 B2INFO("Processing batch: " << batch.first);
1782
1784 channelId = klmChannel.getKLMChannelNumber();
1785
1786 if (!batch.second(klmChannel))
1787 continue;
1788
1790 continue;
1791
1792 eventsChannel =
m_evts[channelId];
1793 int iSub = klmChannel.getSubdetector();
1794 int iF, iS, iL, iP, iC;
1795
1797 iF = klmChannel.getSection();
1798 iS = klmChannel.getSector() - 1;
1799 iL = klmChannel.getLayer() - 1;
1800 iP = klmChannel.getPlane();
1801 iC = klmChannel.getStrip() - 1;
1802 } else {
1803 iF = klmChannel.getSection() - 1;
1804 iS = klmChannel.getSector() - 1;
1805 iL = klmChannel.getLayer() - 1;
1806 iP = klmChannel.getPlane() - 1;
1807 iC = klmChannel.getStrip() - 1;
1808 }
1809
1810 TString hn, ht;
1811 TH1F* hc_temp = nullptr;
1812
1814
1816 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1817 ht = Form("Calibrated time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1818 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1821 } else {
1822 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1823 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1824 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1827 }
1828 } else {
1829 hn = Form("hc_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1830 ht = Form("Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1831 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1834 }
1835
1836 for (
const Event& event : eventsChannel) {
1837
1839 continue;
1840
1841 double timeHit = event.time();
1843 timeHit = timeHit - event.t0;
1844 if (timeHit <= -400e3)
1845 continue;
1846
1848
1850 double propgationT;
1852 propgationT = event.dist * delayRPCZ;
1853 else
1854 propgationT = event.dist * delayRPCPhi;
1855 double time = timeHit - propgationT -
m_timeShift[channelId];
1856
1858 hc_temp->Fill(time);
1859
1868 }
1869 } else {
1870 double propgationT = event.dist * delayBKLM;
1871 double time = timeHit - propgationT -
m_timeShift[channelId];
1872
1874 hc_temp->Fill(time);
1875
1884 }
1885 }
1886 } else {
1887 double propgationT = event.dist * delayEKLM;
1888 double time = timeHit - propgationT -
m_timeShift[channelId];
1889
1891 hc_temp->Fill(time);
1892
1901 }
1902 }
1903 }
1904
1905 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData) {
1906 delete hc_temp;
1907 continue;
1908 }
1909
1910 TFitResultPtr rc = hc_temp->Fit(
fcn_gaus,
"LESQ");
1911 if (int(rc) == 0) {
1912 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1915 }
1916
1917
1922 }
1923
1925 B2INFO("Batch processed and cleared: " << batch.first);
1926 }
1927
1928
1929 int icChannel_rpc = 0;
1930 int icChannel = 0;
1931 int icChannel_end = 0;
1933 channelId = klmChannel.getKLMChannelNumber();
1934 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1935 continue;
1936
1937 int iSub = klmChannel.getSubdetector();
1939 int iL = klmChannel.getLayer() - 1;
1940
1944 icChannel_rpc++;
1945 } else {
1948 icChannel++;
1949 }
1950 } else {
1953 icChannel_end++;
1954 }
1955 }
1956
1960
1964
1968
1969 B2INFO("Channel's time distribution fitting done.");
1973
1974 B2INFO("Calibrated channel's time distribution filling begins.");
1975
1978 channelId = klmChannel.getKLMChannelNumber();
1981 continue;
1985 }
1986
1988 channelId = klmChannel.getKLMChannelNumber();
1990 continue;
1993 B2DEBUG(20,
"Calibrated Estimation " << LogVar(
"Channel", channelId) << LogVar(
"Estimated value",
m_timeRes[channelId]));
1994 }
1995
1996 icChannel_rpc = 0;
1997 icChannel = 0;
1998 icChannel_end = 0;
2000 channelId = klmChannel.getKLMChannelNumber();
2002 B2ERROR("!!! Not All Channels Calibration Constant Set. Error Happened on " << LogVar("Channel", channelId));
2003 continue;
2004 }
2005 int iSub = klmChannel.getSubdetector();
2007
2008 int iL = klmChannel.getLayer() - 1;
2011 icChannel_rpc++;
2012 } else {
2014 icChannel++;
2015 }
2016 } else {
2018 icChannel_end++;
2019 }
2020 }
2021
2022
2023
2024
2025 B2INFO("Fifth pass: Computing di-muon ΔT0 for EventT0 hit resolution calibration...");
2026
2027
2028 struct TrackT0Info {
2029 int charge;
2030 int nHits_BKLM_Scint;
2031 int nHits_BKLM_RPC_Phi;
2032 int nHits_BKLM_RPC_Z;
2033 int nHits_EKLM_Scint;
2034 double sumT0_BKLM_Scint;
2035 double sumT0_BKLM_RPC_Phi;
2036 double sumT0_BKLM_RPC_Z;
2037 double sumT0_EKLM_Scint;
2038
2039 TrackT0Info() : charge(0),
2040 nHits_BKLM_Scint(0),
2041 nHits_BKLM_RPC_Phi(0),
2042 nHits_BKLM_RPC_Z(0),
2043 nHits_EKLM_Scint(0),
2044 sumT0_BKLM_Scint(0.0),
2045 sumT0_BKLM_RPC_Phi(0.0),
2046 sumT0_BKLM_RPC_Z(0.0),
2047 sumT0_EKLM_Scint(0.0) {}
2048 };
2049
2050
2051 std::map<std::pair<int, int>, std::map<int, TrackT0Info>> eventTrackMap;
2052
2053
2054 for (const auto& batch : batches) {
2055 B2INFO("Processing batch for di-muon analysis: " << batch.first);
2057
2058 for (
const auto& channelPair :
m_evts) {
2060 const std::vector<Event>& chEvents = channelPair.second;
2061
2062
2063 int subdetector, section, sector, layer, plane, strip;
2065 chId, &subdetector, §ion, §or, &layer, &plane, &strip);
2066
2067
2068 int iSub = subdetector;
2069 int iL = layer - 1;
2070
2071 for (
const Event& event : chEvents) {
2072
2074 continue;
2075
2076
2077 std::pair<int, int> eventKey(event.Run, event.Events);
2078 int trackIdx = event.nTrack;
2079 int charge = event.Track_Charge;
2080
2081
2082 double timeHit =
event.time() -
m_timeShift[chId];
2083
2084 if (timeHit <= -400e3)
2085 continue;
2086
2087
2088 double propT = 0.0;
2091
2093 propT = event.dist * delayRPCZ;
2094 else
2095 propT = event.dist * delayRPCPhi;
2096 } else {
2097
2098 propT = event.dist * delayBKLM;
2099 }
2100 } else {
2101
2102 propT = event.dist * delayEKLM;
2103 }
2104
2105 double t0_estimate = timeHit - propT;
2106
2107
2108 TrackT0Info& trackInfo = eventTrackMap[eventKey][trackIdx];
2109 trackInfo.charge = charge;
2110
2113
2115 trackInfo.nHits_BKLM_RPC_Z++;
2116 trackInfo.sumT0_BKLM_RPC_Z += t0_estimate;
2117 } else {
2118 trackInfo.nHits_BKLM_RPC_Phi++;
2119 trackInfo.sumT0_BKLM_RPC_Phi += t0_estimate;
2120 }
2121 } else {
2122
2123 trackInfo.nHits_BKLM_Scint++;
2124 trackInfo.sumT0_BKLM_Scint += t0_estimate;
2125 }
2126 } else {
2127 trackInfo.nHits_EKLM_Scint++;
2128 trackInfo.sumT0_EKLM_Scint += t0_estimate;
2129 }
2130 }
2131 }
2132
2134 }
2135
2136 B2INFO("Event-track map built. Processing events for EventT0 histograms...");
2137
2138
2139
2140 double sum_delta2_over_v_BKLM_Scint = 0.0;
2141 double sum_delta2_over_v_BKLM_RPC_Phi = 0.0;
2142 double sum_delta2_over_v_BKLM_RPC_Z = 0.0;
2143 double sum_delta2_over_v_EKLM_Scint = 0.0;
2144
2145 int nDimuon_BKLM_Scint = 0;
2146 int nDimuon_BKLM_RPC_Phi = 0;
2147 int nDimuon_BKLM_RPC_Z = 0;
2148 int nDimuon_EKLM_Scint = 0;
2149
2150 for (const auto& eventPair : eventTrackMap) {
2151 const auto& trackMap = eventPair.second;
2152
2153
2154 if (trackMap.size() != 2)
2155 continue;
2156
2157 auto it1 = trackMap.begin();
2158 auto it2 = trackMap.begin();
2159 ++it2;
2160 const TrackT0Info& track1 = it1->second;
2161 const TrackT0Info& track2 = it2->second;
2162
2163
2164 if (track1.charge * track2.charge >= 0)
2165 continue;
2166
2167
2168 const TrackT0Info& muPlus = (track1.charge > 0) ? track1 : track2;
2169 const TrackT0Info& muMinus = (track1.charge > 0) ? track2 : track1;
2170
2171
2172 if (muPlus.nHits_BKLM_Scint > 0 && muMinus.nHits_BKLM_Scint > 0) {
2173 double t0_plus = muPlus.sumT0_BKLM_Scint / muPlus.nHits_BKLM_Scint;
2174 double t0_minus = muMinus.sumT0_BKLM_Scint / muMinus.nHits_BKLM_Scint;
2175 double deltaT0 = t0_plus - t0_minus;
2176
2177
2178 double v = 1.0 / muPlus.nHits_BKLM_Scint + 1.0 / muMinus.nHits_BKLM_Scint;
2179 int nTotal = muPlus.nHits_BKLM_Scint + muMinus.nHits_BKLM_Scint;
2180
2181 if (v <= 0.0)
2182 continue;
2183
2184
2185 sum_delta2_over_v_BKLM_Scint += (deltaT0 * deltaT0) / v;
2186 nDimuon_BKLM_Scint++;
2187
2188
2192
2193
2199
2200
2201 if (nTotal < 5) {
2203 } else if (nTotal < 15) {
2205 } else {
2207 }
2208 }
2209
2210
2211 if (muPlus.nHits_BKLM_RPC_Phi > 0 && muMinus.nHits_BKLM_RPC_Phi > 0) {
2212 double t0_plus = muPlus.sumT0_BKLM_RPC_Phi / muPlus.nHits_BKLM_RPC_Phi;
2213 double t0_minus = muMinus.sumT0_BKLM_RPC_Phi / muMinus.nHits_BKLM_RPC_Phi;
2214 double deltaT0 = t0_plus - t0_minus;
2215
2216 double v = 1.0 / muPlus.nHits_BKLM_RPC_Phi + 1.0 / muMinus.nHits_BKLM_RPC_Phi;
2217 int nTotal = muPlus.nHits_BKLM_RPC_Phi + muMinus.nHits_BKLM_RPC_Phi;
2218
2219 if (v <= 0.0)
2220 continue;
2221
2222 sum_delta2_over_v_BKLM_RPC_Phi += (deltaT0 * deltaT0) / v;
2223 nDimuon_BKLM_RPC_Phi++;
2224
2228
2229
2235
2236 if (nTotal < 10) {
2238 } else if (nTotal < 30) {
2240 } else {
2242 }
2243 }
2244
2245
2246 if (muPlus.nHits_BKLM_RPC_Z > 0 && muMinus.nHits_BKLM_RPC_Z > 0) {
2247 double t0_plus = muPlus.sumT0_BKLM_RPC_Z / muPlus.nHits_BKLM_RPC_Z;
2248 double t0_minus = muMinus.sumT0_BKLM_RPC_Z / muMinus.nHits_BKLM_RPC_Z;
2249 double deltaT0 = t0_plus - t0_minus;
2250
2251 double v = 1.0 / muPlus.nHits_BKLM_RPC_Z + 1.0 / muMinus.nHits_BKLM_RPC_Z;
2252 int nTotal = muPlus.nHits_BKLM_RPC_Z + muMinus.nHits_BKLM_RPC_Z;
2253
2254 if (v <= 0.0)
2255 continue;
2256
2257 sum_delta2_over_v_BKLM_RPC_Z += (deltaT0 * deltaT0) / v;
2258 nDimuon_BKLM_RPC_Z++;
2259
2263
2264
2270
2271 if (nTotal < 10) {
2273 } else if (nTotal < 30) {
2275 } else {
2277 }
2278 }
2279
2280
2281 if (muPlus.nHits_EKLM_Scint > 0 && muMinus.nHits_EKLM_Scint > 0) {
2282 double t0_plus = muPlus.sumT0_EKLM_Scint / muPlus.nHits_EKLM_Scint;
2283 double t0_minus = muMinus.sumT0_EKLM_Scint / muMinus.nHits_EKLM_Scint;
2284 double deltaT0 = t0_plus - t0_minus;
2285
2286 double v = 1.0 / muPlus.nHits_EKLM_Scint + 1.0 / muMinus.nHits_EKLM_Scint;
2287 int nTotal = muPlus.nHits_EKLM_Scint + muMinus.nHits_EKLM_Scint;
2288
2289 if (v <= 0.0)
2290 continue;
2291
2292 sum_delta2_over_v_EKLM_Scint += (deltaT0 * deltaT0) / v;
2293 nDimuon_EKLM_Scint++;
2294
2298
2299
2305
2306
2307 if (nTotal < 5) {
2309 } else if (nTotal < 15) {
2311 } else {
2313 }
2314 }
2315 }
2316
2317 B2INFO("Di-muon ΔT0 data collected."
2318 << LogVar("BKLM Scint di-muon events", nDimuon_BKLM_Scint)
2319 << LogVar("BKLM RPC Phi di-muon events", nDimuon_BKLM_RPC_Phi)
2320 << LogVar("BKLM RPC Z di-muon events", nDimuon_BKLM_RPC_Z)
2321 << LogVar("EKLM Scint di-muon events", nDimuon_EKLM_Scint));
2322
2323
2324
2325
2326 float sigma_BKLM_Scint = 10.0f;
2327 float sigma_BKLM_Scint_err = 1.0f;
2328 if (nDimuon_BKLM_Scint > 0) {
2329 double sigma2 = sum_delta2_over_v_BKLM_Scint / static_cast<double>(nDimuon_BKLM_Scint);
2330 sigma_BKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2331
2332 sigma_BKLM_Scint_err = sigma_BKLM_Scint / std::sqrt(2.0 * nDimuon_BKLM_Scint);
2333 }
2334
2335 float sigma_RPC_Phi = 10.0f;
2336 float sigma_RPC_Phi_err = 1.0f;
2337 if (nDimuon_BKLM_RPC_Phi > 0) {
2338 double sigma2 = sum_delta2_over_v_BKLM_RPC_Phi / static_cast<double>(nDimuon_BKLM_RPC_Phi);
2339 sigma_RPC_Phi = static_cast<float>(std::sqrt(sigma2));
2340 sigma_RPC_Phi_err = sigma_RPC_Phi / std::sqrt(2.0 * nDimuon_BKLM_RPC_Phi);
2341 }
2342
2343 float sigma_RPC_Z = 10.0f;
2344 float sigma_RPC_Z_err = 1.0f;
2345 if (nDimuon_BKLM_RPC_Z > 0) {
2346 double sigma2 = sum_delta2_over_v_BKLM_RPC_Z / static_cast<double>(nDimuon_BKLM_RPC_Z);
2347 sigma_RPC_Z = static_cast<float>(std::sqrt(sigma2));
2348 sigma_RPC_Z_err = sigma_RPC_Z / std::sqrt(2.0 * nDimuon_BKLM_RPC_Z);
2349 }
2350
2351
2352 float sigma_RPC = 10.0f;
2353 float sigma_RPC_err = 1.0f;
2354 int nDimuon_RPC_total = nDimuon_BKLM_RPC_Phi + nDimuon_BKLM_RPC_Z;
2355 if (nDimuon_RPC_total > 0) {
2356
2357 double w_phi = static_cast<double>(nDimuon_BKLM_RPC_Phi) / nDimuon_RPC_total;
2358 double w_z = static_cast<double>(nDimuon_BKLM_RPC_Z) / nDimuon_RPC_total;
2359 sigma_RPC = w_phi * sigma_RPC_Phi + w_z * sigma_RPC_Z;
2360
2361 sigma_RPC_err = std::sqrt(w_phi * w_phi * sigma_RPC_Phi_err * sigma_RPC_Phi_err +
2362 w_z * w_z * sigma_RPC_Z_err * sigma_RPC_Z_err);
2363 }
2364
2365 float sigma_EKLM_Scint = 10.0f;
2366 float sigma_EKLM_Scint_err = 1.0f;
2367 if (nDimuon_EKLM_Scint > 0) {
2368 double sigma2 = sum_delta2_over_v_EKLM_Scint / static_cast<double>(nDimuon_EKLM_Scint);
2369 sigma_EKLM_Scint = static_cast<float>(std::sqrt(sigma2));
2370 sigma_EKLM_Scint_err = sigma_EKLM_Scint / std::sqrt(2.0 * nDimuon_EKLM_Scint);
2371 }
2372
2373 B2INFO("Extracted per-hit resolutions using event-by-event weighting:"
2374 << LogVar("σ_BKLM_Scint [ns]", sigma_BKLM_Scint) << LogVar("±", sigma_BKLM_Scint_err)
2375 << LogVar("σ_RPC_Phi [ns]", sigma_RPC_Phi) << LogVar("±", sigma_RPC_Phi_err)
2376 << LogVar("σ_RPC_Z [ns]", sigma_RPC_Z) << LogVar("±", sigma_RPC_Z_err)
2377 << LogVar("σ_RPC_combined [ns]", sigma_RPC) << LogVar("±", sigma_RPC_err)
2378 << LogVar("σ_EKLM_Scint [ns]", sigma_EKLM_Scint) << LogVar("±", sigma_EKLM_Scint_err));
2379
2380
2386
2387 B2INFO("EventT0 hit resolution calibration complete and stored in payload.");
2388
2389
2390 eventTrackMap.clear();
2391
2397
2399
2404
2406}
@ 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.