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 <vector>
20#include <memory>
21#include <random>
22
23// o2 includes
27#include "Framework/Logger.h"
29#include "Framework/Task.h"
34#include "Headers/DataHeader.h"
39
40using namespace o2::framework;
43
44namespace o2::tpc
45{
46
48{
49 public:
50 MIPTrackFilterDevice(std::shared_ptr<o2::base::GRPGeomRequest> gr, std::shared_ptr<DataRequest> dr, GID::mask_t trackSourcesMask)
51 : mGRPGeomRequest(gr), mDataRequest(dr), mTrackSourcesMask(trackSourcesMask) {}
52
53 void init(framework::InitContext& ic) final;
54 void run(ProcessingContext& pc) final;
55 void endOfStream(EndOfStreamContext& eos) final;
56 void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final;
57
58 private:
59 void sendOutput(DataAllocator& output);
60
61 std::shared_ptr<o2::base::GRPGeomRequest> mGRPGeomRequest;
62 std::shared_ptr<DataRequest> mDataRequest;
63 GID::mask_t mTrackSourcesMask;
64 TrackCuts mCuts{};
65 std::vector<TrackTPC> mMIPTracks;
67 unsigned int mProcessEveryNthTF{1};
68 int mMaxTracksPerTF{-1};
69 uint32_t mTFCounter{0};
70 int mProcessNFirstTFs{0};
71 float mDCACut{-1};
72 float mDCAZCut{-1};
73 bool mSendDummy{false};
74
75 bool acceptDCA(o2::track::TrackPar propTrack, o2::math_utils::Point3D<float> refPoint, bool useDCAz = false);
76};
77
79{
80 const double minP = ic.options().get<double>("min-momentum");
81 const double maxP = ic.options().get<double>("max-momentum");
82 const double mindEdx = ic.options().get<double>("min-dedx");
83 const double maxdEdx = ic.options().get<double>("max-dedx");
84 const int minClusters = std::max(10, ic.options().get<int>("min-clusters"));
85 const auto cutLoopers = !ic.options().get<bool>("dont-cut-loopers");
86 mSendDummy = ic.options().get<bool>("send-dummy-data");
87 mMaxTracksPerTF = ic.options().get<int>("maxTracksPerTF");
88 if (mMaxTracksPerTF > 0) {
89 mMIPTracks.reserve(mMaxTracksPerTF);
90 }
91
92 mProcessEveryNthTF = ic.options().get<int>("processEveryNthTF");
93 if (mProcessEveryNthTF <= 0) {
94 mProcessEveryNthTF = 1;
95 }
96 mProcessNFirstTFs = ic.options().get<int>("process-first-n-TFs");
97
98 if (mProcessEveryNthTF > 1) {
99 std::mt19937 rng(std::time(nullptr));
100 std::uniform_int_distribution<std::mt19937::result_type> dist(1, mProcessEveryNthTF);
101 mTFCounter = dist(rng);
102 LOGP(info, "Skipping first {} TFs", mProcessEveryNthTF - mTFCounter);
103 }
104
105 mCuts.setPMin(minP);
106 mCuts.setPMax(maxP);
107 mCuts.setNClusMin(minClusters);
108 mCuts.setdEdxMin(mindEdx);
109 mCuts.setdEdxMax(maxdEdx);
110 mCuts.setCutLooper(cutLoopers);
111
112 mDCACut = ic.options().get<float>("dca-cut");
113 mDCAZCut = ic.options().get<float>("dca-z-cut");
114
116}
117
119{
122
123 const auto currentTF = processing_helpers::getCurrentTF(pc);
124 if ((mTFCounter++ % mProcessEveryNthTF) && (currentTF >= mProcessNFirstTFs)) {
125 LOGP(info, "Skipping TF {}", currentTF);
126 mMIPTracks.clear();
127 if (mSendDummy) {
128 sendOutput(pc.outputs());
129 }
130 return;
131 }
132
134 recoData.collectData(pc, *mDataRequest);
135 const auto tracksTPC = recoData.getTPCTracks();
136 const auto nTracks = tracksTPC.size();
137
138 // indices to good tracks
139 std::vector<size_t> indices;
140 indices.reserve(nTracks);
141
142 const auto useGlobalTracks = mTrackSourcesMask[GID::ITSTPC];
144
145 if (useGlobalTracks) {
146 auto trackIndex = recoData.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
147 auto vtxRefs = recoData.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
148 std::vector<GID::Source> selSrc{GID::ITSTPC, GID::ITSTPCTRD, GID::ITSTPCTRDTOF}; // for Instance
149 // LOGP(info, "Number of vertex tracks: {}", vtxRefs.size());
150 const auto nv = (vtxRefs.size() > 0) ? vtxRefs.size() - 1 : 0; // note: the last entry groups the tracks which were not related to any vertex, to skip them, use vtxRefs.size()-1
151
152 for (int iv = 0; iv < nv; iv++) {
153 const auto& vtref = vtxRefs[iv];
154 // LOGP(info, "Processing vertex {} with {} tracks", iv, vtref.getEntries());
155 vertex = recoData.getPrimaryVertex(iv).getXYZ();
156 // LOGP(info, "Vertex position: x={} y={} z={}", vertex.x(), vertex.y(), vertex.z());
157
158 for (auto src : selSrc) {
159 int idMin = vtxRefs[iv].getFirstEntryOfSource(src), idMax = idMin + vtxRefs[iv].getEntriesOfSource(src);
160 // LOGP(info, "Source {}: idMin={} idMax={}", GID::getSourceName(src), idMin, idMax);
161
162 for (int i = idMin; i < idMax; i++) {
163 auto vid = trackIndex[i];
164 const auto& track = recoData.getTrackParam(vid); // this is a COPY of the track param which we will modify during DCA calculation
165 auto gidTPC = recoData.getTPCContributorGID(vid);
166 if (gidTPC.isSourceSet()) {
167 const auto idxTPC = gidTPC.getIndex();
168 if (mCuts.goodTrack(tracksTPC[idxTPC]) && acceptDCA(tracksTPC[idxTPC], vertex, true)) {
169 indices.emplace_back(idxTPC);
170 }
171 }
172 }
173 }
174 }
175
176 } else {
177 for (size_t i = 0; i < nTracks; ++i) {
178 if (mCuts.goodTrack(tracksTPC[i]) && acceptDCA(tracksTPC[i], vertex)) {
179 indices.emplace_back(i);
180 }
181 }
182 }
183
184 size_t nTracksSel = indices.size();
185
186 if ((mMaxTracksPerTF != -1) && (nTracksSel > mMaxTracksPerTF)) {
187 // in case no good tracks have been found
188 if (indices.empty()) {
189 mMIPTracks.clear();
190 if (mSendDummy) {
191 sendOutput(pc.outputs());
192 }
193 return;
194 }
195
196 // shuffle indices to good tracks
197 std::minstd_rand rng(std::time(nullptr));
198 std::shuffle(indices.begin(), indices.end(), rng);
199
200 // copy good tracks
201 nTracksSel = (mMaxTracksPerTF > indices.size()) ? indices.size() : mMaxTracksPerTF;
202 }
203
204 for (int i = 0; i < nTracksSel; ++i) {
205 mMIPTracks.emplace_back(tracksTPC[indices[i]]);
206 }
207
208 LOGP(info, "Filtered {} / {} MIP tracks out of {} total tpc tracks, using {}", mMIPTracks.size(), indices.size(), tracksTPC.size(), useGlobalTracks ? "global tracks" : "TPC only tracks");
209 sendOutput(pc.outputs());
210 mMIPTracks.clear();
211}
212
214{
216 return;
217 }
218 if (matcher == ConcreteDataMatcher("GLO", "MEANVERTEX", 0)) {
219 LOG(info) << "Setting new MeanVertex: " << ((const o2::dataformats::MeanVertexObject*)obj)->asString();
220 mVtx = *(const o2::dataformats::MeanVertexObject*)obj;
221 return;
222 }
223}
224
225void MIPTrackFilterDevice::sendOutput(DataAllocator& output) { output.snapshot(Output{header::gDataOriginTPC, "MIPS", 0}, mMIPTracks); }
226
228{
229 LOG(info) << "Finalizig MIP Tracks filter";
230}
231
232bool MIPTrackFilterDevice::acceptDCA(o2::track::TrackPar propTrack, o2::math_utils::Point3D<float> refPoint, bool useDCAz)
233{
234 if (mDCACut < 0) {
235 return true;
236 }
237
238 auto propagator = o2::base::Propagator::Instance();
239 std::array<float, 2> dca;
240 const auto ok = propagator->propagateToDCABxByBz(refPoint, propTrack, 2., o2::base::Propagator::MatCorrType::USEMatCorrLUT, &dca);
241 const auto dcar = std::abs(dca[0]);
242
243 return ok && (dcar < mDCACut) && (!useDCAz || (std::abs(dca[1]) < mDCAZCut));
244}
245
247{
248 std::vector<OutputSpec> outputs;
249 outputs.emplace_back(header::gDataOriginTPC, "MIPS", 0, Lifetime::Sporadic);
250
251 const auto useMC = false;
252 auto dataRequest = std::make_shared<DataRequest>();
253 dataRequest->requestTracks(srcTracks, useMC);
254 dataRequest->requestPrimaryVertices(useMC);
255
256 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
257 true, // GRPECS=true
258 false, // GRPLHCIF
259 true, // GRPMagField
260 true, // askMatLUT
262 dataRequest->inputs,
263 true);
264
265 dataRequest->inputs.emplace_back("meanvtx", "GLO", "MEANVERTEX", 0, Lifetime::Condition, o2::framework::ccdbParamSpec("GLO/Calib/MeanVertex", {}, 1));
266
267 return DataProcessorSpec{
268 "tpc-miptrack-filter",
269 dataRequest->inputs,
270 outputs,
271 adaptFromTask<MIPTrackFilterDevice>(ggRequest, dataRequest, srcTracks),
272 Options{
273 {"min-momentum", VariantType::Double, 0.35, {"minimum momentum cut"}},
274 {"max-momentum", VariantType::Double, 0.55, {"maximum momentum cut"}},
275 {"min-dedx", VariantType::Double, 10., {"minimum dEdx cut"}},
276 {"max-dedx", VariantType::Double, 200., {"maximum dEdx cut"}},
277 {"min-clusters", VariantType::Int, 60, {"minimum number of clusters in a track"}},
278 {"processEveryNthTF", VariantType::Int, 1, {"Using only a fraction of the data: 1: Use every TF, 10: Process only every tenth TF."}},
279 {"maxTracksPerTF", VariantType::Int, -1, {"Maximum number of processed tracks per TF (-1 for processing all tracks)"}},
280 {"process-first-n-TFs", VariantType::Int, 1, {"Number of first TFs which are not sampled"}},
281 {"send-dummy-data", VariantType::Bool, false, {"Send empty data in case TF is skipped"}},
282 {"dont-cut-loopers", VariantType::Bool, false, {"Do not cut loopers by comparing zout-zin"}},
283 {"dca-cut", VariantType::Float, 3.f, {"DCA cut in xy (cm), < 0 to disable cut in xy and z"}},
284 {"dca-z-cut", VariantType::Float, 5.f, {"DCA cut in z (cm)"}},
285 }};
286}
287
288} // namespace o2::tpc
Wrapper container for different reconstructed object types.
uint64_t vertex
Definition RawEventData.h:9
int32_t i
Helper for geometry and GRP related CCDB requests.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Workflow to filter MIP tracks and streams them to other devices.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:147
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 finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void run(ProcessingContext &pc) final
void init(framework::InitContext &ic) final
MIPTrackFilterDevice(std::shared_ptr< o2::base::GRPGeomRequest > gr, std::shared_ptr< DataRequest > dr, GID::mask_t trackSourcesMask)
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
GLenum src
Definition glcorearb.h:1767
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 > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
uint32_t getCurrentTF(o2::framework::ProcessingContext &pc)
Global TPC definitions and constants.
Definition SimTraits.h:167
o2::framework::DataProcessorSpec getMIPTrackFilterSpec(GID::mask_t srcTracks=GID::getSourcesMask("TPC"))
create a processor spec
GTrackID getTPCContributorGID(GTrackID source) const
const o2::track::TrackParCov & getTrackParam(GTrackID gidx) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::dataformats::PrimaryVertex & getPrimaryVertex(int i) const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"