Belle II Software development
EventT0Combiner.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <reconstruction/modules/EventT0Combiner/EventT0Combiner.h>
10
11#include <cmath>
12
13using namespace Belle2;
14
15REG_MODULE(EventT0Combiner);
16
18{
19 setDescription("Module to combine the EventT0 values from multiple sub-detectors");
20
22}
23
25{
26 if (!m_eventT0.isValid()) {
27 B2DEBUG(20, "EventT0 object not created, cannot do EventT0 combination");
28 return;
29 }
30
31 // NOT checking for m_eventT0.hasEventT0() here, as this would only indicate that so far no EventT0 has been set.
32 // However, this does not mean that we can't set one from the temporary values.
33 // But of course nothing can be done if no temporary EventT0s are present.
34 if (m_eventT0->getTemporaryEventT0s().empty()) {
35 B2DEBUG(20, "No temporary EventT0s available, can't chose the best one.");
36 return;
37 }
38
39 // We have an SVD based EventT0 and it currently is set as *THE* EventT0 -> nothing to do
40 if (m_eventT0->isSVDEventT0()) {
41 B2DEBUG(20, "EventT0 already based on SVD information, nothing to do.");
42 return;
43 }
44
45 // We have an SVD based EventT0 but it currently is *NOT* set as *THE* EventT0 -> set it as *THE* EventT0
46 // This might happen e.g. during calibration if the CDCFullGridChi2 ("chi2", see below) is run after the SVD EventT0 algorithm
47 if (m_eventT0->hasTemporaryEventT0(Const::SVD)) {
48 const auto& bestSVDT0 = m_eventT0->getBestSVDTemporaryEventT0();
49 m_eventT0->setEventT0(*bestSVDT0);
50 B2DEBUG(20, "EventT0 is set to SVD EventT0.");
51 return;
52 }
53
54 // If we don't have an SVD based EventT0, the second choice is the EventT0 estimate using CDC information calculabed by the
55 // FullGridChi2TrackTimeExtractor method. In principle, this algorithm can create EventT0 estimates using two methods:
56 // "grid" and "chi2". We are only interested in the latter one.
57 // If no SVD based EventT0 is present, but a CDC based one using the "chi2" algorithm is available -> nothing to do
58 if (m_eventT0->isCDCEventT0()) {
59 const auto& bestCDCT0 = m_eventT0->getBestCDCTemporaryEventT0();
60 if ((*bestCDCT0).algorithm == "chi2") {
61 B2DEBUG(20, "Using CDC chi2 EventT0.");
62 return;
63 }
64 B2DEBUG(20, "Current EventT0 is based on CDC, but it's not the chi2 value. Continue Search.");
65 }
66
67 // No CDC chi2 EventT0 present -> try to combine ECL and CDC hit based EventT0
68 // First, clear the EventT0 so that EventT0::hasEventT0() will return false
69 m_eventT0->clearEventT0();
70 const auto& bestECLT0 = m_eventT0->getBestECLTemporaryEventT0();
71 const auto& cdcT0Candidates = m_eventT0->getTemporaryEventT0s(Const::CDC);
72 const auto& hitBasedCDCT0Candidate = std::find_if(cdcT0Candidates.begin(), cdcT0Candidates.end(), [](const auto & a) { return a.algorithm == "hit based";});
73
74 // Strategy in case none of the SVD based or the CDC chi2 based EventT0 values is available:
75 // 1) If we have both an EventT0 estimate from ECL and a CDC hit based value, combine the two
76 // 2) If we only have one of the two, take that value
77 // 3) If we don't have either, we have a problem -> issue a B2WARNING and clear the EventT0
78 // If we arrive at 3), this means that we could only have TOP EventT0, or an EventT0 from a
79 // CDC based algorithm other than "hit based" or "chi2", and so far we don't want to use these.
80 if (bestECLT0 and hitBasedCDCT0Candidate != cdcT0Candidates.end()) {
81 B2DEBUG(20, "Combining ECL EventT0 and CDC hit based EventT0.");
82 const auto combined = computeCombination({ *bestECLT0, *hitBasedCDCT0Candidate });
83 m_eventT0->setEventT0(combined);
84 return;
85 } else if (bestECLT0 and hitBasedCDCT0Candidate == cdcT0Candidates.end()) {
86 B2DEBUG(20, "Using ECL EventT0, as CDC hit based EventT0 is not available.");
87 m_eventT0->setEventT0(*bestECLT0);
88 return;
89 } else if (hitBasedCDCT0Candidate != cdcT0Candidates.end() and not bestECLT0) {
90 B2DEBUG(20, "Using CDC hit based EventT0, as ECL EventT0 is not available.");
91 m_eventT0->setEventT0(*hitBasedCDCT0Candidate);
92 return;
93 } else {
94 B2DEBUG(20, "There is no EventT0 from neither \n" \
95 " * the SVD based algorithm\n" \
96 " * the CDC based chi^2 algorithm\n" \
97 " * the CDC based hit-based algorithm\n" \
98 " * the ECL algorithm.\n" \
99 "Thus, no EventT0 value can be calculated.");
100 }
101
102
103}
104
105EventT0::EventT0Component EventT0CombinerModule::computeCombination(std::vector<EventT0::EventT0Component> measurements) const
106{
107 if (measurements.size() == 0) {
108 B2FATAL("Need at least one EvenT0 Measurement to do a sensible combination.");
109 }
110
111 double eventT0 = 0.0f;
112 double preFactor = 0.0f;
113
114 Const::DetectorSet usedDetectorSet;
115
116 for (auto const& meas : measurements) {
117 usedDetectorSet += meas.detectorSet;
118 const double oneOverUncertaintySquared = 1.0f / std::pow(meas.eventT0Uncertainty, 2.0);
119 eventT0 += meas.eventT0 * oneOverUncertaintySquared;
120 preFactor += oneOverUncertaintySquared;
121 }
122
123 eventT0 /= preFactor;
124 const auto eventT0unc = std::sqrt(1.0f / preFactor);
125
126 return EventT0::EventT0Component(eventT0, eventT0unc, usedDetectorSet);
127}
128
129
The DetectorSet class for sets of detector IDs in the form of EDetector values.
Definition: Const.h:80
StoreObjPtr< EventT0 > m_eventT0
Access to global EventT0 which will be read and updated.
void event() override
This method is called for each event.
EventT0::EventT0Component computeCombination(std::vector< EventT0::EventT0Component > measurements) const
computes the new average between multiple, un-correlated sub-detector measurements
EventT0CombinerModule()
Default constructor.
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
Abstract base class for different kinds of events.
Structure for storing the extracted event t0s together with its detector and its uncertainty.
Definition: EventT0.h:33