11 #include <top/modules/collectors/TOPCommonT0LLCollectorModule.h>
12 #include <top/geometry/TOPGeometryPar.h>
13 #include <top/reconstruction/TOPreco.h>
14 #include <top/reconstruction/TOPtrack.h>
15 #include <top/reconstruction/TOPconfigure.h>
18 #include <framework/gearbox/Const.h>
19 #include <framework/logging/Logger.h>
50 setDescription(
"A collector for common T0 calibration with dimuons or Bhabha's using "
51 "neg. log likelihood minimization (method LL)");
52 setPropertyFlags(c_ParallelProcessingCertified);
55 addParam(
"bunchesPerSSTclk", m_bunchesPerSSTclk,
56 "number of bunches per SST clock period", 24);
57 addParam(
"numBins", m_numBins,
"number of bins of the search region", 200);
58 addParam(
"timeRange", m_timeRange,
59 "time range in which to search for the minimum [ns]", 10.0);
60 addParam(
"minBkgPerBar", m_minBkgPerBar,
61 "minimal number of background photons per module", 0.0);
62 addParam(
"scaleN0", m_scaleN0,
63 "Scale factor for figure-of-merit N0", 1.0);
64 addParam(
"sigmaSmear", m_sigmaSmear,
65 "sigma in [ns] for additional smearing of PDF", 0.0);
66 addParam(
"sample", m_sample,
67 "sample type: one of dimuon or bhabha", std::string(
"dimuon"));
68 addParam(
"deltaEcms", m_deltaEcms,
69 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
70 addParam(
"dr", m_dr,
"cut on POCA in r", 2.0);
71 addParam(
"dz", m_dz,
"cut on POCA in abs(z)", 4.0);
72 addParam(
"minZ", m_minZ,
73 "minimal local z of extrapolated hit", -130.0);
74 addParam(
"maxZ", m_maxZ,
75 "maximal local z of extrapolated hit", 130.0);
76 addParam(
"pdfOption", m_pdfOption,
77 "PDF option, one of 'rough', 'fine', 'optimal'", std::string(
"rough"));
81 void TOPCommonT0LLCollectorModule::prepare()
85 m_digits.isRequired();
86 m_tracks.isRequired();
87 m_extHits.isRequired();
88 m_recBunch.isRequired();
92 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
93 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / m_bunchesPerSSTclk;
101 if (m_pdfOption ==
"rough") {
102 m_PDFOption = TOPreco::c_Rough;
103 }
else if (m_pdfOption ==
"fine") {
104 m_PDFOption = TOPreco::c_Fine;
105 }
else if (m_pdfOption ==
"optimal") {
106 m_PDFOption = TOPreco::c_Optimal;
108 B2ERROR(
"Unknown PDF option '" << m_pdfOption <<
"'");
113 if (m_sample ==
"dimuon" or m_sample ==
"bhabha") {
115 m_selector.setDeltaEcms(m_deltaEcms);
116 m_selector.setCutOnPOCA(m_dr, m_dz);
117 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
119 B2ERROR(
"Invalid sample type '" << m_sample <<
"'");
124 double tmin = -m_timeRange / 2;
125 double tmax = m_timeRange / 2;
126 for (
unsigned i = 0; i < c_numSets; i++) {
127 string name =
"chi2_set" + to_string(i);
128 auto h =
new TH1D(name.c_str(),
"chi2 scan; t0 [ns]; chi2", m_numBins, tmin, tmax);
129 registerObject<TH1D>(name, h);
130 m_names.push_back(name);
133 auto h1 =
new TH1F(
"tracks_per_set",
"tracks per sample; sample number; num tracks",
134 c_numSets, 0, c_numSets);
135 registerObject<TH1F>(
"tracks_per_set", h1);
137 auto h2 =
new TH1F(
"numHits",
"Number of photons per slot",
138 c_numModules, 0.5, c_numModules + 0.5);
139 h2->SetXTitle(
"slot number");
140 h2->SetYTitle(
"hits per slot");
141 registerObject<TH1F>(
"numHits", h2);
143 auto h3 =
new TH2F(
"timeHits",
"Photon times vs. boardstacks",
144 c_numModules * 4, 0.5, c_numModules + 0.5, 200, 0.0, 20.0);
145 h3->SetXTitle(
"slot number");
146 h3->SetYTitle(
"time [ns]");
147 registerObject<TH2F>(
"timeHits", h3);
151 auto h4 =
new TH1F(
"offset",
"current offset from input files; offset [ns]",
152 200, -m_bunchTimeSep / 2, m_bunchTimeSep / 2);
153 registerObject<TH1F>(
"offset", h4);
158 void TOPCommonT0LLCollectorModule::collect()
162 if (not m_recBunch.isValid())
return;
163 if (not m_recBunch->isReconstructed())
return;
168 double mass = m_selector.getChargedStable().getMass();
169 int pdg = m_selector.getChargedStable().getPDGCode();
170 TOPreco reco(Nhyp, &mass, &pdg, m_minBkgPerBar, m_scaleN0);
172 const auto& tdc = TOPGeometryPar::Instance()->getGeometry()->getNominalTDC();
173 double timeMin = tdc.getTimeMin();
174 double timeMax = tdc.getTimeMax();
179 if (m_commonT0->isCalibrated()) T0 = m_commonT0->getT0();
180 for (
const auto& digit : m_digits) {
181 if (digit.getHitQuality() == TOPDigit::c_Good) {
182 double t = digit.getTime();
183 if (digit.isCommonT0Calibrated()) t += T0;
184 if (digit.hasStatus(TOPDigit::c_BunchOffsetSubtracted)) {
185 t += m_recBunch->getAverageOffset();
187 reco.
addData(digit.getModuleID(), digit.getPixelID(), t, digit.getTimeError());
194 for (
const auto& track : m_tracks) {
198 if (not trk.
isValid())
continue;
200 if (not m_selector.isSelected(trk))
continue;
204 if (reco.
getFlag() != 1)
continue;
207 int sub = gRandom->Integer(c_numSets);
208 auto h = getObjectPtr<TH1D>(m_names[sub]);
209 for (
int ibin = 0; ibin < h->GetNbinsX(); ibin++) {
210 double t0 = h->GetBinCenter(ibin + 1);
211 double chi = h->GetBinContent(ibin + 1);
212 chi += -2 * reco.
getLogL(t0, timeMin, timeMax, m_sigmaSmear);
213 h->SetBinContent(ibin + 1, chi);
215 auto h1 = getObjectPtr<TH1F>(
"tracks_per_set");
219 auto h2 = getObjectPtr<TH1F>(
"numHits");
220 auto h3 = getObjectPtr<TH2F>(
"timeHits");
221 for (
const auto& digit : m_digits) {
222 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
223 if (digit.getModuleID() != trk.
getModuleID())
continue;
224 if (digit.getTime() < timeMin)
continue;
225 if (digit.getTime() > timeMax)
continue;
226 h2->Fill(digit.getModuleID());
227 int bs = digit.getBoardstackNumber();
228 h3->Fill((digit.getModuleID() * 4 + bs - 1.5) / 4.0 , digit.getTime());
236 auto h4 = getObjectPtr<TH1F>(
"offset");
237 h4->Fill(m_recBunch->getCurrentOffset());