Project
Loading...
Searching...
No Matches
MIPTrackFilterSpec.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
15
17
18#include <algorithm>
19#include <iterator>
20#include <vector>
21#include <memory>
22#include <random>
23
24// o2 includes
28#include "Framework/Logger.h"
29#include "Framework/Task.h"
33#include "Headers/DataHeader.h"
34
35using namespace o2::framework;
36
37namespace o2::tpc
38{
39
41{
42 public:
43 void init(framework::InitContext& ic) final;
44 void run(ProcessingContext& pc) final;
45 void endOfStream(EndOfStreamContext& eos) final;
46
47 private:
48 void sendOutput(DataAllocator& output);
49
50 TrackCuts mCuts{};
51 std::vector<TrackTPC> mMIPTracks;
52 unsigned int mProcessEveryNthTF{1};
53 int mMaxTracksPerTF{-1};
54 uint32_t mTFCounter{0};
55 int mProcessNFirstTFs{0};
56 bool mSendDummy{false};
57};
58
60{
61 const double minP = ic.options().get<double>("min-momentum");
62 const double maxP = ic.options().get<double>("max-momentum");
63 const double mindEdx = ic.options().get<double>("min-dedx");
64 const double maxdEdx = ic.options().get<double>("max-dedx");
65 const int minClusters = std::max(10, ic.options().get<int>("min-clusters"));
66 const auto cutLoopers = !ic.options().get<bool>("dont-cut-loopers");
67 mSendDummy = ic.options().get<bool>("send-dummy-data");
68 mMaxTracksPerTF = ic.options().get<int>("maxTracksPerTF");
69 if (mMaxTracksPerTF > 0) {
70 mMIPTracks.reserve(mMaxTracksPerTF);
71 }
72
73 mProcessEveryNthTF = ic.options().get<int>("processEveryNthTF");
74 if (mProcessEveryNthTF <= 0) {
75 mProcessEveryNthTF = 1;
76 }
77 mProcessNFirstTFs = ic.options().get<int>("process-first-n-TFs");
78
79 if (mProcessEveryNthTF > 1) {
80 std::mt19937 rng(std::time(nullptr));
81 std::uniform_int_distribution<std::mt19937::result_type> dist(1, mProcessEveryNthTF);
82 mTFCounter = dist(rng);
83 LOGP(info, "Skipping first {} TFs", mProcessEveryNthTF - mTFCounter);
84 }
85
86 mCuts.setPMin(minP);
87 mCuts.setPMax(maxP);
88 mCuts.setNClusMin(minClusters);
89 mCuts.setdEdxMin(mindEdx);
90 mCuts.setdEdxMax(maxdEdx);
91 mCuts.setCutLooper(cutLoopers);
92}
93
95{
96 const auto currentTF = processing_helpers::getCurrentTF(pc);
97 if ((mTFCounter++ % mProcessEveryNthTF) && (currentTF >= mProcessNFirstTFs)) {
98 LOGP(info, "Skipping TF {}", currentTF);
99 mMIPTracks.clear();
100 if (mSendDummy) {
101 sendOutput(pc.outputs());
102 }
103 return;
104 }
105
106 const auto tracks = pc.inputs().get<gsl::span<TrackTPC>>("tracks");
107 const auto nTracks = tracks.size();
108
109 if ((mMaxTracksPerTF != -1) && (nTracks > mMaxTracksPerTF)) {
110 // indices to good tracks
111 std::vector<size_t> indices;
112 indices.reserve(nTracks);
113 for (size_t i = 0; i < nTracks; ++i) {
114 if (mCuts.goodTrack(tracks[i])) {
115 indices.emplace_back(i);
116 }
117 }
118
119 // in case no good tracks have been found
120 if (indices.empty()) {
121 mMIPTracks.clear();
122 if (mSendDummy) {
123 sendOutput(pc.outputs());
124 }
125 return;
126 }
127
128 // shuffle indices to good tracks
129 std::minstd_rand rng(std::time(nullptr));
130 std::shuffle(indices.begin(), indices.end(), rng);
131
132 // copy good tracks
133 const int loopEnd = (mMaxTracksPerTF > indices.size()) ? indices.size() : mMaxTracksPerTF;
134 for (int i = 0; i < loopEnd; ++i) {
135 mMIPTracks.emplace_back(tracks[indices[i]]);
136 }
137 } else {
138 std::copy_if(tracks.begin(), tracks.end(), std::back_inserter(mMIPTracks), [this](const auto& track) { return mCuts.goodTrack(track); });
139 }
140
141 LOGP(info, "Filtered {} MIP tracks out of {} total tpc tracks", mMIPTracks.size(), tracks.size());
142 sendOutput(pc.outputs());
143 mMIPTracks.clear();
144}
145
146void MIPTrackFilterDevice::sendOutput(DataAllocator& output) { output.snapshot(Output{header::gDataOriginTPC, "MIPS", 0}, mMIPTracks); }
147
149{
150 LOG(info) << "Finalizig MIP Tracks filter";
151}
152
154{
155 std::vector<OutputSpec> outputs;
156 outputs.emplace_back(header::gDataOriginTPC, "MIPS", 0, Lifetime::Sporadic);
157
158 return DataProcessorSpec{
159 "tpc-miptrack-filter",
160 Inputs{
161 InputSpec{"tracks", "TPC", "TRACKS"},
162 },
163 outputs,
164 adaptFromTask<MIPTrackFilterDevice>(),
165 Options{
166 {"min-momentum", VariantType::Double, 0.35, {"minimum momentum cut"}},
167 {"max-momentum", VariantType::Double, 0.55, {"maximum momentum cut"}},
168 {"min-dedx", VariantType::Double, 10., {"minimum dEdx cut"}},
169 {"max-dedx", VariantType::Double, 200., {"maximum dEdx cut"}},
170 {"min-clusters", VariantType::Int, 60, {"minimum number of clusters in a track"}},
171 {"processEveryNthTF", VariantType::Int, 1, {"Using only a fraction of the data: 1: Use every TF, 10: Process only every tenth TF."}},
172 {"maxTracksPerTF", VariantType::Int, -1, {"Maximum number of processed tracks per TF (-1 for processing all tracks)"}},
173 {"process-first-n-TFs", VariantType::Int, 1, {"Number of first TFs which are not sampled"}},
174 {"send-dummy-data", VariantType::Bool, false, {"Send empty data in case TF is skipped"}},
175 {"dont-cut-loopers", VariantType::Bool, false, {"Do not cut loopers by comparing zout-zin"}}}};
176}
177
178} // namespace o2::tpc
Utils and constants for calibration and related workflows.
int32_t i
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Workflow to filter MIP tracks and streams them to other devices.
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.
void endOfStream(EndOfStreamContext &eos) final
void run(ProcessingContext &pc) final
void init(framework::InitContext &ic) final
track cut class
Definition TrackCuts.h:37
void setPMax(float PMax)
Definition TrackCuts.h:45
void setPMin(float PMin)
Definition TrackCuts.h:44
void setCutLooper(bool cut)
try to remove looper cutting on (abs(z_out) - abs(z_in)) < -10), not very precise
Definition TrackCuts.h:50
void setdEdxMax(float dEdxMax)
Definition TrackCuts.h:48
void setNClusMin(float NClusMin)
Definition TrackCuts.h:46
void setdEdxMin(float dEdxMin)
Definition TrackCuts.h:47
bool goodTrack(o2::tpc::TrackTPC const &track)
Definition TrackCuts.cxx:31
GLsizei GLenum const void * indices
Definition glcorearb.h:400
constexpr o2::header::DataOrigin gDataOriginTPC
Definition DataHeader.h:576
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > Inputs
uint32_t getCurrentTF(o2::framework::ProcessingContext &pc)
Global TPC definitions and constants.
Definition SimTraits.h:167
o2::framework::DataProcessorSpec getMIPTrackFilterSpec()
create a processor spec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"