Belle II Software  release-05-01-25
TOPCosmicT0FinderModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2017 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Marko Staric *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 // Own include
12 #include <top/modules/TOPCosmicT0Finder/TOPCosmicT0FinderModule.h>
13 #include <top/geometry/TOPGeometryPar.h>
14 #include <top/reconstruction/TOPreco.h>
15 #include <top/reconstruction/TOPtrack.h>
16 #include <top/reconstruction/TOPconfigure.h>
17 #include <top/reconstruction/TOP1Dpdf.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  //-----------------------------------------------------------------
47  // Register module
48  //-----------------------------------------------------------------
49 
50  REG_MODULE(TOPCosmicT0Finder)
51 
52  //-----------------------------------------------------------------
53  // Implementation
54  //-----------------------------------------------------------------
55 
57 
58  {
59  // set module description
60  setDescription("Event T0 finder for global cosmic runs");
61  setPropertyFlags(c_ParallelProcessingCertified);
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 
78  TOPCosmicT0FinderModule::~TOPCosmicT0FinderModule()
79  {
80  }
81 
82  void TOPCosmicT0FinderModule::initialize()
83  {
84 
85  // input
86 
87  StoreArray<TOPDigit> topDigits;
88  topDigits.isRequired();
89 
90  StoreArray<Track> tracks;
91  tracks.isRequired();
92 
93  StoreArray<ExtHit> extHits;
94  extHits.isRequired();
95 
96  StoreArray<TOPBarHit> barHits;
97  barHits.isOptional();
98 
99  // output
100 
101  StoreArray<TOPTimeZero> timeZeros;
102  timeZeros.registerInDataStore();
103  timeZeros.registerRelationTo(tracks);
104  timeZeros.registerRelationTo(extHits);
105  timeZeros.registerRelationTo(barHits);
106 
107  // Configure TOP detector
108 
109  TOPconfigure config;
110 
111  }
112 
113  void TOPCosmicT0FinderModule::beginRun()
114  {
115  }
116 
117  void TOPCosmicT0FinderModule::event()
118  {
119 
120  // select track: if several, choose highest momentum track
121 
122  StoreArray<Track> tracks;
123  const Track* selectedTrack = 0;
124  double p0 = 0;
125  int moduleID = 0;
126  for (const auto& track : tracks) {
127  const auto extHits = track.getRelationsWith<ExtHit>();
128  const ExtHit* extHit0 = 0;
129  for (const auto& extHit : extHits) {
130  if (abs(extHit.getPdgCode()) != 13) continue;
131  if (extHit.getDetectorID() != Const::EDetector::TOP) continue;
132  double dot = extHit.getPosition() * extHit.getMomentum();
133  if (m_useIncomingTrack) {
134  if (dot > 0) continue;
135  if (!extHit0) extHit0 = &extHit;
136  if (extHit.getTOF() < extHit0->getTOF()) extHit0 = &extHit;
137  } else {
138  if (dot < 0) continue;
139  if (!extHit0) extHit0 = &extHit;
140  if (extHit.getTOF() > extHit0->getTOF()) extHit0 = &extHit;
141  }
142  }
143  if (!extHit0) continue;
144  double p = extHit0->getMomentum().Mag();
145  if (p > p0) {
146  p0 = p;
147  selectedTrack = &track;
148  moduleID = abs(extHit0->getCopyID());
149  }
150  }
151  if (!selectedTrack) return;
152 
153  if (moduleID == 0) {
154  B2ERROR("moduleID == 0");
155  return;
156  }
157 
158  TOPtrack topTrack(selectedTrack, moduleID, Const::muon);
159  if (!topTrack.isValid()) return;
160 
161  // select photons: at least m_minHits
162 
163  StoreArray<TOPDigit> topDigits;
164  std::vector<const TOPDigit*> selDigits;
165  for (const auto& digit : topDigits) {
166  if (digit.getModuleID() != topTrack.getModuleID()) continue;
167  if (digit.getHitQuality() != TOPDigit::c_Good) continue;
168  selDigits.push_back(&digit);
169  }
170  if (selDigits.empty() or selDigits.size() < m_minHits) return;
171 
172  // create reconstruction object and set various options
173 
174  int Nhyp = 1;
175  double mass = Const::muon.getMass();
176  int pdg = Const::muon.getPDGCode();
177  TOPreco reco(Nhyp, &mass, &pdg);
178  reco.setPDFoption(TOPreco::c_Rough);
179 
180  // add photon hits to reconstruction object
181 
182  for (const auto& digit : selDigits) {
183  if (digit->getHitQuality() == TOPDigit::c_Good)
184  reco.addData(digit->getModuleID(), digit->getPixelID(), digit->getTime(),
185  digit->getTimeError());
186  }
187 
188  // construct PDF
189 
190  reco.reconstruct(topTrack);
191  if (reco.getFlag() != 1) return;
192  if (reco.getExpectedPhotons() - reco.getExpectedBG() < m_minSignal) return;
193 
194  // event is accepted for t0 determination
195 
196  m_acceptedCount++;
197 
198  // find rough t0
199 
200  TOP1Dpdf pdf1d(reco, topDigits, topTrack.getModuleID(), 1.0); // ~1 ns bin size
201  Chi2MinimumFinder1D roughFinder(pdf1d.getNumBinsT0(), pdf1d.getMinT0(),
202  pdf1d.getMaxT0());
203  const auto& bins = roughFinder.getBinCenters();
204  for (unsigned i = 0; i < bins.size(); i++) {
205  double t0 = bins[i];
206  roughFinder.add(i, -2 * pdf1d.getLogL(t0));
207  }
208  const auto& t0Rough = roughFinder.getMinimum();
209 
210  // find precise t0
211 
212  const auto& tdc = TOPGeometryPar::Instance()->getGeometry()->getNominalTDC();
213  double timeMin = tdc.getTimeMin() + t0Rough.position;
214  double timeMax = tdc.getTimeMax() + t0Rough.position;
215  double t0min = t0Rough.position - m_timeRange / 2;
216  double t0max = t0Rough.position + m_timeRange / 2;
217  Chi2MinimumFinder1D finder(m_numBins, t0min, t0max);
218  const auto& binCenters = finder.getBinCenters();
219  for (unsigned i = 0; i < binCenters.size(); i++) {
220  double t0 = binCenters[i];
221  finder.add(i, -2 * reco.getLogL(t0, timeMin, timeMax, m_sigma));
222  }
223  const auto& t0 = finder.getMinimum();
224  if (t0.position < t0min or t0.position > t0max or !t0.valid) return; // out of range
225 
226  // event t0 is successfully determined
227 
228  m_successCount++;
229 
230  // store results
231 
232  StoreArray<TOPTimeZero> timeZeros;
233  auto* timeZero = timeZeros.appendNew(topTrack.getModuleID(), t0.position, t0.error,
234  reco.getNumOfPhotons());
235  timeZero->addRelationTo(topTrack.getTrack());
236  timeZero->addRelationTo(topTrack.getExtHit());
237  if (topTrack.getBarHit()) timeZero->addRelationTo(topTrack.getBarHit());
238 
239  // save histograms
240 
241  if (m_saveHistograms) {
242  std::string name;
243 
244  name = "chi2_" + to_string(m_num);
245  std::string title = "muon -2 logL vs. t0; t_{0} [ns]; -2 log L_{#mu}";
246  auto chi2 = finder.getHistogram(name, title);
247 
248  name = "pdf_" + to_string(m_num);
249  auto pdf = pdf1d.getHistogram(name, "PDF projected to time axis");
250  pdf.SetName(name.c_str());
251  pdf.SetXTitle("time [ns]");
252  pdf.SetLineColor(2);
253  pdf.SetOption("hist");
254 
255  name = "hits_" + to_string(m_num);
256  TH1F hits(name.c_str(), "time distribution of photons (t0-subtracted)",
257  pdf.GetNbinsX(), pdf.GetXaxis()->GetXmin(), pdf.GetXaxis()->GetXmax());
258  hits.SetXTitle("time [ns]");
259  for (const auto& digit : selDigits) {
260  if (digit->getHitQuality() == TOPDigit::c_Good)
261  hits.Fill(digit->getTime() - t0.position);
262  }
263 
264  timeZero->setHistograms(chi2, pdf, hits);
265  m_num++;
266  }
267 
268  // subtract T0 in digits
269 
270  if (m_applyT0) {
271  for (auto& digit : topDigits) {
272  digit.subtractT0(t0.position);
273  double err = digit.getTimeError();
274  digit.setTimeError(sqrt(err * err + t0.error * t0.error));
275  digit.addStatus(TOPDigit::c_EventT0Subtracted);
276  }
277  }
278 
279  }
280 
281 
282  void TOPCosmicT0FinderModule::endRun()
283  {
284  }
285 
286  void TOPCosmicT0FinderModule::terminate()
287  {
288  B2RESULT("TOPCosmicT0Finder: accepted events " << m_acceptedCount
289  << ", event T0 determined for " << m_successCount << " events");
290  }
291 
292 
294 } // end Belle2 namespace
295 
296 
Belle2::StoreArray::appendNew
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:256
Belle2::TOP::TOPreco::getFlag
int getFlag()
Return status.
Definition: TOPreco.cc:278
Belle2::StoreArray::registerRelationTo
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:150
Belle2::TOP::TOPreco::getNumOfPhotons
int getNumOfPhotons()
Return number of measured photons.
Definition: TOPreco.cc:297
Belle2::TOP::TOPreco::getExpectedPhotons
double getExpectedPhotons(int i=0)
Return expected number of photons (signal + background) for i-th mass hypothesis.
Definition: TOPreco.cc:284
Belle2::ExtHit::getPosition
TVector3 getPosition() const
Get position of this extrapolation hit.
Definition: ExtHit.h:153
Belle2::TOP::TOPreco::reconstruct
void reconstruct(const TOPtrack &trk, int pdg=0)
Run reconstruction for a given track.
Definition: TOPreco.cc:268
Belle2::TOP::TOP1Dpdf::getMinT0
double getMinT0() const
Returns lower edge of the T0 search region.
Definition: TOP1Dpdf.h:125
Belle2::TOP::TOPtrack::getExtHit
const ExtHit * getExtHit() const
Return extrapolated hit (track entrance to the bar) if this track is constructed from mdst track.
Definition: TOPtrack.h:236
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::TOP::TOPtrack
Class to hold reconstructed track, interface to fortran.
Definition: TOPtrack.h:42
Belle2::TOP::TOPtrack::getBarHit
const TOPBarHit * getBarHit() const
Return bar hit of MC particle assigned to this track (if any)
Definition: TOPtrack.h:248
Belle2::TOP::Chi2MinimumFinder1D::getBinCenters
const std::vector< double > & getBinCenters() const
Returns vector of bin centers.
Definition: Chi2MinimumFinder1D.h:130
Belle2::TOP::Chi2MinimumFinder1D::Minimum::position
double position
position of the minimum
Definition: Chi2MinimumFinder1D.h:45
Belle2::TOP::TOPtrack::isValid
bool isValid() const
Check if track is properly defined.
Definition: TOPtrack.h:87
Belle2::TOP::Chi2MinimumFinder1D
Minimum finder using tabulated chi^2 values in one dimension.
Definition: Chi2MinimumFinder1D.h:37
Belle2::TOP::TOPreco::addData
int addData(int moduleID, int pixelID, double time, double timeError)
Add data.
Definition: TOPreco.cc:214
Belle2::TOP::TOPtrack::getModuleID
int getModuleID() const
Return module ID.
Definition: TOPtrack.h:217
Belle2::TOP::TOP1Dpdf::getMaxT0
double getMaxT0() const
Returns upper edge of the T0 search region.
Definition: TOP1Dpdf.h:131
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::TOP::TOPreco
TOP reconstruction: this class provides interface to fortran code.
Definition: TOPreco.h:36
Belle2::ExtHit
Store one Ext hit as a ROOT object.
Definition: ExtHit.h:40
Belle2::TOP::Chi2MinimumFinder1D::getMinimum
const Minimum & getMinimum()
Returns parabolic minimum.
Definition: Chi2MinimumFinder1D.h:147
Belle2::TOP::TOPreco::getLogL
double getLogL(int i=0)
Return log likelihood for i-th mass hypothesis.
Definition: TOPreco.cc:303
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TOP::TOPconfigure
Configure TOP geometry for reconstruction: provides interface to fortran code.
Definition: TOPconfigure.h:36
Belle2::TOP::TOPtrack::getTrack
const Track * getTrack() const
Return mdst track if this track is constructed from it.
Definition: TOPtrack.h:229
Belle2::TOP::TOP1Dpdf
Binned one dimensional PDF (a projection of PDF to time axis)
Definition: TOP1Dpdf.h:39
Belle2::TOP::TOP1Dpdf::getNumBinsT0
int getNumBinsT0() const
Returns number of bins the T0 search region.
Definition: TOP1Dpdf.h:137
Belle2::TOP::TOPreco::getExpectedBG
double getExpectedBG()
Return expected number of background photons.
Definition: TOPreco.cc:291
Belle2::TOP::Chi2MinimumFinder1D::add
void add(unsigned i, double chi2)
Add chi^2 value to bin i.
Definition: Chi2MinimumFinder1D.cc:72
Belle2::Track
Class that bundles various TrackFitResults.
Definition: Track.h:35
Belle2::StoreArray
Accessor to arrays stored in the data store.
Definition: ECLMatchingPerformanceExpertModule.h:33
Belle2::TOPCosmicT0FinderModule
Event T0 finder for global cosmic runs.
Definition: TOPCosmicT0FinderModule.h:32
Belle2::TOP::TOP1Dpdf::getHistogram
TH1F getHistogram(std::string name, std::string title) const
Returns binned one dimensional PDF (projection to time axis)
Definition: TOP1Dpdf.cc:119
Belle2::TOP::TOPreco::setPDFoption
void setPDFoption(PDFoption opt, int NP=0, int NC=0)
Sets PDF option.
Definition: TOPreco.cc:196
Belle2::TOP::TOP1Dpdf::getLogL
double getLogL(double timeShift) const
Returns log likelihood.
Definition: TOP1Dpdf.cc:102