9 #include <top/modules/collectors/TOPModuleT0LLCollectorModule.h>
10 #include <top/geometry/TOPGeometryPar.h>
11 #include <top/reconstruction_cpp/TOPTrack.h>
12 #include <top/reconstruction_cpp/PDFConstructor.h>
13 #include <top/reconstruction_cpp/TOPRecoManager.h>
16 #include <framework/gearbox/Const.h>
17 #include <framework/logging/Logger.h>
45 TOPModuleT0LLCollectorModule::TOPModuleT0LLCollectorModule()
48 setDescription(
"A collector for module T0 calibration with neg. log likelihood "
49 "minimization (method LL). Aimed for the final (precise) calibration"
50 "after initial one with DeltaT method.");
51 setPropertyFlags(c_ParallelProcessingCertified);
54 addParam(
"numBins", m_numBins,
"number of bins of the search region", 200);
55 addParam(
"timeRange", m_timeRange,
56 "time range in which to search for the minimum [ns]", 10.0);
57 addParam(
"sigmaSmear", m_sigmaSmear,
58 "sigma in [ns] for additional smearing of PDF", 0.0);
59 addParam(
"sample", m_sample,
60 "sample type: one of dimuon or bhabha", std::string(
"dimuon"));
61 addParam(
"deltaEcms", m_deltaEcms,
62 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
63 addParam(
"dr", m_dr,
"cut on POCA in r", 2.0);
64 addParam(
"dz", m_dz,
"cut on POCA in abs(z)", 4.0);
65 addParam(
"minZ", m_minZ,
66 "minimal local z of extrapolated hit", -130.0);
67 addParam(
"maxZ", m_maxZ,
68 "maximal local z of extrapolated hit", 130.0);
69 addParam(
"pdfOption", m_pdfOption,
70 "PDF option, one of 'rough', 'fine', 'optimal'", std::string(
"rough"));
75 void TOPModuleT0LLCollectorModule::prepare()
79 m_digits.isRequired();
80 m_tracks.isRequired();
81 m_extHits.isRequired();
82 m_recBunch.isRequired();
86 if (m_pdfOption ==
"rough") {
87 m_PDFOption = PDFConstructor::c_Rough;
88 }
else if (m_pdfOption ==
"fine") {
89 m_PDFOption = PDFConstructor::c_Fine;
90 }
else if (m_pdfOption ==
"optimal") {
91 m_PDFOption = PDFConstructor::c_Optimal;
93 B2ERROR(
"Unknown PDF option '" << m_pdfOption <<
"'");
98 if (m_sample ==
"dimuon" or m_sample ==
"bhabha") {
100 m_selector.setDeltaEcms(m_deltaEcms);
101 m_selector.setCutOnPOCA(m_dr, m_dz);
102 m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
104 B2ERROR(
"Invalid sample type '" << m_sample <<
"'");
109 double tmin = -m_timeRange / 2;
110 double tmax = m_timeRange / 2;
111 for (
unsigned i = 0; i < c_numSets; i++) {
112 for (
int slot = 1; slot <= c_numModules; slot++) {
114 if (m_moduleT0->isCalibrated(slot)) T0 = m_moduleT0->getT0(slot);
115 string name =
"chi2_set" + to_string(i) +
"_slot" + to_string(slot);
116 string title =
"chi2 scan, slot" + to_string(slot) +
"; t0 [ns]; chi2";
117 auto h =
new TH1D(name.c_str(), title.c_str(), m_numBins, tmin + T0, tmax + T0);
118 registerObject<TH1D>(name, h);
119 m_names[i].push_back(name);
123 auto h1 =
new TH2F(
"tracks_per_slot",
"tracks per slot and sample",
124 c_numModules, 0.5,
static_cast<float>(c_numModules) + 0.5, c_numSets, 0, c_numSets);
125 h1->SetXTitle(
"slot number");
126 h1->SetYTitle(
"sample number");
127 registerObject<TH2F>(
"tracks_per_slot", h1);
129 auto h2 =
new TH1F(
"numHits",
"Number of photons per slot",
130 c_numModules, 0.5,
static_cast<float>(c_numModules) + 0.5);
131 h2->SetXTitle(
"slot number");
132 h2->SetYTitle(
"hits per slot");
133 registerObject<TH1F>(
"numHits", h2);
135 auto h3 =
new TH2F(
"timeHits",
"Photon times vs. boardstacks",
136 c_numModules * 4, 0.5,
static_cast<float>(c_numModules) + 0.5, 200, 0.0, 20.0);
137 h3->SetXTitle(
"slot number");
138 h3->SetYTitle(
"time [ns]");
139 registerObject<TH2F>(
"timeHits", h3);
141 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
142 double bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / 24;
143 auto h4 =
new TH1F(
"offset",
"current offset from input files; offset [ns]",
144 200, -bunchTimeSep / 2, bunchTimeSep / 2);
145 registerObject<TH1F>(
"offset", h4);
150 void TOPModuleT0LLCollectorModule::collect()
154 if (not m_recBunch.isValid())
return;
155 if (not m_recBunch->isReconstructed())
return;
157 TOPRecoManager::setDefaultTimeWindow();
158 double timeMin = TOPRecoManager::getMinTime();
159 double timeMax = TOPRecoManager::getMaxTime();
163 for (
auto& digit : m_digits) {
164 int slot = digit.getModuleID();
165 if (digit.isModuleT0Calibrated()) digit.subtractT0(-m_moduleT0->getT0(slot));
166 if (digit.hasStatus(TOPDigit::c_BunchOffsetSubtracted)) digit.subtractT0(-m_recBunch->getAverageOffset());
172 for (
const auto& track : m_tracks) {
176 if (not trk.
isValid())
continue;
178 if (not m_selector.isSelected(trk))
continue;
181 PDFConstructor pdfConstructor(trk, m_selector.getChargedStable(), m_PDFOption);
182 if (not pdfConstructor.
isValid())
continue;
185 int sub = gRandom->Integer(c_numSets);
187 if (module >= m_names[sub].size())
continue;
188 auto h = getObjectPtr<TH1D>(m_names[sub][module]);
189 for (
int ibin = 0; ibin < h->GetNbinsX(); ibin++) {
190 double t0 = h->GetBinCenter(ibin + 1);
191 double chi = h->GetBinContent(ibin + 1);
192 chi += -2 * pdfConstructor.
getLogL(t0, m_sigmaSmear).
logL;
193 h->SetBinContent(ibin + 1, chi);
195 auto h1 = getObjectPtr<TH2F>(
"tracks_per_slot");
199 auto h2 = getObjectPtr<TH1F>(
"numHits");
200 auto h3 = getObjectPtr<TH2F>(
"timeHits");
201 for (
const auto& digit : m_digits) {
202 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
203 if (digit.getModuleID() != trk.
getModuleID())
continue;
204 if (digit.getTime() < timeMin)
continue;
205 if (digit.getTime() > timeMax)
continue;
206 h2->Fill(digit.getModuleID());
207 int bs = digit.getBoardstackNumber();
208 h3->Fill((digit.getModuleID() * 4 + bs - 1.5) / 4.0, digit.getTime());
216 auto h4 = getObjectPtr<TH1F>(
"offset");
217 h4->Fill(m_recBunch->getCurrentOffset());
PDF construction and log likelihood determination for a given track and particle hypothesis.
LogL getLogL() const
Returns extended log likelihood (using the default time window)
bool isValid() const
Checks the object status.
Reconstructed track at TOP.
bool isValid() const
Checks if track is successfully constructed.
int getModuleID() const
Returns slot ID.
Utility for the track selection - used in various calibration modules.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.
double logL
extended log likelihood