Belle II Software development
TOPLLScannerModule.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 <top/modules/TOPLLScannerModule/TOPLLScannerModule.h>
10
11#include <top/reconstruction_cpp/TOPRecoManager.h>
12#include <top/reconstruction_cpp/TOPTrack.h>
13#include <top/reconstruction_cpp/PDFConstructor.h>
14
15#include <framework/datastore/StoreArray.h>
16#include <framework/datastore/StoreObjPtr.h>
17
18#include <iostream>
19#include <TTree.h>
20#include <TH2F.h>
21#include <TFile.h>
22#include <TRandom.h>
23#include <TGraph.h>
24#include <TF1.h>
25
26// framework - DataStore
27#include <framework/datastore/DataStore.h>
28#include <framework/datastore/StoreArray.h>
29#include <framework/datastore/StoreObjPtr.h>
30
31// framework aux
32#include <framework/gearbox/Unit.h>
33#include <framework/gearbox/Const.h>
34#include <framework/logging/Logger.h>
35
36using namespace Belle2;
37using namespace TOP;
38
39REG_MODULE(TOPLLScanner);
40
42{
43 setDescription(R"DOC(A module to perform the TOP PID likelihood scan and find the actual minimum as function of the mass)DOC");
44}
45
47{
48}
49
50void TOPLLScannerModule::scanLikelihood(std::vector<float>masses, std::vector<float>logLs, float deltaLL, float& maxLL,
51 float& massMax, float& minMassRange, float& maxMassRange)
52{
53 // Find the index and the value of the LL maximum
54 auto llMaxIndex = std::distance(logLs.begin(), std::max_element(logLs.begin(), logLs.end()));
55 maxLL = logLs[llMaxIndex];
56 massMax = masses[llMaxIndex];
57
58 // if no deltaLL value is given, return a +/- 30 MeV range around the maximum
59 if (isnan(deltaLL)) {
60 minMassRange = massMax - 0.03;
61 if (minMassRange < masses[0])
62 minMassRange = masses[0];
63
64 maxMassRange = massMax + 0.03;
65 if (maxMassRange < masses[0])
66 maxMassRange = masses.back();
67 } else {
68 // search forward
69 auto llValue = maxLL;
70 int llIndex = llMaxIndex;
71 while (llValue > maxLL - deltaLL && llIndex < int(masses.size())) {
72 llValue = logLs[llIndex];
73 maxMassRange = masses[llIndex];
74 llIndex++;
75 }
76 // search backward
77 llValue = maxLL;
78 llIndex = llMaxIndex;
79 while (llValue > maxLL - deltaLL && llIndex >= 0) {
80 llValue = logLs[llIndex];
81 minMassRange = masses[llIndex];
82 llIndex--;
83 }
84 }
85}
86
88{
89 m_digits.isRequired();
90 m_tracks.isRequired();
91 m_extHits.isRequired();
92 m_barHits.isOptional();
93 m_recBunch.isOptional();
94
95
96 m_likelihoodScanResults.registerInDataStore();
97 m_likelihoodScanResults.registerRelationTo(m_extHits);
98 m_likelihoodScanResults.registerRelationTo(m_barHits);
99 m_tracks.registerRelationTo(m_likelihoodScanResults);
100
101
102 // Fill the array of masses for the coarse scan in un-even steps
103 float step;
104 float lastVal = 0.0002;
105 for (auto i = 1; i < 240; i++) {
106 if (i < 10)
107 step = 0.001;
108 else if (i < 50)
109 step = 0.005;
110 else step = 0.01;
111 m_massPoints.push_back(lastVal);
112 lastVal = lastVal + step;
113 }
114}
115
117{
118
119 for (const auto& track : m_tracks) {
120 auto* topLLScanRes = m_likelihoodScanResults.appendNew();
121 track.addRelationTo(topLLScanRes);
122
123 const TOPTrack trk(track);
124 if (not trk.isValid())
125 continue; // track missed the bars
126
127 topLLScanRes->addRelationTo(trk.getExtHit());
128 topLLScanRes->addRelationTo(trk.getBarHit());
129
130 // -------------
131 // First make a coarse scan to store it and find the LL maximum
132 // -------------
133 std::vector<float> logLcoarseScan;
134 std::vector<float> nSignalPhotonsCoarseScan;
135
136 for (const auto& mass : m_massPoints) {
138 pdfConstructor.switchOffDeltaRayPDF();
139 auto LL = pdfConstructor.getLogL();
140 logLcoarseScan.push_back(LL.logL);
141 nSignalPhotonsCoarseScan.push_back(pdfConstructor.getExpectedSignalPhotons());
142 }
143
144 float massMax = -1;
145 float minMassRange = 0;
146 float maxMassRange = 0;
147 float maxLL = 0;
148 scanLikelihood(m_massPoints, logLcoarseScan, 0.8, maxLL, massMax, minMassRange, maxMassRange);
149
150
151 // -------------
152 // Then make a fine scan to store it and measure the TOP mass and uncertainty
153 // -------------
154 std::vector<float> logLfineScan;
155 std::vector<float> massPointsFineScan;
156 std::vector<float> nSignalPhotonsFineScan;
157 auto mass = minMassRange;
158 auto step = (maxMassRange - minMassRange) / m_nFineScanPoints;
159 if (step > 0.001)
160 step = 0.001;
161 while (mass < maxMassRange) {
163 pdfConstructor.switchOffDeltaRayPDF();
164 auto LL = pdfConstructor.getLogL();
165 logLfineScan.push_back(LL.logL);
166 nSignalPhotonsFineScan.push_back(pdfConstructor.getExpectedSignalPhotons());
167 massPointsFineScan.push_back(mass);
168 mass += step;
169 }
170
171 // find the maximum and the confidence interval usin the fine-grained scan
172 scanLikelihood(massPointsFineScan, logLfineScan, 0.5, maxLL, massMax, minMassRange, maxMassRange);
173
174
175 // finally find the location of the cherenkov threshold looking for a plateau of the
176 // LL value
177 auto lastLL = logLcoarseScan.back();
178 auto currentLL = logLcoarseScan.back();
179 auto index = m_massPoints.size() - 1;
180 while (TMath::Abs(lastLL - currentLL) < 0.01 && index > 0) {
181 lastLL = currentLL;
182 currentLL = logLcoarseScan[index];
183 index--;
184 }
185 float threshold = m_massPoints[index + 1];
186
187 // grab the number of expected photons at the LL maximum
189 pdfConstructor.switchOffDeltaRayPDF();
190 float nSignalPhotons = pdfConstructor.getExpectedSignalPhotons();
191 float nBackgroundPhotons = pdfConstructor.getExpectedBkgPhotons();
192 float nDeltaPhotons = pdfConstructor.getExpectedDeltaPhotons();
193
194 topLLScanRes->set(massMax,
195 minMassRange,
196 maxMassRange,
197 threshold,
198 nSignalPhotons,
199 nBackgroundPhotons,
200 nDeltaPhotons,
201 m_massPoints, massPointsFineScan,
202 logLcoarseScan, logLfineScan,
203 nSignalPhotonsCoarseScan, nSignalPhotonsFineScan);
204 }
205}
206
208{
209
210}
211
212
static const ChargedStable pion
charged pion particle
Definition: Const.h:661
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
StoreObjPtr< TOPRecBunch > m_recBunch
reconstructed bunch
void initialize() override
Setup the storearrays.
TOPLLScannerModule()
Constructor: Sets the description, the properties and the parameters of the module.
void event() override
Performs the scan.
void scanLikelihood(std::vector< float >masses, std::vector< float >logLs, float deltaLL, float &maxLL, float &massMax, float &minMassRange, float &maxMassRange)
Finds best fit value and confidence interval form a LL vie direct scan.
void terminate() override
Saves the results.
short m_nFineScanPoints
number of points for the fine-graned scan
~TOPLLScannerModule() override
Default destructor, Nothing to see here.
StoreArray< Track > m_tracks
collection of tracks
StoreArray< TOPDigit > m_digits
collection of digits
StoreArray< ExtHit > m_extHits
collection of extrapolated hits
StoreArray< TOPBarHit > m_barHits
collection of MCParticle hits at TOP
std::vector< float > m_massPoints
vector with the mass points used in the coarse scan
StoreArray< TOPLikelihoodScanResult > m_likelihoodScanResults
collection of likelihoods
PDF construction and log likelihood determination for a given track and particle hypothesis.
void switchOffDeltaRayPDF() const
Exclude delta-ray PDF in log likelihood calculation.
LogL getLogL() const
Returns extended log likelihood (using the default time window)
double getExpectedDeltaPhotons() const
Returns the expected number of delta-ray photons within the default time window.
double getExpectedSignalPhotons() const
Returns the expected number of signal photons within the default time window.
@ c_Reduced
only PDF peak data
@ c_Optimal
y dependent only where necessary
double getExpectedBkgPhotons() const
Returns the expected number of background photons within the default time window.
Reconstructed track at TOP.
Definition: TOPTrack.h:39
bool isValid() const
Checks if track is successfully constructed.
Definition: TOPTrack.h:137
const ExtHit * getExtHit() const
Returns extrapolated hit (track entrance to the bar)
Definition: TOPTrack.h:216
const TOPBarHit * getBarHit() const
Returns bar hit of MC particle assigned to this track (if any)
Definition: TOPTrack.h:238
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.