Belle II Software  release-06-01-15
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 include
10 #include <top/modules/TOPCosmicT0Finder/TOPCosmicT0FinderModule.h>
11 #include <top/geometry/TOPGeometryPar.h>
12 #include <top/reconstruction_cpp/TOPTrack.h>
13 #include <top/reconstruction_cpp/PDFConstructor.h>
14 #include <top/reconstruction_cpp/TOPRecoManager.h>
15 #include <top/reconstruction_cpp/PDF1Dim.h>
16 #include <top/utilities/Chi2MinimumFinder1D.h>
17 
18 // framework - DataStore
19 #include <framework/datastore/StoreArray.h>
20 
21 // framework aux
22 #include <framework/gearbox/Const.h>
23 #include <framework/logging/Logger.h>
24 
25 // dataobjects
26 #include <mdst/dataobjects/Track.h>
27 #include <tracking/dataobjects/ExtHit.h>
28 #include <top/dataobjects/TOPBarHit.h>
29 #include <top/dataobjects/TOPDigit.h>
30 #include <top/dataobjects/TOPTimeZero.h>
31 
32 // Root
33 #include <TH1F.h>
34 
35 using namespace std;
36 
37 namespace Belle2 {
42  using namespace TOP;
43 
44  //-----------------------------------------------------------------
45  // Register module
46  //-----------------------------------------------------------------
47 
48  REG_MODULE(TOPCosmicT0Finder)
49 
50  //-----------------------------------------------------------------
51  // Implementation
52  //-----------------------------------------------------------------
53 
55 
56  {
57  // set module description
58  setDescription("Event T0 finder for global cosmic runs");
59  setPropertyFlags(c_ParallelProcessingCertified);
60 
61  // Add parameters
62  addParam("useIncomingTrack", m_useIncomingTrack,
63  "if true, use incoming track, otherwise use outcoming track", true);
64  addParam("minHits", m_minHits,
65  "minimal number of detected photons in a module", (unsigned) 10);
66  addParam("minSignal", m_minSignal,
67  "minimal number of expected signal photons", 5.0);
68  addParam("applyT0", m_applyT0, "if true, subtract T0 in TOPDigits", true);
69  addParam("numBins", m_numBins, "number of bins time range is divided to", 200);
70  addParam("timeRange", m_timeRange, "time range in which to search [ns]", 10.0);
71  addParam("sigma", m_sigma, "additional time spread added to PDF [ns]", 0.0);
72  addParam("saveHistograms", m_saveHistograms,
73  "save histograms to TOPTimeZero", false);
74  }
75 
76  void TOPCosmicT0FinderModule::initialize()
77  {
78  // input
79 
80  StoreArray<TOPDigit> topDigits;
81  topDigits.isRequired();
82 
83  StoreArray<Track> tracks;
84  tracks.isRequired();
85 
86  StoreArray<ExtHit> extHits;
87  extHits.isRequired();
88 
89  StoreArray<TOPBarHit> barHits;
90  barHits.isOptional();
91 
92  // output
93 
94  StoreArray<TOPTimeZero> timeZeros;
95  timeZeros.registerInDataStore();
96  timeZeros.registerRelationTo(tracks);
97  timeZeros.registerRelationTo(extHits);
98  timeZeros.registerRelationTo(barHits);
99  }
100 
101  void TOPCosmicT0FinderModule::event()
102  {
103  TOPRecoManager::setDefaultTimeWindow();
104 
105  // select track: if several, choose highest momentum track
106 
107  StoreArray<Track> tracks;
108  const ExtHit* selectedExtHit = 0;
109  double p0 = 0;
110  for (const auto& track : tracks) {
111  const auto extHits = track.getRelationsWith<ExtHit>();
112  const ExtHit* extHit0 = 0;
113  for (const auto& extHit : extHits) {
114  if (abs(extHit.getPdgCode()) != Const::muon.getPDGCode()) continue;
115  if (extHit.getDetectorID() != Const::EDetector::TOP) continue;
116  if (extHit.getCopyID() <= 0) continue;
117  double dot = extHit.getPosition() * extHit.getMomentum();
118  if (m_useIncomingTrack) {
119  if (dot > 0) continue;
120  if (not extHit0) extHit0 = &extHit;
121  if (extHit.getTOF() < extHit0->getTOF()) extHit0 = &extHit;
122  } else {
123  if (dot < 0) continue;
124  if (not extHit0) extHit0 = &extHit;
125  if (extHit.getTOF() > extHit0->getTOF()) extHit0 = &extHit;
126  }
127  }
128  if (not extHit0) continue;
129  double p = extHit0->getMomentum().Mag();
130  if (p > p0) {
131  p0 = p;
132  selectedExtHit = extHit0;
133  }
134  }
135  if (not selectedExtHit) return;
136 
137  TOPTrack topTrack(selectedExtHit);
138  if (not topTrack.isValid()) return;
139 
140  // require minimal number of photon hits
141 
142  if (topTrack.getSelectedHits().size() < m_minHits) return;
143 
144  // construct PDF for muon
145 
146  PDFConstructor pdfConstructor(topTrack, Const::muon, PDFConstructor::c_Rough);
147  if (not pdfConstructor.isValid()) return;
148 
149  // require minimal expected signal
150 
151  if (pdfConstructor.getExpectedSignalPhotons() < m_minSignal) return;
152 
153  // event is accepted for t0 determination
154 
155  m_acceptedCount++;
156 
157  // full time window in which data are taken (smaller time window is used in reconstruction)
158 
159  const auto& tdc = TOPGeometryPar::Instance()->getGeometry()->getNominalTDC();
160  double timeWindow = m_feSetting->getReadoutWindows() * tdc.getSyncTimeBase() / TOPNominalTDC::c_syncWindows;
161 
162  // find rough t0
163 
164  PDF1Dim pdf1d(pdfConstructor, 1.0, timeWindow); // ~1 ns bin size
165  pdfConstructor.switchOffDeltaRayPDF(); // to speed-up fine search
166 
167  Chi2MinimumFinder1D roughFinder(pdf1d.getNumBinsT0(), pdf1d.getMinT0(), pdf1d.getMaxT0());
168  const auto& bins = roughFinder.getBinCenters();
169  for (unsigned i = 0; i < bins.size(); i++) {
170  double t0 = bins[i];
171  roughFinder.add(i, -2 * pdf1d.getLogL(t0));
172  }
173  const auto& t0Rough = roughFinder.getMinimum();
174 
175  // find precise t0
176 
177  double timeMin = TOPRecoManager::getMinTime() + t0Rough.position;
178  double timeMax = TOPRecoManager::getMaxTime() + t0Rough.position;
179  double t0min = t0Rough.position - m_timeRange / 2;
180  double t0max = t0Rough.position + m_timeRange / 2;
181  Chi2MinimumFinder1D finder(m_numBins, t0min, t0max);
182  const auto& binCenters = finder.getBinCenters();
183  int numPhotons = 0;
184  for (unsigned i = 0; i < binCenters.size(); i++) {
185  double t0 = binCenters[i];
186  auto LL = pdfConstructor.getLogL(t0, timeMin, timeMax, m_sigma);
187  finder.add(i, -2 * LL.logL);
188  if (i == 0) numPhotons = LL.numPhotons;
189  }
190  const auto& t0 = finder.getMinimum();
191  if (t0.position < t0min or t0.position > t0max or not t0.valid) return; // out of range
192 
193  // event t0 is successfully determined
194 
195  m_successCount++;
196 
197  // store results
198 
199  StoreArray<TOPTimeZero> timeZeros;
200  auto* timeZero = timeZeros.appendNew(topTrack.getModuleID(), t0.position, t0.error, numPhotons);
201  timeZero->addRelationTo(topTrack.getTrack());
202  timeZero->addRelationTo(topTrack.getExtHit());
203  if (topTrack.getBarHit()) timeZero->addRelationTo(topTrack.getBarHit());
204 
205  // save histograms
206 
207  if (m_saveHistograms) {
208  std::string name;
209 
210  name = "chi2_" + to_string(m_num);
211  std::string title = "muon -2 logL vs. t0; t_{0} [ns]; -2 log L_{#mu}";
212  auto chi2 = finder.getHistogram(name, title);
213 
214  name = "pdf_" + to_string(m_num);
215  auto pdf = pdf1d.getHistogram(name, "PDF projected to time axis");
216  pdf.SetName(name.c_str());
217  pdf.SetXTitle("time [ns]");
218  pdf.SetLineColor(2);
219  pdf.SetOption("hist");
220 
221  name = "hits_" + to_string(m_num);
222  TH1F hits(name.c_str(), "time distribution of photons (t0-subtracted)",
223  pdf.GetNbinsX(), pdf.GetXaxis()->GetXmin(), pdf.GetXaxis()->GetXmax());
224  hits.SetXTitle("time [ns]");
225  for (const auto& hit : topTrack.getSelectedHits()) {
226  hits.Fill(hit.time - t0.position);
227  }
228  timeZero->setHistograms(chi2, pdf, hits);
229  m_num++;
230  }
231 
232  // subtract T0 in digits
233 
234  if (m_applyT0) {
235  StoreArray<TOPDigit> topDigits;
236  for (auto& digit : topDigits) {
237  digit.subtractT0(t0.position);
238  double err = digit.getTimeError();
239  digit.setTimeError(sqrt(err * err + t0.error * t0.error));
240  digit.addStatus(TOPDigit::c_EventT0Subtracted);
241  }
242  }
243 
244  }
245 
246 
247  void TOPCosmicT0FinderModule::terminate()
248  {
249  B2RESULT("TOPCosmicT0Finder: accepted events " << m_acceptedCount
250  << ", event T0 determined for " << m_successCount << " events");
251  }
252 
253 
255 } // end Belle2 namespace
256 
257 
Store one Ext hit as a ROOT object.
Definition: ExtHit.h:30
TVector3 getPosition() const
Get position of this extrapolation hit.
Definition: ExtHit.h:143
Base class for Modules.
Definition: Module.h:72
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
Event T0 finder for global cosmic runs.
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.
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
const Track * getTrack() const
Returns mdst track.
Definition: TOPTrack.h:212
int getModuleID() const
Returns slot ID.
Definition: TOPTrack.h:145
const std::vector< SelectedHit > & getSelectedHits() const
Returns selected photon hits from TOPDigits belonging to the slot ID.
Definition: TOPTrack.h:246
#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.
double position
position of the minimum