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>
21 #include <framework/datastore/StoreArray.h>
24 #include <framework/gearbox/Const.h>
25 #include <framework/logging/Logger.h>
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>
60 setDescription(
"Event T0 finder for global cosmic runs");
61 setPropertyFlags(c_ParallelProcessingCertified);
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);
78 TOPCosmicT0FinderModule::~TOPCosmicT0FinderModule()
82 void TOPCosmicT0FinderModule::initialize()
88 topDigits.isRequired();
102 timeZeros.registerInDataStore();
113 void TOPCosmicT0FinderModule::beginRun()
117 void TOPCosmicT0FinderModule::event()
123 const Track* selectedTrack = 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;
138 if (dot < 0)
continue;
139 if (!extHit0) extHit0 = &extHit;
140 if (extHit.getTOF() > extHit0->getTOF()) extHit0 = &extHit;
143 if (!extHit0)
continue;
144 double p = extHit0->getMomentum().Mag();
147 selectedTrack = &track;
148 moduleID = abs(extHit0->getCopyID());
151 if (!selectedTrack)
return;
154 B2ERROR(
"moduleID == 0");
158 TOPtrack topTrack(selectedTrack, moduleID, Const::muon);
159 if (!topTrack.
isValid())
return;
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);
170 if (selDigits.empty() or selDigits.size() < m_minHits)
return;
175 double mass = Const::muon.getMass();
176 int pdg = Const::muon.getPDGCode();
177 TOPreco reco(Nhyp, &mass, &pdg);
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());
191 if (reco.
getFlag() != 1)
return;
204 for (
unsigned i = 0; i < bins.size(); i++) {
208 const auto& t0Rough = roughFinder.
getMinimum();
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;
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));
223 const auto& t0 = finder.getMinimum();
224 if (t0.position < t0min or t0.position > t0max or !t0.valid)
return;
235 timeZero->addRelationTo(topTrack.
getTrack());
236 timeZero->addRelationTo(topTrack.
getExtHit());
241 if (m_saveHistograms) {
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);
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]");
253 pdf.SetOption(
"hist");
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);
264 timeZero->setHistograms(chi2, pdf, hits);
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);
282 void TOPCosmicT0FinderModule::endRun()
286 void TOPCosmicT0FinderModule::terminate()
288 B2RESULT(
"TOPCosmicT0Finder: accepted events " << m_acceptedCount
289 <<
", event T0 determined for " << m_successCount <<
" events");