Project
Loading...
Searching...
No Matches
CheckResid.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#include <vector>
17#include <TStopwatch.h>
34#include "ITStracking/IOUtils.h"
41#ifdef WITH_OPENMP
42#include <omp.h>
43#endif
44
45// Attention: in case the residuals are checked with geometry different from the one used for initial reconstruction,
46// pass a --configKeyValues option for vertex refit as:
47// ;pvertexer.useMeanVertexConstraint=false;pvertexer.iniScale2=100;pvertexer.acceptableScale2=10.;
48// In any case, it is better to pass ;pvertexer.useMeanVertexConstraint=false;
49
50namespace o2::checkresid
51{
52using namespace o2::framework;
55
61
62class CheckResidSpec : public Task
63{
64 public:
65 CheckResidSpec(std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> gr, GTrackID::mask_t src, bool useMC /*, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts*/)
66 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src), mUseMC(useMC)
67 {
68 /*
69 mTPCCorrMapsLoader.setLumiScaleType(sclOpts.lumiType);
70 mTPCCorrMapsLoader.setLumiScaleMode(sclOpts.lumiMode);
71 mTPCCorrMapsLoader.setCheckCTPIDCConsistency(sclOpts.checkCTPIDCconsistency);
72 */
73 }
74 ~CheckResidSpec() final = default;
75 void init(InitContext& ic) final;
76 void run(ProcessingContext& pc) final;
77 void endOfStream(EndOfStreamContext& ec) final;
78 void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final;
79 void process();
80
81 private:
82 void updateTimeDependentParams(ProcessingContext& pc);
83 bool refitPV(o2::dataformats::PrimaryVertex& pv, int vid);
84 bool refitITStrack(o2::track::TrackParCov& track, GTrackID gid);
85 bool processITSTrack(const o2::its::TrackITS& iTrack, const o2::dataformats::PrimaryVertex& pv, o2::checkresid::Track& resTrack);
86
87 o2::globaltracking::RecoContainer* mRecoData = nullptr;
88 int mNThreads = 1;
89 bool mMeanVertexUpdated = false;
90 float mITSROFrameLengthMUS = 0.f;
91 o2::dataformats::MeanVertexObject mMeanVtx{};
92 std::vector<o2::BaseCluster<float>> mITSClustersArray;
93 const o2::itsmft::TopologyDictionary* mITSDict = nullptr;
95 std::shared_ptr<DataRequest> mDataRequest;
96 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
97 bool mUseMC{false};
98 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
99 GTrackID::mask_t mTracksSrc{};
100};
101
103{
105 int lane = ic.services().get<const o2::framework::DeviceSpec>().inputTimesliceId;
106 int maxLanes = ic.services().get<const o2::framework::DeviceSpec>().maxInputTimeslices;
107 std::string dbgnm = maxLanes == 1 ? "checkResid.root" : fmt::format("checkResid_t{}.root", lane);
108 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(dbgnm.c_str(), "recreate");
109 mNThreads = ic.options().get<int>("nthreads");
110#ifndef WITH_OPENMP
111 if (mNThreads > 1) {
112 LOGP(warn, "No OpenMP");
113 }
114 mNThreads = 1;
115#endif
116 // mTPCCorrMapsLoader.init(ic);
117}
118
120{
122 mRecoData = &recoData;
123 mRecoData->collectData(pc, *mDataRequest.get()); // select tracks of needed type, with minimal cuts, the real selected will be done in the vertexer
124 mRecoData = &recoData;
125 updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions
126 process();
127 mRecoData = nullptr;
128}
129
130void CheckResidSpec::updateTimeDependentParams(ProcessingContext& pc)
131{
134 // mTPCVDriftHelper.extractCCDBInputs(pc);
135 // mTPCCorrMapsLoader.extractCCDBInputs(pc);
136 static bool initOnceDone = false;
137 if (!initOnceDone) { // this params need to be queried only once
139 initOnceDone = true;
140 // Note: reading of the ITS AlpideParam needed for ITS timing is done by the RecoContainer
143 if (!grp->isDetContinuousReadOut(DetID::ITS)) {
144 mITSROFrameLengthMUS = alpParams.roFrameLengthTrig / 1.e3; // ITS ROFrame duration in \mus
145 } else {
146 mITSROFrameLengthMUS = alpParams.roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3; // ITS ROFrame duration in \mus
147 }
150 o2::conf::ConfigurableParam::updateFromString("pvertexer.useTimeInChi2=false;");
151 mVertexer.init();
152 }
153 if (mMeanVertexUpdated) {
154 mMeanVertexUpdated = false;
155 mVertexer.initMeanVertexConstraint();
156 }
157 bool updateMaps = false;
158 /*
159 if (mTPCCorrMapsLoader.isUpdated()) {
160 mTPCCorrMapsLoader.acknowledgeUpdate();
161 updateMaps = true;
162 }
163 if (mTPCVDriftHelper.isUpdated()) {
164 LOGP(info, "Updating TPC fast transform map with new VDrift factor of {} wrt reference {} and DriftTimeOffset correction {} wrt {} from source {}",
165 mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift,
166 mTPCVDriftHelper.getVDriftObject().timeOffsetCorr, mTPCVDriftHelper.getVDriftObject().refTimeOffset,
167 mTPCVDriftHelper.getSourceName());
168 mTPCVDriftHelper.acknowledgeUpdate();
169 updateMaps = true;
170 }
171 if (updateMaps) {
172 mTPCCorrMapsLoader.updateVDrift(mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift, mTPCVDriftHelper.getVDriftObject().getTimeOffset());
173 }
174 */
175}
176
178{
179 if (!mITSDict) {
180 LOGP(fatal, "ITS data is not loaded");
181 }
182 const auto itsTracks = mRecoData->getITSTracks();
183 // const auto itsLbls = mRecoData->getITSTracksMCLabels();
184 const auto itsClRefs = mRecoData->getITSTracksClusterRefs();
185 const auto clusITS = mRecoData->getITSClusters();
186 const auto patterns = mRecoData->getITSClustersPatterns();
188 auto pattIt = patterns.begin();
189 mITSClustersArray.clear();
190 mITSClustersArray.reserve(clusITS.size());
191
192 o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict);
193
194 auto pvvec = mRecoData->getPrimaryVertices();
195 auto trackIndex = mRecoData->getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
196 auto vtxRefs = mRecoData->getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
197 auto prop = o2::base::Propagator::Instance();
198 static int TFCount = 0;
199 int nv = vtxRefs.size() - 1;
200 std::vector<std::vector<checkresid::Track>> slots;
201 slots.resize(mNThreads);
202 int nvGood = 0, nvUse = 0, nvRefFail = 0;
203 long pvFitDuration{};
204 for (int iv = 0; iv < nv; iv++) {
205 const auto& vtref = vtxRefs[iv];
206 auto pve = pvvec[iv];
207 if (pve.getNContributors() < params.minPVContributors) {
208 continue;
209 }
210 nvGood++;
211 if (params.refitPV) {
212 LOGP(debug, "Refitting PV#{} of {} tracks", iv, pve.getNContributors());
213 auto tStartPVF = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
214 bool res = refitPV(pve, iv);
215 pvFitDuration += std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count() - tStartPVF;
216 if (!res) {
217 nvRefFail++;
218 continue;
219 }
220 }
221 nvUse++;
222 for (int is = 0; is < GTrackID::NSources; is++) {
223 if (!mTracksSrc[is] || !mRecoData->isTrackSourceLoaded(is)) {
224 continue;
225 }
226 int idMin = vtref.getFirstEntryOfSource(is), idMax = idMin + vtref.getEntriesOfSource(is);
227 DetID::mask_t dm = GTrackID::getSourceDetectorsMask(is);
228 if (!dm[DetID::ITS]) {
229 continue;
230 }
231 if (dm[DetID::TPC] && params.minTPCCl > 0 && !mRecoData->isTrackSourceLoaded(GTrackID::TPC)) {
232 LOGP(fatal, "Cut on TPC tracks is requested by they are not loaded");
233 }
234#ifdef WITH_OPENMP
235#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
236#endif
237 for (int i = idMin; i < idMax; i++) {
238 auto vid = trackIndex[i];
239 bool pvCont = vid.isPVContributor();
240 if (!pvCont && params.pvcontribOnly) {
241 continue;
242 }
243 if (dm[DetID::TPC] && params.minTPCCl > 0 && mRecoData->getTPCTrack(mRecoData->getTPCContributorGID(vid)).getNClusters() < params.minTPCCl) {
244 continue;
245 }
246 auto gidITS = mRecoData->getITSContributorGID(vid);
247 if (gidITS.getSource() != GTrackID::ITS) {
248 continue;
249 }
250 const auto& trc = mRecoData->getTrackParam(vid);
251 auto pt = trc.getPt();
252 if (pt < params.minPt || pt > params.maxPt) {
253 continue;
254 }
255 const auto& itsTrack = mRecoData->getITSTrack(gidITS);
256 if (itsTrack.getNClusters() < params.minITSCl) {
257 continue;
258 }
259#ifdef WITH_OPENMP
260 auto& accum = slots[omp_get_thread_num()];
261#else
262 auto& accum = slots[0];
263#endif
264 auto& resTrack = accum.emplace_back();
265 resTrack.gid = vid;
266 if (!processITSTrack(itsTrack, pve, resTrack)) {
267 accum.pop_back();
268 continue;
269 }
270 }
271 }
272 }
273 // output
274 for (const auto& accum : slots) {
275 for (const auto& tr : accum) {
276 (*mDBGOut) << "res" << "tr=" << tr << "\n";
277 }
278 }
279 LOGP(info, "processed {} PVs out of {} good vertices (out of {} in total), PV refits took {} mus, {} refits failed", nvUse, nvGood, nv, pvFitDuration, nvRefFail);
280 TFCount++;
281}
282
283bool CheckResidSpec::processITSTrack(const o2::its::TrackITS& iTrack, const o2::dataformats::PrimaryVertex& pv, o2::checkresid::Track& resTrack)
284{
285 const auto itsClRefs = mRecoData->getITSTracksClusterRefs();
286 auto trFitInw = iTrack.getParamOut(); // seed for inward refit
287 auto trFitOut = iTrack.getParamIn(); // seed for outward refit
288 auto prop = o2::base::Propagator::Instance();
290 float pvAlpha = 0;
291 float bz = prop->getNominalBz();
292 std::array<const o2::BaseCluster<float>*, 8> clArr{};
293 const auto& params = CheckResidConfig::Instance();
294 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw; // 2-way Kalman extrapolations, vertex + 7 layers
295
296 auto rotateTrack = [bz](o2::track::TrackParCov& tr, float alpha, o2::track::TrackPar* refLin) {
297 return refLin ? tr.rotate(alpha, *refLin, bz) : tr.rotate(alpha);
298 };
299
300 auto accountCluster = [&](int i, std::array<o2::track::TrackParCov, 8>& extrapDest, o2::track::TrackParCov& tr, o2::track::TrackPar* refLin) {
301 if (clArr[i]) { // update with cluster
302 if (!rotateTrack(tr, i == 0 ? pvAlpha : geom->getSensorRefAlpha(clArr[i]->getSensorID()), refLin) ||
303 !prop->propagateTo(tr, refLin, clArr[i]->getX(), true)) {
304 return 0;
305 }
306 extrapDest[i] = tr; // before update
307 if (!tr.update(*clArr[i])) {
308 return 0;
309 }
310 } else {
311 extrapDest[i].invalidate();
312 return -1;
313 }
314 return 1;
315 };
316
317 auto inv2d = [](float s00, float s11, float s01) -> std::array<float, 3> {
318 auto det = s00 * s11 - s01 * s01;
319 if (det < 1e-16) {
320 return {0.f, 0.f, 0.f};
321 }
322 det = 1.f / det;
323 return {s11 * det, s00 * det, -s01 * det};
324 };
325
326 resTrack.points.clear();
327 if (!prop->propagateToDCA(pv, trFitOut, bz)) {
328 LOGP(debug, "Failed to propagateToDCA, {}", trFitOut.asString());
329 return false;
330 }
331 float cosAlp, sinAlp;
332 pvAlpha = trFitOut.getAlpha();
333 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp); // vertex position rotated to track frame
335 if (params.addPVAsCluster) {
336 bcPV.setXYZ(pv.getX() * cosAlp + pv.getY() * sinAlp, -pv.getX() * sinAlp + pv.getY() * cosAlp, pv.getZ());
337 bcPV.setSigmaY2(0.5 * (pv.getSigmaX2() + pv.getSigmaY2()));
338 bcPV.setSigmaZ2(pv.getSigmaZ2());
339 bcPV.setSensorID(-1);
340 clArr[0] = &bcPV;
341 }
342 // collect all track clusters to array, placing them to layer+1 slot
343 int nCl = iTrack.getNClusters();
344 for (int i = 0; i < nCl; i++) { // clusters are ordered from the outermost to the innermost
345 const auto& curClu = mITSClustersArray[itsClRefs[iTrack.getClusterEntry(i)]];
346
347 int llr = geom->getLayer(curClu.getSensorID());
348 if (clArr[1 + llr]) {
349 LOGP(error, "Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->getSensorID(), curClu.getSensorID());
350 }
351 clArr[1 + geom->getLayer(curClu.getSensorID())] = &curClu;
352 }
353 o2::track::TrackPar refLinInw0, refLinOut0, *refLinOut = nullptr, *refLinInw = nullptr;
354 o2::track::TrackPar refLinIBOut0, refLinOBInw0, *refLinOBInw = nullptr, *refLinIBOut = nullptr;
355 if (params.useStableRef) {
356 refLinOut = &(refLinOut0 = trFitOut);
357 refLinInw = &(refLinInw0 = trFitInw);
358 }
359 trFitOut.resetCovariance();
360 trFitOut.setCov(trFitOut.getQ2Pt() * trFitOut.getQ2Pt() * trFitOut.getCov()[14], 14);
361 trFitInw.resetCovariance();
362 trFitInw.setCov(trFitInw.getQ2Pt() * trFitInw.getQ2Pt() * trFitInw.getCov()[14], 14);
363 // fit in inward and outward direction
364 for (int i = 0; i <= 7; i++) {
365 int resOut, resInw;
366 // process resOut in ascending order (0-->7) and resInw in descending order (7-->0)
367 if (!(resOut = accountCluster(i, extrapOut, trFitOut, refLinOut)) || !(resInw = accountCluster(7 - i, extrapInw, trFitInw, refLinInw))) {
368 return false;
369 }
370 // at layer 3, find the IB track (trIBOut) and the OB track (trOBInw)
371 // propagate both trcaks to a common radius, RCompIBOB (12cm), and rotates
372 // them to the same reference frame for comparison
373 if (i == 3 && resOut == 1 && resInw == 1 && params.doIBOB && nCl == 7) {
374 resTrack.trIBOut = trFitOut; // outward track updated at outermost IB layer
375 resTrack.trOBInw = trFitInw; // inward track updated at innermost OB layer
376 o2::track::TrackPar refLinIBOut0, refLinIBIn0;
377 if (refLinOut) {
378 refLinIBOut = &(refLinIBOut0 = refLinOut0);
379 refLinOBInw = &(refLinOBInw0 = refLinInw0);
380 }
381 float xRref;
382 if (!resTrack.trOBInw.getXatLabR(params.rCompIBOB, xRref, bz) ||
383 !prop->propagateTo(resTrack.trOBInw, refLinOBInw, xRref, true) ||
384 !rotateTrack(resTrack.trOBInw, resTrack.trOBInw.getPhiPos(), refLinOBInw) || // propagate OB track to ref R and rotate
385 !rotateTrack(resTrack.trIBOut, resTrack.trOBInw.getAlpha(), refLinIBOut) ||
386 !prop->propagateTo(resTrack.trIBOut, refLinIBOut, resTrack.trOBInw.getX(), true)) { // rotate OB track to same frame and propagate to same X
387 // if any propagation or rotation steps fail, invalidate both tracks
388 return false;
389 }
390 }
391 }
392
393 bool innerDone = false;
394 if (params.doResid) {
395 for (int i = 0; i <= 7; i++) {
396 if (clArr[i]) {
397 // calculate interpolation as a weighted mean of inward/outward extrapolations to this layer
398 const auto &tInw = extrapInw[i], &tOut = extrapOut[i];
399 auto wInw = inv2d(tInw.getSigmaY2(), tInw.getSigmaZ2(), tInw.getSigmaZY());
400 auto wOut = inv2d(tOut.getSigmaY2(), tOut.getSigmaZ2(), tOut.getSigmaZY());
401 if (wInw[0] == 0.f || wOut[0] == 0.f) {
402 return -1;
403 }
404 std::array<float, 3> wTot = {wInw[0] + wOut[0], wInw[1] + wOut[1], wInw[2] + wOut[2]};
405 auto cTot = inv2d(wTot[0], wTot[1], wTot[2]);
406 auto ywi = wInw[0] * tInw.getY() + wInw[2] * tInw.getZ() + wOut[0] * tOut.getY() + wOut[2] * tOut.getZ();
407 auto zwi = wInw[2] * tInw.getY() + wInw[1] * tInw.getZ() + wOut[2] * tOut.getY() + wOut[1] * tOut.getZ();
408 auto yw = ywi * cTot[0] + zwi * cTot[2];
409 auto zw = ywi * cTot[2] + zwi * cTot[1];
410 // posCl.push_back(clArr[i]->getXYZGlo(*o2::its::GeometryTGeo::Instance()));
411 auto phi = i == 0 ? tInw.getPhi() : tInw.getPhiPos();
412 o2::math_utils::bringTo02Pi(phi);
413 resTrack.points.emplace_back(clArr[i]->getY() - yw, clArr[i]->getZ() - zw, cTot[0] + clArr[i]->getSigmaY2(), cTot[1] + clArr[i]->getSigmaZ2(), phi, clArr[i]->getZ(), clArr[i]->getSensorID(), i - 1);
414 if (!innerDone) {
415 resTrack.track = tInw;
416 innerDone = true;
417 }
418 } else {
419 LOGP(debug, "No cluster on lr {}", i);
420 }
421 }
422 }
423 return true;
424}
425
426bool CheckResidSpec::refitPV(o2::dataformats::PrimaryVertex& pv, int vid)
427{
429 std::vector<o2::track::TrackParCov> tracks;
430 std::vector<bool> useTrack;
431 std::vector<GTrackID> gidsITS;
432 int ntr = pv.getNContributors(), ntrIni = ntr;
433 tracks.reserve(ntr);
434 useTrack.reserve(ntr);
435 gidsITS.reserve(ntr);
436 const auto& vtref = mRecoData->getPrimaryVertexMatchedTrackRefs()[vid];
437 auto trackIndex = mRecoData->getPrimaryVertexMatchedTracks();
438 int itr = vtref.getFirstEntry(), itLim = itr + vtref.getEntries();
439 for (; itr < itLim; itr++) {
440 auto vid = trackIndex[itr];
441 if (vid.isPVContributor()) {
442 tracks.emplace_back().setPID(mRecoData->getTrackParam(vid).getPID());
443 gidsITS.push_back(mRecoData->getITSContributorGID(vid));
444 }
445 }
446 ntr = tracks.size();
447 useTrack.resize(ntr);
448#ifdef WITH_OPENMP
449#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
450#endif
451 for (int itr = 0; itr < ntr; itr++) {
452 if (!(useTrack[itr] = refitITStrack(tracks[itr], gidsITS[itr]))) {
453 tracks[itr] = mRecoData->getTrackParam(gidsITS[itr]); // this track will not be used but participates in prepareVertexRefit
454 }
455 }
456 ntr = 0;
457 for (auto v : useTrack) {
458 ntr++;
459 }
460 if (ntr < params.minPVContributors || !mVertexer.prepareVertexRefit(tracks, pv)) {
461 LOGP(warn, "Abandon vertex refit: NcontribNew = {} vs NcontribOld = {}", ntr, ntrIni);
462 return false;
463 }
464 LOGP(debug, "Original vtx: Nc:{} {}, chi2={}", pv.getNContributors(), pv.asString(), pv.getChi2());
465 auto pvSave = pv;
466 pv = mVertexer.refitVertexFull(useTrack, pv);
467 LOGP(debug, "Refitted vtx: Nc:{} {}, chi2={}", ntr, pv.asString(), pv.getChi2());
468 if (pv.getChi2() < 0.f) {
469 LOGP(warn, "Failed to refit PV {}", pvSave.asString());
470 return false;
471 }
472 return true;
473}
474
475bool CheckResidSpec::refitITStrack(o2::track::TrackParCov& track, GTrackID gid)
476{
477 // destination tack might have non-default PID assigned
478 const auto& trkITS = mRecoData->getITSTrack(gid);
479 const auto itsClRefs = mRecoData->getITSTracksClusterRefs();
480 const auto& params = CheckResidConfig::Instance();
481 auto pid = track.getPID();
482 track = trkITS.getParamOut();
483 track.setPID(pid);
484 auto nCl = trkITS.getNumberOfClusters();
486 auto prop = o2::base::Propagator::Instance();
487 float bz = prop->getNominalBz();
488 o2::track::TrackPar refLin{track};
489
490 for (int iCl = 0; iCl < nCl; iCl++) { // clusters are stored from outer to inner layers
491 const auto& cls = mITSClustersArray[itsClRefs[trkITS.getClusterEntry(iCl)]];
492 auto alpha = geom->getSensorRefAlpha(cls.getSensorID());
493 if (!(params.useStableRef ? track.rotate(alpha, refLin, bz) : track.rotate(alpha)) ||
494 !prop->propagateTo(track, params.useStableRef ? &refLin : nullptr, cls.getX(), true)) {
495 LOGP(debug, "refitITStrack failed on propagation to cl#{}, alpha={}, x={} | {}", iCl, alpha, cls.getX(), track.asString());
496 return false;
497 }
498 if (!track.update(cls)) {
499 LOGP(debug, "refitITStrack failed on update with cl#{}, | {}", iCl, track.asString());
500 return false;
501 }
502 }
503 return true;
504}
505
507{
508 mDBGOut.reset();
509}
510
512{
514 return;
515 }
516 /*
517 if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) {
518 return;
519 }
520 if (mTPCCorrMapsLoader.accountCCDBInputs(matcher, obj)) {
521 return;
522 }
523 */
524 if (matcher == ConcreteDataMatcher("GLO", "MEANVERTEX", 0)) {
525 LOG(info) << "Imposing new MeanVertex: " << ((const o2::dataformats::MeanVertexObject*)obj)->asString();
526 mMeanVtx = *(const o2::dataformats::MeanVertexObject*)obj;
527 mMeanVertexUpdated = true;
528 return;
529 }
530 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
531 LOG(info) << "cluster dictionary updated";
532 mITSDict = (const o2::itsmft::TopologyDictionary*)obj;
533 return;
534 }
535}
536
537DataProcessorSpec getCheckResidSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool useMC /*, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts*/)
538{
539 std::vector<OutputSpec> outputs;
540 auto dataRequest = std::make_shared<DataRequest>();
541 dataRequest->requestTracks(srcTracks, useMC);
542 dataRequest->requestClusters(srcClusters, useMC);
543 dataRequest->requestPrimaryVertices(useMC);
544 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
545 true, // GRPECS=true
546 true, // GRPLHCIF
547 true, // GRPMagField
548 true, // askMatLUT
550 dataRequest->inputs,
551 true);
552 dataRequest->inputs.emplace_back("meanvtx", "GLO", "MEANVERTEX", 0, Lifetime::Condition, ccdbParamSpec("GLO/Calib/MeanVertex", {}, 1));
553 Options opts{
554 {"nthreads", VariantType::Int, 1, {"number of threads"}},
555 };
556 // o2::tpc::VDriftHelper::requestCCDBInputs(dataRequest->inputs);
557 // o2::tpc::CorrectionMapsLoader::requestCCDBInputs(dataRequest->inputs, opts, sclOpts);
558
559 return DataProcessorSpec{
560 "check-resid",
561 dataRequest->inputs,
562 outputs,
563 AlgorithmSpec{adaptFromTask<CheckResidSpec>(dataRequest, ggRequest, srcTracks, useMC /*, sclOpts*/)},
564 opts};
565}
566
567} // namespace o2::checkresid
Wrapper container for different reconstructed object types.
Base track model for the Barrel, params only, w/o covariance.
Definition of the GeometryManager class.
std::ostringstream debug
int32_t i
Helper for geometry and GRP related CCDB requests.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the GeometryTGeo class.
Utility functions for MC particles.
Definition of the Names Generator class.
Primary vertex finder.
uint16_t pid
Definition RawData.h:2
uint32_t res
Definition RawData.h:0
Wrapper container for different reconstructed object types.
o2::track::TrackParCov TrackParCov
Definition Recon.h:39
Result of refitting TPC-ITS matched track.
Reference on ITS/MFT clusters set.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
void setSigmaZ2(T v)
void setSigmaY2(T v)
void setSensorID(std::int16_t sid)
Definition BaseCluster.h:92
void setXYZ(T x, T y, T z)
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:178
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
CheckResidSpec(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, GTrackID::mask_t src, bool useMC)
void run(ProcessingContext &pc) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void init(InitContext &ic) final
static void updateFromString(std::string const &)
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
static constexpr ID ITS
Definition DetID.h:63
static constexpr ID TPC
Definition DetID.h:64
ServiceRegistryRef services()
Definition InitContext.h:34
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
static GeometryTGeo * Instance()
int getClusterEntry(int i) const
Definition TrackITS.h:67
PVertex refitVertexFull(const std::vector< bool > useTrack, const o2d::VertexBase &vtxSeed)
bool prepareVertexRefit(const TR &tracks, const o2d::VertexBase &vtxSeed)
Definition PVertexer.h:359
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLenum src
Definition glcorearb.h:1767
const GLdouble * v
Definition glcorearb.h:832
GLdouble f
Definition glcorearb.h:310
GLenum const GLfloat * params
Definition glcorearb.h:272
o2::framework::DataProcessorSpec getCheckResidSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool useMC)
create a processor spec
constexpr double LHCBunchSpacingNS
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
void convertCompactClusters(gsl::span< const itsmft::CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &pattIt, std::vector< o2::BaseCluster< float > > &output, const itsmft::TopologyDictionary *dict)
convert compact clusters to 3D spacepoints
Definition IOUtils.cxx:35
double * getX(double *xyDxy, int N)
double * getY(double *xyDxy, int N)
TrackParCovF TrackParCov
Definition Track.h:33
struct o2::upgrades_utils::@453 tracks
structure to keep trigger-related info
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
o2::track::TrackPar track
o2::track::TrackParCov trIBOut
o2::track::TrackParCov trOBInw
std::vector< Point > points
GTrackID getITSContributorGID(GTrackID source) const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
GTrackID getTPCContributorGID(GTrackID source) const
const o2::track::TrackParCov & getTrackParam(GTrackID gidx) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
static constexpr int L2G
Definition Cartesian.h:54
static constexpr int T2L
Definition Cartesian.h:55
static constexpr int T2G
Definition Cartesian.h:56
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"