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
46void TOPLLScannerModule::scanLikelihood(const std::vector<float>& masses, const std::vector<float>& logLs, float deltaLL,
47 float& maxLL,
48 float& massMax, float& minMassRange, float& maxMassRange)
49{
50 // Find the index and the value of the LL maximum
51 auto llMaxIndex = std::distance(logLs.begin(), std::max_element(logLs.begin(), logLs.end()));
52 maxLL = logLs[llMaxIndex];
53 massMax = masses[llMaxIndex];
54
55 // if no deltaLL value is given, return a +/- 30 MeV range around the maximum
56 if (isnan(deltaLL)) {
57 minMassRange = massMax - 0.03;
58 if (minMassRange < masses[0])
59 minMassRange = masses[0];
60
61 maxMassRange = massMax + 0.03;
62 if (maxMassRange < masses[0])
63 maxMassRange = masses.back();
64 } else {
65 // search forward
66 auto llValue = maxLL;
67 int llIndex = llMaxIndex;
68 while (llValue > maxLL - deltaLL && llIndex < int(masses.size())) {
69 llValue = logLs[llIndex];
70 maxMassRange = masses[llIndex];
71 llIndex++;
72 }
73 // search backward
74 llValue = maxLL;
75 llIndex = llMaxIndex;
76 while (llValue > maxLL - deltaLL && llIndex >= 0) {
77 llValue = logLs[llIndex];
78 minMassRange = masses[llIndex];
79 llIndex--;
80 }
81 }
82}
83
85{
86 m_digits.isRequired();
87 m_tracks.isRequired();
88 m_extHits.isRequired();
89 m_barHits.isOptional();
90 m_recBunch.isOptional();
91
92
93 m_likelihoodScanResults.registerInDataStore();
94 m_likelihoodScanResults.registerRelationTo(m_extHits);
95 m_likelihoodScanResults.registerRelationTo(m_barHits);
96 m_tracks.registerRelationTo(m_likelihoodScanResults);
97
98
99 // Fill the array of masses for the coarse scan in un-even steps
100 float step;
101 float lastVal = 0.0002;
102 for (auto i = 1; i < 240; i++) {
103 if (i < 10)
104 step = 0.001;
105 else if (i < 50)
106 step = 0.005;
107 else step = 0.01;
108 m_massPoints.push_back(lastVal);
109 lastVal = lastVal + step;
110 }
111}
112
114{
115
116 for (const auto& track : m_tracks) {
117 auto* topLLScanRes = m_likelihoodScanResults.appendNew();
118 track.addRelationTo(topLLScanRes);
119
120 const TOPTrack trk(track);
121 if (not trk.isValid())
122 continue; // track missed the bars
123
124 topLLScanRes->addRelationTo(trk.getExtHit());
125 topLLScanRes->addRelationTo(trk.getBarHit());
126
127 // -------------
128 // First make a coarse scan to store it and find the LL maximum
129 // -------------
130 std::vector<float> logLcoarseScan;
131 std::vector<float> nSignalPhotonsCoarseScan;
132
133 for (const auto& mass : m_massPoints) {
135 pdfConstructor.switchOffDeltaRayPDF();
136 auto LL = pdfConstructor.getLogL();
137 logLcoarseScan.push_back(LL.logL);
138 nSignalPhotonsCoarseScan.push_back(pdfConstructor.getExpectedSignalPhotons());
139 }
140
141 float massMax = -1;
142 float minMassRange = 0;
143 float maxMassRange = 0;
144 float maxLL = 0;
145 scanLikelihood(m_massPoints, logLcoarseScan, 0.8, maxLL, massMax, minMassRange, maxMassRange);
146
147
148 // -------------
149 // Then make a fine scan to store it and measure the TOP mass and uncertainty
150 // -------------
151 std::vector<float> logLfineScan;
152 std::vector<float> massPointsFineScan;
153 std::vector<float> nSignalPhotonsFineScan;
154 auto mass = minMassRange;
155 auto step = (maxMassRange - minMassRange) / m_nFineScanPoints;
156 if (step > 0.001)
157 step = 0.001;
158 while (mass < maxMassRange) {
160 pdfConstructor.switchOffDeltaRayPDF();
161 auto LL = pdfConstructor.getLogL();
162 logLfineScan.push_back(LL.logL);
163 nSignalPhotonsFineScan.push_back(pdfConstructor.getExpectedSignalPhotons());
164 massPointsFineScan.push_back(mass);
165 mass += step;
166 }
167
168 // find the maximum and the confidence interval using the fine-grained scan
169 scanLikelihood(massPointsFineScan, logLfineScan, 0.5, maxLL, massMax, minMassRange, maxMassRange);
170
171
172 // finally find the location of the cherenkov threshold looking for a plateau of the
173 // LL value
174 auto lastLL = logLcoarseScan.back();
175 auto currentLL = logLcoarseScan.back();
176 auto index = m_massPoints.size() - 1;
177 while (TMath::Abs(lastLL - currentLL) < 0.01 && index > 0) {
178 lastLL = currentLL;
179 currentLL = logLcoarseScan[index];
180 index--;
181 }
182 float threshold = m_massPoints[index + 1];
183
184 // grab the number of expected photons at the LL maximum
186 pdfConstructor.switchOffDeltaRayPDF();
187 float nSignalPhotons = pdfConstructor.getExpectedSignalPhotons();
188 float nBackgroundPhotons = pdfConstructor.getExpectedBkgPhotons();
189 float nDeltaPhotons = pdfConstructor.getExpectedDeltaPhotons();
190
191 topLLScanRes->set(massMax,
192 minMassRange,
193 maxMassRange,
194 threshold,
195 nSignalPhotons,
196 nBackgroundPhotons,
197 nDeltaPhotons,
198 m_massPoints, massPointsFineScan,
199 logLcoarseScan, logLfineScan,
200 nSignalPhotonsCoarseScan, nSignalPhotonsFineScan);
201 }
202}
203
static const ChargedStable pion
charged pion particle
Definition Const.h:661
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
static void scanLikelihood(const std::vector< float > &masses, const std::vector< float > &logLs, float deltaLL, float &maxLL, float &massMax, float &minMassRange, float &maxMassRange)
Finds best fit value and confidence interval form a LL via direct scan.
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.
short m_nFineScanPoints
number of points for the fine-graned scan
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:40
bool isValid() const
Checks if track is successfully constructed.
Definition TOPTrack.h:144
const ExtHit * getExtHit() const
Returns extrapolated hit (track entrance to the bar)
Definition TOPTrack.h:223
const TOPBarHit * getBarHit() const
Returns bar hit of MC particle assigned to this track (if any)
Definition TOPTrack.h:245
#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.