8#include <tracking/eventTimeExtraction/findlets/HitBasedT0Extractor.h>
9#include <tracking/eventTimeExtraction/findlets/BaseEventTimeExtractor.icc.h>
11#include <tracking/trackFindingCDC/utilities/StringManipulation.h>
13#include <framework/core/ModuleParamList.h>
15#include <framework/logging/Logger.h>
16#include <framework/utilities/ScopeGuard.h>
20#include <TFitResult.h>
23#include <boost/lexical_cast.hpp>
28using namespace TrackFindingCDC;
32 return "Extracts the T0 time of an event only using CDC Hits";
42 const std::string& prefix)
44 moduleParamList->
addParameter(prefixed(prefix,
"searchWindow"),
46 "Size of the time distance (in ns) to search for t0 in both direction from the current best t0",
49 moduleParamList->
addParameter(prefixed(prefix,
"fitWindow"),
51 "Size of the time distance (in ns) to used for fitting",
54 moduleParamList->
addParameter(prefixed(prefix,
"refitWindow"),
56 "Size of the time distance (in ns) to used for re-fitting",
59 moduleParamList->
addParameter(prefixed(prefix,
"binCountTimeHistogram"),
61 "Number of bins in the timing histogram used for fitting",
64 moduleParamList->
addParameter(prefixed(prefix,
"rejectByBackgroundFlag"),
66 "Don't consider hits if they have the background flag set",
69 moduleParamList->
addParameter(prefixed(prefix,
"rejectIfNotTakenFlag"),
71 "Don't consider hits which have not been assigned during track finding. The CDC track finding has "
72 "to be run before for this flag to be useful.",
75 moduleParamList->
addParameter(prefixed(prefix,
"rejectIfChiSquareLargerThan"),
77 "consider the t0 fit failed which have larger chi2 than this number",
80 moduleParamList->
addParameter(prefixed(prefix,
"rejectIfUncertaintyLargerThan"),
82 "consider the t0 fit if the uncertainty on t0 is larger than this value",
85 moduleParamList->
addParameter(prefixed(prefix,
"storeAllFits"),
87 "store images for all fits",
90 moduleParamList->
addParameter(prefixed(prefix,
"minHitCount"),
92 "Minimum amount of hits which is required to try the extraction",
100 const auto timeHistogramName =
"HitBasedT0Extractor_time_hist";
101 const std::string debugImageName =
"HitBasedT0Extractor_debug_" + boost::lexical_cast<std::string>
104 auto timingHistgram = TH1D(timeHistogramName, timeHistogramName,
111 TCanvas canvas(debugImageName.c_str(), debugImageName.c_str(), 800, 600);
113 if (inputWireHits.size() == 0) {
114 B2WARNING(
"No input CDC hits available for the CDC hit based t0 extraction.");
118 for (
auto const& wireHit : inputWireHits) {
121 && wireHit.getAutomatonCell().hasBackgroundFlag())
125 && !wireHit.getAutomatonCell().hasTakenFlag())
132 && wireHit.getAutomatonCell().hasTakenFlag()
133 && wireHit.getAutomatonCell().hasBackgroundFlag())
138 timingHistgram.Fill(wireHit.getDriftTime());
142 B2DEBUG(25,
"Only " << timingHistgram.GetEntries() <<
" hits satisfied the requirements for t0 extraction, " <<
m_param_minHitCount
143 <<
" are required.");
149 timingHistgram.SetBinContent(1, timingHistgram.GetBinContent(1) + 1);
152 "Filled histogram with " << timingHistgram.GetEntries() <<
" Entries");
154 std::unique_ptr<TH1> cumTimingHistogram(timingHistgram.GetCumulative());
156 cumTimingHistogram->SetDirectory(0);
160 double errPrevBin = 0.0f;
161 double errThisBin = 0.0f;
162 for (
int i = 0; i < cumTimingHistogram->GetNbinsX(); i++) {
164 const double prevEntries = cumTimingHistogram->GetBinContent(i - 1);
165 const double addedEntries = cumTimingHistogram->GetBinContent(i) - prevEntries;
166 if (addedEntries > 0.0) {
168 const double errNewEntries = 1.0 / std::sqrt(addedEntries);
169 errThisBin = errPrevBin + errNewEntries;
173 if (cumTimingHistogram->GetBinContent(i) > 0) {
174 errThisBin = 1.0 / std::sqrt(cumTimingHistogram->GetBinContent(i));
178 cumTimingHistogram->SetBinError(i, errThisBin);
179 errPrevBin = errThisBin;
183 cumTimingHistogram->Draw();
189 TF1 fitfuncBkg = TF1(
"HitBasedT0Extractor_fit_bkg",
"[0]*x + [1]",
190 rangeBkg.first, rangeBkg.second);
191 TF1 fitfuncSig = TF1(
"HitBasedT0Extractor_fit_sig",
"[0]*x + [1]",
192 rangeSig.first, rangeSig.second);
194 auto fitresBkg = cumTimingHistogram->Fit(&fitfuncBkg,
"LQS",
"",
195 rangeBkg.first, rangeBkg.second);
196 auto fitresSig = cumTimingHistogram->Fit(&fitfuncSig,
"LQS",
"",
197 rangeSig.first, rangeSig.second);
200 fitfuncBkg.Draw(
"SAME");
201 fitfuncSig.Draw(
"SAME");
204 TF1 fitfuncSegmented = TF1(
"HitBasedT0Extractor_fit_seg",
205 "[1]*(x+TMath::Abs(x+[3])) + [2]*(x-TMath::Abs(x+[3])) + [0]",
208 if (fitresSig->IsValid() && fitresBkg->IsValid()) {
209 double t0_estimate = (fitresBkg->Parameter(1) - fitresSig->Parameter(1))
210 / (fitresSig->Parameter(0) - fitresBkg->Parameter(0));
213 std::array<double, 4> fit_params = { 0,
214 fitresSig->Parameter(0),
215 fitresBkg->Parameter(0),
221 fit_params[3] = t0_estimate;
224 fitfuncSegmented.SetParameters(fit_params.data());
228 fitfuncSegmented.Draw(
"SAME");
233 const double fitted_t0_first = -fitresFull->Parameter(3);
234 bool refitSuccess =
false;
236 fitresFull = cumTimingHistogram->Fit(&fitfuncSegmented,
"QS",
"",
240 B2DEBUG(25,
"First t0 estimate not in proper range" << fitted_t0_first);
244 fitfuncSegmented.Draw(
"SAME");
248 if (refitSuccess && fitresFull->IsValid()) {
249 const double fitted_t0 = -fitresFull->Parameter(3);
250 const double fitted_t0_error = fitresFull->Error(3);
252 const double norm_chi2 = fitresFull->Chi2() / double(fitresFull->Ndf());
254 B2DEBUG(25,
"T0 fit with t0 " << fitted_t0 <<
" +- " << fitted_t0_error <<
" and normalized chi2 " << norm_chi2 <<
" and " <<
255 timingHistgram.GetEntries() <<
" hits");
260 "T0 fit has too large Chi2 " << fitresFull->Chi2());
263 "T0 fit has too large error " << fitted_t0_error);
269 EventT0::EventT0Component eventT0Component(fitted_t0 + lastEventT0, fitted_t0_error, Const::CDC,
"hit based", norm_chi2);
270 m_eventT0->addTemporaryEventT0(eventT0Component);
274 "Successful t0 extraction with CDC hits: " << fitted_t0 <<
" +- " << fitted_t0_error);
278 "Cannot fit t0 from CDC hits only. Won't set EventT0 for now.");
282 "Cannot extract background or signal segment because fit failed. Won't set EventT0 for now.");
287 canvas.SaveAs(debugImageName.c_str());
The Module parameter list class.
static ScopeGuard guardBatchMode(bool batchMode=true)
Create a ScopeGuard to turn ROOT into batch mode and restore the initial batch mode status after the ...
void addParameter(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
virtual void initialize() override
Initialize the event t0 store obj ptr.
virtual void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) override
Expose our parameters to the super module.
Abstract base class for different kinds of events.
Structure for storing the extracted event t0s together with its detector and its uncertainty.