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/ROframe.h"
38#include "ITStracking/IOUtils.h"
41
45
46using namespace o2::framework;
47
48namespace o2
49{
50namespace its
51{
52
54
55CookedTrackerDPL::CookedTrackerDPL(std::shared_ptr<o2::base::GRPGeomRequest> gr, bool useMC, int trgType, const TrackingMode& trMode) : mGGCCDBRequest(gr), mUseMC(useMC), mUseTriggers{trgType}, mMode(trMode)
56{
57 mVertexerTraitsPtr = std::make_unique<VertexerTraits>();
58 mVertexerPtr = std::make_unique<Vertexer>(mVertexerTraitsPtr.get());
59}
60
62{
63 mTimer.Stop();
64 mTimer.Reset();
66 auto nthreads = ic.options().get<int>("nthreads");
67 mTracker.setNumberOfThreads(nthreads);
68}
69
71{
72 mTimer.Start(false);
73 updateTimeDependentParams(pc);
74 auto compClusters = pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("compClusters");
75 gsl::span<const unsigned char> patterns = pc.inputs().get<gsl::span<unsigned char>>("patterns");
76
77 // code further down does assignment to the rofs and the altered object is used for output
78 // we therefore need a copy of the vector rather than an object created directly on the input data,
79 // the output vector however is created directly inside the message memory thus avoiding copy by
80 // snapshot
81 auto rofsinput = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
82 gsl::span<const o2::itsmft::PhysTrigger> physTriggers;
83 std::vector<o2::itsmft::PhysTrigger> fromTRD;
84 if (mUseTriggers == 2) { // use TRD triggers
86 auto trdTriggers = pc.inputs().get<gsl::span<o2::trd::TriggerRecord>>("phystrig");
87 for (const auto& trig : trdTriggers) {
88 if (trig.getBCData() >= ir && trig.getNumberOfTracklets()) {
89 ir = trig.getBCData();
90 fromTRD.emplace_back(o2::itsmft::PhysTrigger{ir, 0});
91 }
92 }
93 physTriggers = gsl::span<const o2::itsmft::PhysTrigger>(fromTRD.data(), fromTRD.size());
94 } else if (mUseTriggers == 1) { // use Phys triggers from ITS stream
95 physTriggers = pc.inputs().get<gsl::span<o2::itsmft::PhysTrigger>>("phystrig");
96 }
97
98 auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "ITSTrackROF", 0}, rofsinput.begin(), rofsinput.end());
99
100 std::unique_ptr<const o2::dataformats::MCTruthContainer<o2::MCCompLabel>> labels;
101 gsl::span<itsmft::MC2ROFRecord const> mc2rofs;
102 if (mUseMC) {
103 labels = pc.inputs().get<const o2::dataformats::MCTruthContainer<o2::MCCompLabel>*>("labels");
104 // get the array as read-onlt span, a snapshot is send forward
105 mc2rofs = pc.inputs().get<gsl::span<itsmft::MC2ROFRecord>>("MC2ROframes");
106 }
107 TimeFrame mTimeFrame;
108
109 LOG(info) << "ITSCookedTracker pulled " << compClusters.size() << " clusters, in " << rofs.size() << " RO frames";
110
111 std::vector<o2::MCCompLabel> trackLabels;
112 if (mUseMC) {
113 mTracker.setMCTruthContainers(labels.get(), &trackLabels);
114 }
115
117 mVertexerPtr->adoptTimeFrame(mTimeFrame);
118
119 auto& vertROFvec = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "VERTICESROF", 0});
120 auto& vertices = pc.outputs().make<std::vector<Vertex>>(Output{"ITS", "VERTICES", 0});
121 auto& tracks = pc.outputs().make<std::vector<o2::its::TrackITS>>(Output{"ITS", "TRACKS", 0});
122 auto& clusIdx = pc.outputs().make<std::vector<int>>(Output{"ITS", "TRACKCLSID", 0});
123 auto& irFrames = pc.outputs().make<std::vector<o2::dataformats::IRFrame>>(Output{"ITS", "IRFRAMES", 0});
124
125 const auto& alpParams = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance(); // RS: this should come from CCDB
126 int nBCPerTF = mTracker.getContinuousMode() ? alpParams.roFrameLengthInBC : alpParams.roFrameLengthTrig;
127
128 gsl::span<const unsigned char>::iterator pattIt_timeframe = patterns.begin();
129 gsl::span<const unsigned char>::iterator pattIt_tracker = patterns.begin();
130 gsl::span<itsmft::ROFRecord> rofspan(rofs);
131 mTimeFrame.loadROFrameData(rofspan, compClusters, pattIt_timeframe, mDict, labels.get());
132
133 const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts
134 FastMultEst multEst; // mult estimator
135 std::vector<uint8_t> processingMask;
136 int cutVertexMult{0}, cutRandomMult = int(rofsinput.size()) - multEst.selectROFs(rofsinput, compClusters, physTriggers, processingMask);
137
138 // auto processingMask_ephemeral = processingMask;
139 mTimeFrame.setMultiplicityCutMask(processingMask);
140 float vertexerElapsedTime;
141 if (mRunVertexer) {
142 vertexerElapsedTime = mVertexerPtr->clustersToVertices([&](std::string s) { LOG(info) << s; });
143 }
144 LOG(info) << fmt::format(" - Vertex seeding total elapsed time: {} ms in {} ROFs", vertexerElapsedTime, rofspan.size());
145 for (size_t iRof{0}; iRof < rofspan.size(); ++iRof) {
146 auto& rof = rofspan[iRof];
147
148 auto& vtxROF = vertROFvec.emplace_back(rof); // register entry and number of vertices in the
149 vtxROF.setFirstEntry(vertices.size());
150 vtxROF.setNEntries(0);
151 if (!processingMask[iRof]) {
152 rof.setFirstEntry(tracks.size());
153 rof.setNEntries(0);
154 continue;
155 }
156
157 std::vector<o2::dataformats::Vertex<o2::dataformats::TimeStamp<int>>> vtxVecLoc;
158 for (auto& v : mTimeFrame.getPrimaryVertices(iRof)) {
159 vtxVecLoc.push_back(v);
160 }
161
162 if (multEstConf.isVtxMultCutRequested()) { // cut was requested
163 std::vector<o2::dataformats::Vertex<o2::dataformats::TimeStamp<int>>> vtxVecSel;
164 vtxVecSel.swap(vtxVecLoc);
165 int nv = vtxVecSel.size(), nrej = 0;
166 for (const auto& vtx : vtxVecSel) {
167 if (!multEstConf.isPassingVtxMultCut(vtx.getNContributors())) {
168 LOG(info) << "Found vertex mult. " << vtx.getNContributors() << " is outside of requested range " << multEstConf.cutMultVtxLow << " : " << multEstConf.cutMultVtxHigh << " | ROF " << rof.getBCData();
169 nrej++;
170 continue; // skip vertex of unwanted multiplicity
171 }
172 vtxVecLoc.push_back(vtx);
173 }
174 if (nv && (nrej == nv)) { // all vertices were rejected
175 cutVertexMult++;
176 processingMask[iRof] = false;
177 }
178 }
179 if (vtxVecLoc.empty()) {
180 if (multEstConf.cutMultVtxLow < 1) { // do blind search only if there is no cut on the low mult vertices
181 vtxVecLoc.emplace_back();
182 } else {
183 rof.setFirstEntry(tracks.size());
184 rof.setNEntries(0);
185 continue;
186 }
187 } else { // save vertices
188 vtxROF.setNEntries(vtxVecLoc.size());
189 for (const auto& vtx : vtxVecLoc) {
190 vertices.push_back(vtx);
191 }
192 }
193
194 mTracker.setVertices(vtxVecLoc);
195 mTracker.process(compClusters, pattIt_tracker, mDict, tracks, clusIdx, rof);
196 if (processingMask[iRof]) {
197 irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1).info = tracks.size();
198 }
199 }
200 LOGP(info, " - rejected {}/{} ROFs: random/mult.sel:{} (seed {}), vtx.sel:{}", cutRandomMult + cutVertexMult, rofspan.size(), cutRandomMult, multEst.lastRandomSeed, cutVertexMult);
201 LOG(info) << "ITSCookedTracker pushed " << tracks.size() << " tracks and " << vertices.size() << " vertices";
202
203 if (mUseMC) {
204 pc.outputs().snapshot(Output{"ITS", "TRACKSMCTR", 0}, trackLabels);
205 pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0}, mc2rofs);
206 }
207 mTimer.Stop();
208}
209
211{
212 LOGF(info, "ITS Cooked-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots",
213 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
214}
215
217void CookedTrackerDPL::updateTimeDependentParams(ProcessingContext& pc)
218{
220 static bool initOnceDone = false;
221 if (!initOnceDone) { // this params need to be queried only once
222 initOnceDone = true;
223 pc.inputs().get<o2::itsmft::TopologyDictionary*>("cldict"); // just to trigger the finaliseCCDB
225 if (pc.inputs().getPos("itsTGeo") >= 0) {
226 pc.inputs().get<o2::its::GeometryTGeo*>("itsTGeo");
227 }
228 mVertexerPtr->getGlobalConfiguration();
232 mTracker.setGeometry(geom);
233 mTracker.setConfigParams();
234 LOG(info) << "Tracking mode " << mMode;
235 if (mMode == TrackingMode::Cosmics) {
236 LOG(info) << "Setting cosmics parameters...";
237 mTracker.setParametersCosmics();
238 mRunVertexer = false;
239 }
240 mTracker.setBz(o2::base::Propagator::Instance()->getNominalBz());
241 bool continuous = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::ITS);
242 LOG(info) << "ITSCookedTracker RO: continuous=" << continuous;
243 mTracker.setContinuousMode(continuous);
244 }
245}
246
249{
251 return;
252 }
253 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
254 LOG(info) << "cluster dictionary updated";
256 return;
257 }
258 // Note: strictly speaking, for Configurable params we don't need finaliseCCDB check, the singletons are updated at the CCDB fetcher level
259 if (matcher == ConcreteDataMatcher("ITS", "ALPIDEPARAM", 0)) {
260 LOG(info) << "Alpide param updated";
262 par.printKeyValues();
263 return;
264 }
265 if (matcher == ConcreteDataMatcher("ITS", "GEOMTGEO", 0)) {
266 LOG(info) << "ITS GeometryTGeo loaded from ccdb";
268 return;
269 }
270}
271
272DataProcessorSpec getCookedTrackerSpec(bool useMC, bool useGeom, int trgType, const std::string& trModeS)
273{
274 std::vector<InputSpec> inputs;
275 inputs.emplace_back("compClusters", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe);
276 inputs.emplace_back("patterns", "ITS", "PATTERNS", 0, Lifetime::Timeframe);
277 inputs.emplace_back("ROframes", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe);
278 inputs.emplace_back("cldict", "ITS", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/ClusterDictionary"));
279 inputs.emplace_back("alppar", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam"));
280 if (trgType == 1) {
281 inputs.emplace_back("phystrig", "ITS", "PHYSTRIG", 0, Lifetime::Timeframe);
282 } else if (trgType == 2) {
283 inputs.emplace_back("phystrig", "TRD", "TRKTRGRD", 0, Lifetime::Timeframe);
284 }
285
286 std::vector<OutputSpec> outputs;
287 outputs.emplace_back("ITS", "TRACKS", 0, Lifetime::Timeframe);
288 outputs.emplace_back("ITS", "TRACKCLSID", 0, Lifetime::Timeframe);
289 outputs.emplace_back("ITS", "ITSTrackROF", 0, Lifetime::Timeframe);
290 outputs.emplace_back("ITS", "VERTICES", 0, Lifetime::Timeframe);
291 outputs.emplace_back("ITS", "VERTICESROF", 0, Lifetime::Timeframe);
292 outputs.emplace_back("ITS", "IRFRAMES", 0, Lifetime::Timeframe);
293
294 if (useMC) {
295 inputs.emplace_back("labels", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe);
296 inputs.emplace_back("MC2ROframes", "ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe);
297 outputs.emplace_back("ITS", "TRACKSMCTR", 0, Lifetime::Timeframe);
298 outputs.emplace_back("ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe);
299 }
300 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
301 true, // GRPECS=true
302 false, // GRPLHCIF
303 true, // GRPMagField
304 true, // askMatLUT
306 inputs,
307 true);
308 if (!useGeom) {
309 ggRequest->addInput({"itsTGeo", "ITS", "GEOMTGEO", 0, Lifetime::Condition, framework::ccdbParamSpec("ITS/Config/Geometry")}, inputs);
310 }
311 return DataProcessorSpec{
312 "its-cooked-tracker",
313 inputs,
314 outputs,
315 AlgorithmSpec{adaptFromTask<CookedTrackerDPL>(ggRequest,
316 useMC,
317 trgType,
318 trModeS == "sync" ? o2::its::TrackingMode::Sync : trModeS == "async" ? o2::its::TrackingMode::Async
320 Options{{"nthreads", VariantType::Int, 1, {"Number of threads"}}}};
321}
322
323} // namespace its
324} // 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.
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
CookedTrackerDPL(std::shared_ptr< o2::base::GRPGeomRequest > gr, bool useMC, int trgType, const TrackingMode &trMode)
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)
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
Definition TimeFrame.h:355
int loadROFrameData(const o2::itsmft::ROFRecord &rof, gsl::span< const itsmft::Cluster > clusters, const dataformats::MCTruthContainer< MCCompLabel > *mcLabels=nullptr)
void setMultiplicityCutMask(const std::vector< uint8_t > &cutMask)
Definition TimeFrame.h:216
struct _cl_event * event
Definition glcorearb.h:2982
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
framework::DataProcessorSpec getCookedTrackerSpec(bool useMC, bool useGeom, int useTrig, const std::string &trMode)
o2::dataformats::Vertex< o2::dataformats::TimeStamp< int > > Vertex
Definition ROframe.h:37
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)
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)