Belle II Software  release-06-02-00
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 
36 using namespace Belle2;
37 using namespace TOP;
38 
39 REG_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 
50 void 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:542
Base class for Modules.
Definition: Module.h:72
A module to perform the TOP PID likelihood scan and find the actual minimum as function of the mass.
void initialize() override
Setup the storearrays.
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.
~TOPLLScannerModule() override
Default destructor, Nothing to see here.
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:139
const ExtHit * getExtHit() const
Returns extrapolated hit (track entrance to the bar)
Definition: TOPTrack.h:218
const TOPBarHit * getBarHit() const
Returns bar hit of MC particle assigned to this track (if any)
Definition: TOPTrack.h:240
#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.