Belle II Software  release-08-01-10
TOPCosmicT0FinderModule.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 // Own header.
10 #include <top/modules/TOPCosmicT0Finder/TOPCosmicT0FinderModule.h>
11 
12 // TOP headers.
13 #include <top/geometry/TOPGeometryPar.h>
14 #include <top/reconstruction_cpp/TOPTrack.h>
15 #include <top/reconstruction_cpp/PDFConstructor.h>
16 #include <top/reconstruction_cpp/TOPRecoManager.h>
17 #include <top/reconstruction_cpp/PDF1Dim.h>
18 #include <top/utilities/Chi2MinimumFinder1D.h>
19 
20 // framework - DataStore
21 #include <framework/datastore/StoreArray.h>
22 
23 // framework aux
24 #include <framework/gearbox/Const.h>
25 #include <framework/logging/Logger.h>
26 
27 // dataobjects
28 #include <mdst/dataobjects/Track.h>
29 #include <tracking/dataobjects/ExtHit.h>
30 #include <top/dataobjects/TOPBarHit.h>
31 #include <top/dataobjects/TOPDigit.h>
32 #include <top/dataobjects/TOPTimeZero.h>
33 
34 // Root
35 #include <TH1F.h>
36 
37 using namespace std;
38 
39 namespace Belle2 {
44  using namespace TOP;
45 
46  //-----------------------------------------------------------------
48  //-----------------------------------------------------------------
49 
50  REG_MODULE(TOPCosmicT0Finder);
51 
52  //-----------------------------------------------------------------
53  // Implementation
54  //-----------------------------------------------------------------
55 
56  TOPCosmicT0FinderModule::TOPCosmicT0FinderModule() : Module()
57 
58  {
59  // set module description
60  setDescription("Event T0 finder for global cosmic runs");
62 
63  // Add parameters
64  addParam("useIncomingTrack", m_useIncomingTrack,
65  "if true, use incoming track, otherwise use outcoming track", true);
66  addParam("minHits", m_minHits,
67  "minimal number of detected photons in a module", (unsigned) 10);
68  addParam("minSignal", m_minSignal,
69  "minimal number of expected signal photons", 5.0);
70  addParam("applyT0", m_applyT0, "if true, subtract T0 in TOPDigits", true);
71  addParam("numBins", m_numBins, "number of bins time range is divided to", 200);
72  addParam("timeRange", m_timeRange, "time range in which to search [ns]", 10.0);
73  addParam("sigma", m_sigma, "additional time spread added to PDF [ns]", 0.0);
74  addParam("saveHistograms", m_saveHistograms,
75  "save histograms to TOPTimeZero", false);
76  }
77 
79  {
80  // input
81 
82  StoreArray<TOPDigit> topDigits;
83  topDigits.isRequired();
84 
85  StoreArray<Track> tracks;
86  tracks.isRequired();
87 
88  StoreArray<ExtHit> extHits;
89  extHits.isRequired();
90 
91  StoreArray<TOPBarHit> barHits;
92  barHits.isOptional();
93 
94  // output
95 
96  StoreArray<TOPTimeZero> timeZeros;
97  timeZeros.registerInDataStore();
98  timeZeros.registerRelationTo(tracks);
99  timeZeros.registerRelationTo(extHits);
100  timeZeros.registerRelationTo(barHits);
101  }
102 
104  {
106 
107  // select track: if several, choose highest momentum track
108 
109  StoreArray<Track> tracks;
110  const ExtHit* selectedExtHit = 0;
111  double p0 = 0;
112  for (const auto& track : tracks) {
113  const auto extHits = track.getRelationsWith<ExtHit>();
114  const ExtHit* extHit0 = 0;
115  for (const auto& extHit : extHits) {
116  if (abs(extHit.getPdgCode()) != Const::muon.getPDGCode()) continue;
117  if (extHit.getDetectorID() != Const::EDetector::TOP) continue;
118  if (extHit.getCopyID() <= 0) continue;
119  double dot = extHit.getPosition().Dot(extHit.getMomentum());
120  if (m_useIncomingTrack) {
121  if (dot > 0) continue;
122  if (not extHit0) extHit0 = &extHit;
123  if (extHit.getTOF() < extHit0->getTOF()) extHit0 = &extHit;
124  } else {
125  if (dot < 0) continue;
126  if (not extHit0) extHit0 = &extHit;
127  if (extHit.getTOF() > extHit0->getTOF()) extHit0 = &extHit;
128  }
129  }
130  if (not extHit0) continue;
131  double p = extHit0->getMomentum().R();
132  if (p > p0) {
133  p0 = p;
134  selectedExtHit = extHit0;
135  }
136  }
137  if (not selectedExtHit) return;
138 
139  TOPTrack topTrack(selectedExtHit);
140  if (not topTrack.isValid()) return;
141 
142  // require minimal number of photon hits
143 
144  if (topTrack.getSelectedHits().size() < m_minHits) return;
145 
146  // construct PDF for muon
147 
148  PDFConstructor pdfConstructor(topTrack, Const::muon, PDFConstructor::c_Rough);
149  if (not pdfConstructor.isValid()) return;
150 
151  // require minimal expected signal
152 
153  if (pdfConstructor.getExpectedSignalPhotons() < m_minSignal) return;
154 
155  // event is accepted for t0 determination
156 
157  m_acceptedCount++;
158 
159  // full time window in which data are taken (smaller time window is used in reconstruction)
160 
161  const auto& tdc = TOPGeometryPar::Instance()->getGeometry()->getNominalTDC();
162  double timeWindow = m_feSetting->getReadoutWindows() * tdc.getSyncTimeBase() / static_cast<double>(TOPNominalTDC::c_syncWindows);
163 
164  // find rough t0
165 
166  PDF1Dim pdf1d(pdfConstructor, 1.0, timeWindow); // ~1 ns bin size
167  pdfConstructor.switchOffDeltaRayPDF(); // to speed-up fine search
168 
169  Chi2MinimumFinder1D roughFinder(pdf1d.getNumBinsT0(), pdf1d.getMinT0(), pdf1d.getMaxT0());
170  const auto& bins = roughFinder.getBinCenters();
171  for (unsigned i = 0; i < bins.size(); i++) {
172  double t0 = bins[i];
173  roughFinder.add(i, -2 * pdf1d.getLogL(t0));
174  }
175  const auto& t0Rough = roughFinder.getMinimum();
176 
177  // find precise t0
178 
179  double timeMin = TOPRecoManager::getMinTime() + t0Rough.position;
180  double timeMax = TOPRecoManager::getMaxTime() + t0Rough.position;
181  double t0min = t0Rough.position - m_timeRange / 2;
182  double t0max = t0Rough.position + m_timeRange / 2;
183  Chi2MinimumFinder1D finder(m_numBins, t0min, t0max);
184  const auto& binCenters = finder.getBinCenters();
185  int numPhotons = 0;
186  for (unsigned i = 0; i < binCenters.size(); i++) {
187  double t0 = binCenters[i];
188  auto LL = pdfConstructor.getLogL(t0, timeMin, timeMax, m_sigma);
189  finder.add(i, -2 * LL.logL);
190  if (i == 0) numPhotons = LL.numPhotons;
191  }
192  const auto& t0 = finder.getMinimum();
193  if (t0.position < t0min or t0.position > t0max or not t0.valid) return; // out of range
194 
195  // event t0 is successfully determined
196 
197  m_successCount++;
198 
199  // store results
200 
201  StoreArray<TOPTimeZero> timeZeros;
202  auto* timeZero = timeZeros.appendNew(topTrack.getModuleID(), t0.position, t0.error, numPhotons);
203  timeZero->addRelationTo(topTrack.getTrack());
204  timeZero->addRelationTo(topTrack.getExtHit());
205  if (topTrack.getBarHit()) timeZero->addRelationTo(topTrack.getBarHit());
206 
207  // save histograms
208 
209  if (m_saveHistograms) {
210  std::string name;
211 
212  name = "chi2_" + to_string(m_num);
213  std::string title = "muon -2 logL vs. t0; t_{0} [ns]; -2 log L_{#mu}";
214  auto chi2 = finder.getHistogram(name, title);
215 
216  name = "pdf_" + to_string(m_num);
217  auto pdf = pdf1d.getHistogram(name, "PDF projected to time axis");
218  pdf.SetName(name.c_str());
219  pdf.SetXTitle("time [ns]");
220  pdf.SetLineColor(2);
221  pdf.SetOption("hist");
222 
223  name = "hits_" + to_string(m_num);
224  TH1F hits(name.c_str(), "time distribution of photons (t0-subtracted)",
225  pdf.GetNbinsX(), pdf.GetXaxis()->GetXmin(), pdf.GetXaxis()->GetXmax());
226  hits.SetXTitle("time [ns]");
227  for (const auto& hit : topTrack.getSelectedHits()) {
228  hits.Fill(hit.time - t0.position);
229  }
230  timeZero->setHistograms(chi2, pdf, hits);
231  m_num++;
232  }
233 
234  // subtract T0 in digits
235 
236  if (m_applyT0) {
237  StoreArray<TOPDigit> topDigits;
238  for (auto& digit : topDigits) {
239  digit.subtractT0(t0.position);
240  double err = digit.getTimeError();
241  digit.setTimeError(sqrt(err * err + t0.error * t0.error));
242  digit.addStatus(TOPDigit::c_EventT0Subtracted);
243  }
244  }
245 
246  }
247 
248 
250  {
251  B2RESULT("TOPCosmicT0Finder: accepted events " << m_acceptedCount
252  << ", event T0 determined for " << m_successCount << " events");
253  }
254 
255 
257 } // end Belle2 namespace
258 
259 
int getPDGCode() const
PDG code.
Definition: Const.h:464
static const ChargedStable muon
muon particle
Definition: Const.h:651
Store one Ext hit as a ROOT object.
Definition: ExtHit.h:32
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
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
bool m_applyT0
if true, subtract T0 in TOPDigits
DBObjPtr< TOPFrontEndSetting > m_feSetting
front-end settings
bool m_saveHistograms
flag to save histograms
double m_minSignal
minimal number of expected signal photons
int m_numBins
number of bins to which time range is divided
bool m_useIncomingTrack
if true use incoming track, otherwise use outcoming
int m_successCount
counter for successfully determined T0
int m_acceptedCount
counter for accepted events
unsigned m_minHits
minimal number of hits on TOP module
double m_timeRange
time range in which to search [ns]
double m_sigma
additional time spread added to PDF [ns]
const TOPNominalTDC & getNominalTDC() const
Returns nominal time-to-digit conversion parameters.
Definition: TOPGeometry.h:218
@ c_syncWindows
number of windows corresponding to syncTimeBase
Definition: TOPNominalTDC.h:29
Minimum finder using tabulated chi^2 values in one dimension.
void add(unsigned i, double chi2)
Add chi^2 value to bin i.
const Minimum & getMinimum()
Returns parabolic minimum.
const std::vector< double > & getBinCenters() const
Returns vector of bin centers.
Binned one dimensional PDF (a projection of PDF to time axis)
Definition: PDF1Dim.h:25
double getLogL(double timeShift) const
Returns log likelihood.
Definition: PDF1Dim.cc:92
TH1F getHistogram(std::string name, std::string title) const
Returns binned one dimensional PDF (projection to time axis)
Definition: PDF1Dim.cc:108
double getMaxT0() const
Returns upper edge of the T0 search region.
Definition: PDF1Dim.h:121
double getMinT0() const
Returns lower edge of the T0 search region.
Definition: PDF1Dim.h:115
int getNumBinsT0() const
Returns number of bins the T0 search region.
Definition: PDF1Dim.h:127
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)
bool isValid() const
Checks the object status.
double getExpectedSignalPhotons() const
Returns the expected number of signal photons within the default time window.
@ c_Rough
no dependence on y
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
static void setDefaultTimeWindow()
Sets default time window (functions getMinTime(), getMaxTime() will then return default values from D...
static double getMaxTime()
Returns time window upper edge.
static double getMinTime()
Returns time window lower edge.
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
const Track * getTrack() const
Returns mdst track.
Definition: TOPTrack.h:210
int getModuleID() const
Returns slot ID.
Definition: TOPTrack.h:143
const std::vector< SelectedHit > & getSelectedHits() const
Returns selected photon hits from TOPDigits belonging to the slot ID.
Definition: TOPTrack.h:244
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
T dot(GeneralVector< T > a, GeneralVector< T > b)
dot product of two general vectors
Definition: beamHelpers.h:163
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual void terminate() override
Termination action.
Abstract base class for different kinds of events.