Project
Loading...
Searching...
No Matches
TimeClusterFinderSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
18
19#include <chrono>
20#include <fstream>
21#include <iostream>
22#include <random>
23#include <stdexcept>
24#include <vector>
25
26#include <fmt/core.h>
27
29
34#include "Framework/Lifetime.h"
35#include "Framework/Logger.h"
36#include "Framework/Output.h"
37#include "Framework/Task.h"
39
47
48namespace o2
49{
50namespace mch
51{
52
53using namespace std;
54using namespace o2::framework;
55
57{
58 public:
59 //_________________________________________________________________________________________________
61 {
63 mTimeClusterWidth = param.maxClusterWidth;
64 mNbinsInOneWindow = param.peakSearchNbins;
65 mMinDigitPerROF = param.minDigitsPerROF;
66 mOnlyTrackable = param.onlyTrackable;
67 mPeakSearchSignalOnly = param.peakSearchSignalOnly;
68 mIRFramesOnly = param.irFramesOnly;
69 mDebug = ic.options().get<bool>("mch-debug");
70 mROFRejectionFraction = param.rofRejectionFraction;
71
72 if (mDebug) {
73 fair::Logger::SetConsoleColor(true);
74 }
75 // number of bins must be >= 3
76 if (mNbinsInOneWindow < 3) {
77 mNbinsInOneWindow = 3;
78 }
79 // number of bins must be odd
80 if ((mNbinsInOneWindow % 2) == 0) {
81 mNbinsInOneWindow += 1;
82 }
83 if (mROFRejectionFraction > 0) {
84 std::random_device rd;
85 mGenerator = std::mt19937(rd());
86 }
87
88 LOGP(info, "TimeClusterWidth : {}", mTimeClusterWidth);
89 LOGP(info, "BinsInOneWindow : {} ", mNbinsInOneWindow);
90 LOGP(info, "MinDigitPerROF : {}", mMinDigitPerROF);
91 LOGP(info, "OnlyTrackable : {}", mOnlyTrackable);
92 LOGP(info, "PeakSearchSignalOnly : {}", mPeakSearchSignalOnly);
93 LOGP(info, "IRFramesOnly : {}", mIRFramesOnly);
94 LOGP(info, "ROFRejectionFraction : {}", mROFRejectionFraction);
95
96 auto stop = [this]() {
97 if (mTFcount) {
98 LOGP(info, "duration = {} us / TF", mTimeProcess.count() * 1000 / mTFcount);
99 }
100 };
101 ic.services().get<CallbackService>().set<CallbackService::Id::Stop>(stop);
102 }
103
104 ROFFilter createRandomRejectionFilter(float rejectionFraction)
105 {
106 return [this, rejectionFraction](const ROFRecord& /*rof*/) {
107 double rnd = mDistribution(mGenerator);
108 return rnd > rejectionFraction;
109 };
110 }
111
112 //_________________________________________________________________________________________________
114 {
115 auto rofs = pc.inputs().get<gsl::span<o2::mch::ROFRecord>>("rofs");
116 auto digits = pc.inputs().get<gsl::span<o2::mch::Digit>>("digits");
117
118 o2::mch::ROFTimeClusterFinder rofProcessor(rofs, digits, mTimeClusterWidth, mNbinsInOneWindow, mPeakSearchSignalOnly, mDebug);
119
120 if (mDebug) {
121 LOGP(warning, "{:=>60} ", fmt::format("{:6d} Input ROFS", rofs.size()));
122 }
123
124 auto tStart = std::chrono::high_resolution_clock::now();
125 rofProcessor.process();
126 auto tEnd = std::chrono::high_resolution_clock::now();
127 mTimeProcess += tEnd - tStart;
128
129 if (mDebug) {
130 LOGP(warning, "{:=>60} ", fmt::format("{:6d} Output ROFS", rofProcessor.getROFRecords().size()));
131 }
132
133 auto& outRofs = pc.outputs().make<std::vector<ROFRecord>>(OutputRef{"rofs"});
134 const auto& pRofs = rofProcessor.getROFRecords();
135
136 // prepare the list of filters we want to apply to ROFs
137 std::vector<ROFFilter> filters;
138
139 if (mOnlyTrackable) {
140 // selects only ROFs that are trackable
141 const auto& trackerParam = TrackerParam::Instance();
142 std::array<bool, 5> requestStation{
143 trackerParam.requestStation[0],
144 trackerParam.requestStation[1],
145 trackerParam.requestStation[2],
146 trackerParam.requestStation[3],
147 trackerParam.requestStation[4]};
148 filters.emplace_back(createTrackableFilter(digits,
149 requestStation,
150 trackerParam.moreCandidates));
151 }
152 if (mMinDigitPerROF > 0) {
153 // selects only those ROFs have that minimum number of digits
154 filters.emplace_back(createMultiplicityFilter(mMinDigitPerROF));
155 }
156 if (mIRFramesOnly) {
157 // selects only those ROFs that overlop some IRFrame
158 auto irFrames = pc.inputs().get<gsl::span<o2::dataformats::IRFrame>>("irframes");
159 filters.emplace_back(createIRFrameFilter(irFrames));
160 }
161
162 std::string extraMsg = "";
163
164 if (mROFRejectionFraction > 0) {
165 filters.emplace_back(createRandomRejectionFilter(mROFRejectionFraction));
166 extraMsg = fmt::format(" (CAUTION : hard-rejected {:3.0f}% of the output ROFs)", mROFRejectionFraction * 100);
167 }
168
169 // a single filter which is the AND combination of the elements of the filters vector
170 auto filter = createROFFilter(filters);
171
172 std::copy_if(begin(pRofs),
173 end(pRofs),
174 std::back_inserter(outRofs),
175 filter);
176
177 const float p1 = rofs.size() > 0 ? 100. * pRofs.size() / rofs.size() : 0;
178 const float p2 = rofs.size() > 0 ? 100. * outRofs.size() / rofs.size() : 0;
179
180 LOGP(info,
181 "TF {} Processed {} input ROFs, "
182 "time-clusterized them into {} ROFs ({:3.0f}%) "
183 "and output {} ({:3.0f}%) of them{}",
184 mTFcount, rofs.size(),
185 pRofs.size(), p1,
186 outRofs.size(), p2, extraMsg);
187 mTFcount += 1;
188 }
189
190 private:
191 std::chrono::duration<double, std::milli>
192 mTimeProcess{};
193
194 uint32_t mTimeClusterWidth;
195 uint32_t mNbinsInOneWindow;
196 int mTFcount{0};
197 int mDebug{0};
198 int mMinDigitPerROF;
199 bool mPeakSearchSignalOnly;
200 bool mOnlyTrackable;
201 bool mIRFramesOnly;
202 float mROFRejectionFraction;
203 std::uniform_real_distribution<double> mDistribution{0.0, 1.0};
204 std::mt19937 mGenerator;
205};
206
207//_________________________________________________________________________________________________
210 std::string_view inputDigitDataDescription,
211 std::string_view inputDigitRofDataDescription,
212 std::string_view outputDigitRofDataDescription,
213 std::string_view inputIRFrameDataDescription)
214{
215 std::string input = fmt::format("rofs:MCH/{}/0;digits:MCH/{}/0",
216 inputDigitRofDataDescription.data(),
217 inputDigitDataDescription.data());
218 if (TimeClusterizerParam::Instance().irFramesOnly && inputIRFrameDataDescription.size()) {
219 LOGP(info, "will select IRFrames from {}", inputIRFrameDataDescription);
220 input += ";irframes:";
221 input += inputIRFrameDataDescription;
222 }
223 std::string output = fmt::format("rofs:MCH/{}/0", outputDigitRofDataDescription.data());
224
225 std::vector<OutputSpec> outputs;
226 auto matchers = select(output.c_str());
227 for (auto& matcher : matchers) {
228 outputs.emplace_back(DataSpecUtils::asOutputSpec(matcher));
229 }
230
231 return DataProcessorSpec{
232 specName,
233 Inputs{select(input.c_str())},
234 outputs,
235 AlgorithmSpec{adaptFromTask<TimeClusterFinderTask>()},
236 Options{{"mch-debug", VariantType::Bool, false, {"enable verbose output"}}}};
237}
238} // end namespace mch
239} // end namespace o2
constexpr int p2()
constexpr int p1()
constexpr to accelerate the coordinates changing
Class to delimit start and end IR of certain time period.
Configurable parameters for MCH tracking.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Class to group the fired pads according to their time stamp.
Definition of a data processor to run the time clusterizer.
const char * specName
decltype(auto) make(const Output &spec, Args... args)
ServiceRegistryRef services()
Definition InitContext.h:34
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ROFFilter createRandomRejectionFilter(float rejectionFraction)
void init(framework::InitContext &ic)
void run(framework::ProcessingContext &pc)
GLuint GLuint end
Definition glcorearb.h:469
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLenum GLfloat param
Definition glcorearb.h:271
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > select(char const *matcher="")
std::vector< InputSpec > Inputs
std::function< bool(const ROFRecord &)> ROFFilter
Definition ROFFilter.h:25
ROFFilter createMultiplicityFilter(int minMultiplicity)
ROFFilter createROFFilter(gsl::span< const ROFFilter > filters)
Definition ROFFilter.cxx:16
o2::framework::DataProcessorSpec getTimeClusterFinderSpec(const char *specName="mch-time-cluster-finder", std::string_view inputDigitDataDescription="F-DIGITS", std::string_view inputDigitRofDataDescription="F-DIGITROFS", std::string_view outputDigitRofDataDescription="TC-F-DIGITROFS", std::string_view inputIRFrameDataDescription="ITS/IRFRAMES")
ROFFilter createIRFrameFilter(gsl::span< const o2::dataformats::IRFrame > irframes)
ROFFilter createTrackableFilter(gsl::span< const T > items, std::array< bool, 5 > requestStation={true, true, true, true, true}, bool moreCandidates=false)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
static OutputSpec asOutputSpec(InputSpec const &spec)
std::random_device rd
std::vector< Digit > digits