Project
Loading...
Searching...
No Matches
CookedTrackerSpec.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
13
14#include <vector>
15
16#include "TGeoGlobalMagField.h"
17
31
32#include "Field/MagneticField.h"
37#include "ITStracking/IOUtils.h"
40
44
45using namespace o2::framework;
46
47namespace o2
48{
49namespace its
50{
51
53
54CookedTrackerDPL::CookedTrackerDPL(std::shared_ptr<o2::base::GRPGeomRequest> gr, bool useMC, int trgType, TrackingMode::Type trMode) : mGGCCDBRequest(gr), mUseMC(useMC), mUseTriggers{trgType}, mMode(trMode)
55{
56 mVertexerTraitsPtr = std::make_unique<VertexerTraits>();
57 mVertexerPtr = std::make_unique<Vertexer>(mVertexerTraitsPtr.get());
58}
59
61{
62 mTimer.Stop();
63 mTimer.Reset();
65 auto nthreads = ic.options().get<int>("nthreads");
66 mTracker.setNumberOfThreads(nthreads);
67 mTaskArena = std::make_shared<tbb::task_arena>(nthreads);
68 mMemoryPool = std::make_unique<BoundedMemoryResource>();
69 mVertexerPtr->setMemoryPool(mMemoryPool);
70 mVertexerPtr->setNThreads(nthreads, mTaskArena);
71 mVertexerTraitsPtr->setMemoryPool(mMemoryPool);
72}
73
75{
76 mTimer.Start(false);
77 updateTimeDependentParams(pc);
78 auto compClusters = pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("compClusters");
79 gsl::span<const unsigned char> patterns = pc.inputs().get<gsl::span<unsigned char>>("patterns");
80
81 // code further down does assignment to the rofs and the altered object is used for output
82 // we therefore need a copy of the vector rather than an object created directly on the input data,
83 // the output vector however is created directly inside the message memory thus avoiding copy by
84 // snapshot
85 auto rofsinput = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
86 gsl::span<const o2::itsmft::PhysTrigger> physTriggers;
87 std::vector<o2::itsmft::PhysTrigger> fromTRD;
88 if (mUseTriggers == 2) { // use TRD triggers
90 auto trdTriggers = pc.inputs().get<gsl::span<o2::trd::TriggerRecord>>("phystrig");
91 for (const auto& trig : trdTriggers) {
92 if (trig.getBCData() >= ir && trig.getNumberOfTracklets()) {
93 ir = trig.getBCData();
94 fromTRD.emplace_back(o2::itsmft::PhysTrigger{ir, 0});
95 }
96 }
97 physTriggers = gsl::span<const o2::itsmft::PhysTrigger>(fromTRD.data(), fromTRD.size());
98 } else if (mUseTriggers == 1) { // use Phys triggers from ITS stream
99 physTriggers = pc.inputs().get<gsl::span<o2::itsmft::PhysTrigger>>("phystrig");
100 }
101
102 auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "ITSTrackROF", 0}, rofsinput.begin(), rofsinput.end());
103
104 std::unique_ptr<const o2::dataformats::MCTruthContainer<o2::MCCompLabel>> labels;
105 gsl::span<itsmft::MC2ROFRecord const> mc2rofs;
106 if (mUseMC) {
107 labels = pc.inputs().get<const o2::dataformats::MCTruthContainer<o2::MCCompLabel>*>("labels");
108 // get the array as read-onlt span, a snapshot is send forward
109 mc2rofs = pc.inputs().get<gsl::span<itsmft::MC2ROFRecord>>("MC2ROframes");
110 }
111 TimeFrame mTimeFrame;
112 mTimeFrame.setMemoryPool(mMemoryPool);
113
114 LOG(info) << "ITSCookedTracker pulled " << compClusters.size() << " clusters, in " << rofs.size() << " RO frames";
115
116 std::vector<o2::MCCompLabel> trackLabels;
117 if (mUseMC) {
118 mTracker.setMCTruthContainers(labels.get(), &trackLabels);
119 }
120
121 mVertexerPtr->adoptTimeFrame(mTimeFrame);
122
123 auto& vertROFvec = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "VERTICESROF", 0});
124 auto& vertices = pc.outputs().make<std::vector<Vertex>>(Output{"ITS", "VERTICES", 0});
125 auto& tracks = pc.outputs().make<std::vector<o2::its::TrackITS>>(Output{"ITS", "TRACKS", 0});
126 auto& clusIdx = pc.outputs().make<std::vector<int>>(Output{"ITS", "TRACKCLSID", 0});
127 auto& irFrames = pc.outputs().make<std::vector<o2::dataformats::IRFrame>>(Output{"ITS", "IRFRAMES", 0});
128
129 const auto& alpParams = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance(); // RS: this should come from CCDB
130 int nBCPerTF = mTracker.getContinuousMode() ? alpParams.roFrameLengthInBC : alpParams.roFrameLengthTrig;
131
132 gsl::span<const unsigned char>::iterator pattIt_timeframe = patterns.begin();
133 gsl::span<const unsigned char>::iterator pattIt_tracker = patterns.begin();
134 gsl::span<itsmft::ROFRecord> rofspan(rofs);
135 mTimeFrame.loadROFrameData(rofspan, compClusters, pattIt_timeframe, mDict, labels.get());
136
137 const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts
138 FastMultEst multEst; // mult estimator
139 std::vector<uint8_t> processingMask;
140 int cutVertexMult{0}, cutRandomMult = int(rofsinput.size()) - multEst.selectROFs(rofsinput, compClusters, physTriggers, processingMask);
141
142 // auto processingMask_ephemeral = processingMask;
143 mTimeFrame.setMultiplicityCutMask(processingMask);
144 float vertexerElapsedTime;
145 if (mRunVertexer) {
146 vertexerElapsedTime = mVertexerPtr->clustersToVertices([&](std::string s) { LOG(info) << s; });
147 }
148 LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms in {} ROFs", vertexerElapsedTime, rofspan.size());
149 for (size_t iRof{0}; iRof < rofspan.size(); ++iRof) {
150 auto& rof = rofspan[iRof];
151
152 auto& vtxROF = vertROFvec.emplace_back(rof); // register entry and number of vertices in the
153 vtxROF.setFirstEntry(vertices.size());
154 vtxROF.setNEntries(0);
155 if (!processingMask[iRof]) {
156 rof.setFirstEntry(tracks.size());
157 rof.setNEntries(0);
158 continue;
159 }
160
161 std::vector<o2::dataformats::Vertex<o2::dataformats::TimeStamp<int>>> vtxVecLoc;
162 for (auto& v : mTimeFrame.getPrimaryVertices(iRof)) {
163 vtxVecLoc.push_back(v);
164 }
165
166 if (multEstConf.isVtxMultCutRequested()) { // cut was requested
167 std::vector<o2::dataformats::Vertex<o2::dataformats::TimeStamp<int>>> vtxVecSel;
168 vtxVecSel.swap(vtxVecLoc);
169 int nv = vtxVecSel.size(), nrej = 0;
170 for (const auto& vtx : vtxVecSel) {
171 if (!multEstConf.isPassingVtxMultCut(vtx.getNContributors())) {
172 LOG(info) << "Found vertex mult. " << vtx.getNContributors() << " is outside of requested range " << multEstConf.cutMultVtxLow << " : " << multEstConf.cutMultVtxHigh << " | ROF " << rof.getBCData();
173 nrej++;
174 continue; // skip vertex of unwanted multiplicity
175 }
176 vtxVecLoc.push_back(vtx);
177 }
178 if (nv && (nrej == nv)) { // all vertices were rejected
179 cutVertexMult++;
180 processingMask[iRof] = false;
181 }
182 }
183 if (vtxVecLoc.empty()) {
184 if (multEstConf.cutMultVtxLow < 1) { // do blind search only if there is no cut on the low mult vertices
185 vtxVecLoc.emplace_back();
186 } else {
187 rof.setFirstEntry(tracks.size());
188 rof.setNEntries(0);
189 continue;
190 }
191 } else { // save vertices
192 vtxROF.setNEntries(vtxVecLoc.size());
193 for (const auto& vtx : vtxVecLoc) {
194 vertices.push_back(vtx);
195 }
196 }
197
198 mTracker.setVertices(vtxVecLoc);
199 mTracker.process(compClusters, pattIt_tracker, mDict, tracks, clusIdx, rof);
200 if (processingMask[iRof]) {
201 irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1).info = tracks.size();
202 }
203 }
204 LOGP(info, " - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}", cutRandomMult + cutVertexMult, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult);
205 LOG(info) << "ITSCookedTracker pushed " << tracks.size() << " tracks and " << vertices.size() << " vertices";
206
207 if (mUseMC) {
208 pc.outputs().snapshot(Output{"ITS", "TRACKSMCTR", 0}, trackLabels);
209 pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0}, mc2rofs);
210 }
211 mTimer.Stop();
212}
213
215{
216 LOGF(info, "ITS Cooked-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots",
217 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
218}
219
221void CookedTrackerDPL::updateTimeDependentParams(ProcessingContext& pc)
222{
224 static bool initOnceDone = false;
225 if (!initOnceDone) { // this params need to be queried only once
226 initOnceDone = true;
227 pc.inputs().get<o2::itsmft::TopologyDictionary*>("cldict"); // just to trigger the finaliseCCDB
229 if (pc.inputs().getPos("itsTGeo") >= 0) {
230 pc.inputs().get<o2::its::GeometryTGeo*>("itsTGeo");
231 }
232 mVertexerPtr->setParameters(TrackingMode::getVertexingParameters(mMode));
236 mTracker.setGeometry(geom);
237 mTracker.setConfigParams();
238 LOG(info) << "Tracking mode " << TrackingMode::toString(mMode);
239 if (mMode == TrackingMode::Cosmics) {
240 LOG(info) << "Setting cosmics parameters...";
241 mTracker.setParametersCosmics();
242 mRunVertexer = false;
243 }
244 mTracker.setBz(o2::base::Propagator::Instance()->getNominalBz());
245 bool continuous = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::ITS);
246 LOG(info) << "ITSCookedTracker RO: continuous=" << continuous;
247 mTracker.setContinuousMode(continuous);
248 }
249}
250
253{
255 return;
256 }
257 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
258 LOG(info) << "cluster dictionary updated";
260 return;
261 }
262 // Note: strictly speaking, for Configurable params we don't need finaliseCCDB check, the singletons are updated at the CCDB fetcher level
263 if (matcher == ConcreteDataMatcher("ITS", "ALPIDEPARAM", 0)) {
264 LOG(info) << "Alpide param updated";
266 par.printKeyValues();
267 return;
268 }
269 if (matcher == ConcreteDataMatcher("ITS", "GEOMTGEO", 0)) {
270 LOG(info) << "ITS GeometryTGeo loaded from ccdb";
272 return;
273 }
274}
275
276DataProcessorSpec getCookedTrackerSpec(bool useMC, bool useGeom, int trgType, TrackingMode::Type trmode)
277{
278 std::vector<InputSpec> inputs;
279 inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe);
280 inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe);
281 inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe);
282 inputs.emplace_back("cldict", "ITS", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/ClusterDictionary"));
283 inputs.emplace_back("alppar", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam"));
284 if (trgType == 1) {
285 inputs.emplace_back("phystrig", "ITS", "PHYSTRIG", 0, Lifetime::Timeframe);
286 } else if (trgType == 2) {
287 inputs.emplace_back("phystrig", "TRD", "TRKTRGRD", 0, Lifetime::Timeframe);
288 }
289
290 std::vector<OutputSpec> outputs;
291 outputs.emplace_back("ITS", "TRACKS", 0, Lifetime::Timeframe);
292 outputs.emplace_back("ITS", "TRACKCLSID", 0, Lifetime::Timeframe);
293 outputs.emplace_back("ITS", "ITSTrackROF", 0, Lifetime::Timeframe);
294 outputs.emplace_back("ITS", "VERTICES", 0, Lifetime::Timeframe);
295 outputs.emplace_back("ITS", "VERTICESROF", 0, Lifetime::Timeframe);
296 outputs.emplace_back("ITS", "IRFRAMES", 0, Lifetime::Timeframe);
297
298 if (useMC) {
299 inputs.emplace_back("labels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe);
300 inputs.emplace_back("MC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe);
301 outputs.emplace_back("ITS", "TRACKSMCTR", 0, Lifetime::Timeframe);
302 outputs.emplace_back("ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe);
303 }
304 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
305 true, // GRPECS=true
306 false, // GRPLHCIF
307 true, // GRPMagField
308 true, // askMatLUT
310 inputs,
311 true);
312 if (!useGeom) {
313 ggRequest->addInput({"itsTGeo", "ITS", "GEOMTGEO", 0, Lifetime::Condition, framework::ccdbParamSpec("ITS/Config/Geometry")}, inputs);
314 }
315 return DataProcessorSpec{
316 "its-cooked-tracker",
317 inputs,
318 outputs,
319 AlgorithmSpec{adaptFromTask<CookedTrackerDPL>(ggRequest,
320 useMC,
321 trgType,
322 trmode)},
323 Options{{"nthreads", VariantType::Int, 1, {"Number of threads"}}}};
324}
325
326} // namespace its
327} // namespace o2
Definition of the ITS/MFT clusterer settings.
Definition of the ITSMFT compact cluster.
Definition of the ITSMFT cluster.
Definition of the Names Generator class.
Definition of the GeometryManager class.
Class to delimit start and end IR of certain time period.
Definition of the GeometryTGeo class.
Configuration parameters for ITS fast multiplicity estimator.
Fast multiplicity estimator for ITS.
Definition of the ITSMFT ROFrame (trigger) record.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Definition of the MagF class.
Definition Physics trigger record extracted from the ITS/MFT stream.
Definition of the ITS track.
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:143
A container to hold and manage MC truth information/labels.
static constexpr ID ITS
Definition DetID.h:63
void snapshot(const Output &spec, T const &object)
decltype(auto) make(const Output &spec, Args... args)
ConfigParamRegistry const & options()
Definition InitContext.h:33
int getPos(const char *name) const
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.
ServiceRegistryRef services()
The services registry associated with this processing context.
CookedTrackerDPL(std::shared_ptr< o2::base::GRPGeomRequest > gr, bool useMC, int trgType, TrackingMode::Type trMode)
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void setClusterDictionary(const o2::itsmft::TopologyDictionary *d)
void run(ProcessingContext &pc) final
void init(InitContext &ic) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void process(gsl::span< const CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &it, const o2::itsmft::TopologyDictionary *dict, U &tracks, V &clusIdx, o2::itsmft::ROFRecord &rof)
void setGeometry(o2::its::GeometryTGeo *geom)
void setContinuousMode(bool mode)
void setBz(Double_t bz)
void setMCTruthContainers(const o2::dataformats::MCTruthContainer< o2::MCCompLabel > *clsLabels, std::vector< o2::MCCompLabel > *trkLabels)
void setNumberOfThreads(Int_t n)
void setVertices(const std::vector< Vertex > &vertices)
static GeometryTGeo * Instance()
void fillMatrixCache(int mask) override
static void adopt(GeometryTGeo *raw, bool canDelete=false)
const GLdouble * v
Definition glcorearb.h:832
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
std::vector< VertexingParameters > getVertexingParameters(Type mode)
std::string toString(Type mode)
framework::DataProcessorSpec getCookedTrackerSpec(bool useMC, bool useGeom, int useTrig, TrackingMode::Type trMode)
o2::dataformats::Vertex< o2::dataformats::TimeStamp< int > > Vertex
Definition TimeFrame.h:65
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint32_t lastRandomSeed
number of layers actually used
Definition FastMultEst.h:41
int selectROFs(const gsl::span< const o2::itsmft::ROFRecord > rofs, const gsl::span< const o2::itsmft::CompClusterExt > clus, const gsl::span< const o2::itsmft::PhysTrigger > trig, std::vector< uint8_t > &sel)
void setMultiplicityCutMask(const std::vector< uint8_t > &cutMask)
Definition TimeFrame.h:226
int loadROFrameData(const o2::itsmft::ROFRecord &rof, gsl::span< const itsmft::Cluster > clusters, const dataformats::MCTruthContainer< MCCompLabel > *mcLabels=nullptr)
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
Definition TimeFrame.h:356
void setMemoryPool(std::shared_ptr< BoundedMemoryResource > &pool)
memory management
static constexpr int T2L
Definition Cartesian.h:55
static constexpr int T2GRot
Definition Cartesian.h:57
static constexpr int T2G
Definition Cartesian.h:56
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)