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.meanVertexExtraErrSelection=0.2;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.setMeanVertex(&mMeanVtx);
156 mVertexer.initMeanVertexConstraint();
157 }
158 bool updateMaps = false;
159 /*
160 if (mTPCCorrMapsLoader.isUpdated()) {
161 mTPCCorrMapsLoader.acknowledgeUpdate();
162 updateMaps = true;
163 }
164 if (mTPCVDriftHelper.isUpdated()) {
165 LOGP(info, "Updating TPC fast transform map with new VDrift factor of {} wrt reference {} and DriftTimeOffset correction {} wrt {} from source {}",
166 mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift,
167 mTPCVDriftHelper.getVDriftObject().timeOffsetCorr, mTPCVDriftHelper.getVDriftObject().refTimeOffset,
168 mTPCVDriftHelper.getSourceName());
169 mTPCVDriftHelper.acknowledgeUpdate();
170 updateMaps = true;
171 }
172 if (updateMaps) {
173 mTPCCorrMapsLoader.updateVDrift(mTPCVDriftHelper.getVDriftObject().corrFact, mTPCVDriftHelper.getVDriftObject().refVDrift, mTPCVDriftHelper.getVDriftObject().getTimeOffset());
174 }
175 */
176}
177
179{
180 if (!mITSDict) {
181 LOGP(fatal, "ITS data is not loaded");
182 }
183 const auto itsTracks = mRecoData->getITSTracks();
184 // const auto itsLbls = mRecoData->getITSTracksMCLabels();
185 const auto itsClRefs = mRecoData->getITSTracksClusterRefs();
186 const auto clusITS = mRecoData->getITSClusters();
187 const auto patterns = mRecoData->getITSClustersPatterns();
189 auto pattIt = patterns.begin();
190 mITSClustersArray.clear();
191 mITSClustersArray.reserve(clusITS.size());
192
193 o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict);
194
195 auto pvvec = mRecoData->getPrimaryVertices();
196 auto trackIndex = mRecoData->getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
197 auto vtxRefs = mRecoData->getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
198 auto prop = o2::base::Propagator::Instance();
199 static int TFCount = 0;
200 int nv = vtxRefs.size() - 1;
201 std::vector<std::vector<checkresid::Track>> slots;
202 slots.resize(mNThreads);
203 int nvGood = 0, nvUse = 0, nvRefFail = 0;
204 long pvFitDuration{};
205 for (int iv = 0; iv < nv; iv++) {
206 const auto& vtref = vtxRefs[iv];
207 auto pve = pvvec[iv];
208 if (pve.getNContributors() < params.minPVContributors) {
209 continue;
210 }
211 nvGood++;
212 if (params.refitPV) {
213 LOGP(debug, "Refitting PV#{} of {} tracks", iv, pve.getNContributors());
214 auto tStartPVF = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
215 bool res = refitPV(pve, iv);
216 pvFitDuration += std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count() - tStartPVF;
217 if (!res) {
218 nvRefFail++;
219 continue;
220 }
221 }
222 nvUse++;
223 for (int is = 0; is < GTrackID::NSources; is++) {
224 if (!mTracksSrc[is] || !mRecoData->isTrackSourceLoaded(is)) {
225 continue;
226 }
227 int idMin = vtref.getFirstEntryOfSource(is), idMax = idMin + vtref.getEntriesOfSource(is);
228 DetID::mask_t dm = GTrackID::getSourceDetectorsMask(is);
229 if (!dm[DetID::ITS]) {
230 continue;
231 }
232 if (dm[DetID::TPC] && params.minTPCCl > 0 && !mRecoData->isTrackSourceLoaded(GTrackID::TPC)) {
233 LOGP(fatal, "Cut on TPC tracks is requested by they are not loaded");
234 }
235#ifdef WITH_OPENMP
236#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
237#endif
238 for (int i = idMin; i < idMax; i++) {
239 auto vid = trackIndex[i];
240 bool pvCont = vid.isPVContributor();
241 if (!pvCont && params.pvcontribOnly) {
242 continue;
243 }
244 if (dm[DetID::TPC] && params.minTPCCl > 0 && mRecoData->getTPCTrack(mRecoData->getTPCContributorGID(vid)).getNClusters() < params.minTPCCl) {
245 continue;
246 }
247 auto gidITS = mRecoData->getITSContributorGID(vid);
248 if (gidITS.getSource() != GTrackID::ITS) {
249 continue;
250 }
251 const auto& trc = mRecoData->getTrackParam(vid);
252 auto pt = trc.getPt();
253 if (pt < params.minPt || pt > params.maxPt) {
254 continue;
255 }
256 const auto& itsTrack = mRecoData->getITSTrack(gidITS);
257 if (itsTrack.getNClusters() < params.minITSCl) {
258 continue;
259 }
260#ifdef WITH_OPENMP
261 auto& accum = slots[omp_get_thread_num()];
262#else
263 auto& accum = slots[0];
264#endif
265 auto& resTrack = accum.emplace_back();
266 resTrack.gid = vid;
267 if (!processITSTrack(itsTrack, pve, resTrack)) {
268 accum.pop_back();
269 continue;
270 }
271 }
272 }
273 }
274 // output
275 for (const auto& accum : slots) {
276 for (const auto& tr : accum) {
277 (*mDBGOut) << "res" << "tr=" << tr << "\n";
278 }
279 }
280 LOGP(info, "processed {} PVs out of {} good vertices (out of {} in total), PV refits took {} mus, {} refits failed", nvUse, nvGood, nv, pvFitDuration, nvRefFail);
281 TFCount++;
282}
283
284bool CheckResidSpec::processITSTrack(const o2::its::TrackITS& iTrack, const o2::dataformats::PrimaryVertex& pv, o2::checkresid::Track& resTrack)
285{
286 const auto itsClRefs = mRecoData->getITSTracksClusterRefs();
287 auto trFitInw = iTrack.getParamOut(); // seed for inward refit
288 auto trFitOut = iTrack.getParamIn(); // seed for outward refit
289 auto prop = o2::base::Propagator::Instance();
291 float pvAlpha = 0;
292 float bz = prop->getNominalBz();
293 std::array<const o2::BaseCluster<float>*, 8> clArr{};
294 const auto& params = CheckResidConfig::Instance();
295 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw; // 2-way Kalman extrapolations, vertex + 7 layers
296
297 auto rotateTrack = [bz](o2::track::TrackParCov& tr, float alpha, o2::track::TrackPar* refLin) {
298 return refLin ? tr.rotate(alpha, *refLin, bz) : tr.rotate(alpha);
299 };
300
301 auto accountCluster = [&](int i, std::array<o2::track::TrackParCov, 8>& extrapDest, o2::track::TrackParCov& tr, o2::track::TrackPar* refLin) {
302 if (clArr[i]) { // update with cluster
303 if (!rotateTrack(tr, i == 0 ? pvAlpha : geom->getSensorRefAlpha(clArr[i]->getSensorID()), refLin) ||
304 !prop->propagateTo(tr, refLin, clArr[i]->getX(), true)) {
305 return 0;
306 }
307 extrapDest[i] = tr; // before update
308 if (!tr.update(*clArr[i])) {
309 return 0;
310 }
311 } else {
312 extrapDest[i].invalidate();
313 return -1;
314 }
315 return 1;
316 };
317
318 auto inv2d = [](float s00, float s11, float s01) -> std::array<float, 3> {
319 auto det = s00 * s11 - s01 * s01;
320 if (det < 1e-16) {
321 LOGP(error, "Singular det {}, input: {} {} {}", det, s00, s11, s01);
322 return {0.f, 0.f, 0.f};
323 }
324 det = 1.f / det;
325 return {s11 * det, s00 * det, -s01 * det};
326 };
327
328 resTrack.points.clear();
329 if (!prop->propagateToDCA(pv, trFitOut, bz)) {
330 LOGP(debug, "Failed to propagateToDCA, {}", trFitOut.asString());
331 return false;
332 }
334 if (params.addPVAsCluster) {
335 float cosAlp, sinAlp;
336 pvAlpha = trFitOut.getAlpha();
337 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp); // vertex position rotated to track frame
338 bcPV.setXYZ(pv.getX() * cosAlp + pv.getY() * sinAlp, -pv.getX() * sinAlp + pv.getY() * cosAlp, pv.getZ());
339 bcPV.setSigmaY2(0.5 * (pv.getSigmaX2() + pv.getSigmaY2()));
340 bcPV.setSigmaZ2(pv.getSigmaZ2());
341 bcPV.setSensorID(-1);
342 clArr[0] = &bcPV;
343 }
344 // collect all track clusters to array, placing them to layer+1 slot
345 int nCl = iTrack.getNClusters();
346 for (int i = 0; i < nCl; i++) { // clusters are ordered from the outermost to the innermost
347 const auto& curClu = mITSClustersArray[itsClRefs[iTrack.getClusterEntry(i)]];
348
349 int llr = geom->getLayer(curClu.getSensorID());
350 if (clArr[1 + llr]) {
351 LOGP(error, "Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->getSensorID(), curClu.getSensorID());
352 }
353 clArr[1 + geom->getLayer(curClu.getSensorID())] = &curClu;
354 }
355 o2::track::TrackPar refLinInw0, refLinOut0, *refLinOut = nullptr, *refLinInw = nullptr;
356 o2::track::TrackPar refLinIBOut0, refLinOBInw0, *refLinOBInw = nullptr, *refLinIBOut = nullptr;
357 if (params.useStableRef) {
358 refLinOut = &(refLinOut0 = trFitOut);
359 refLinInw = &(refLinInw0 = trFitInw);
360 }
361 trFitOut.resetCovariance();
362 trFitOut.setCov(trFitOut.getQ2Pt() * trFitOut.getQ2Pt() * trFitOut.getCov()[14], 14);
363 trFitInw.resetCovariance();
364 trFitInw.setCov(trFitInw.getQ2Pt() * trFitInw.getQ2Pt() * trFitInw.getCov()[14], 14);
365 // fit in inward and outward direction
366 for (int i = 0; i <= 7; i++) {
367 int resOut, resInw;
368 // process resOut in ascending order (0-->7) and resInw in descending order (7-->0)
369 if (!(resOut = accountCluster(i, extrapOut, trFitOut, refLinOut)) || !(resInw = accountCluster(7 - i, extrapInw, trFitInw, refLinInw))) {
370 return false;
371 }
372 // at layer 3, find the IB track (trIBOut) and the OB track (trOBInw)
373 // propagate both trcaks to a common radius, RCompIBOB (12cm), and rotates
374 // them to the same reference frame for comparison
375 if (i == 3 && resOut == 1 && resInw == 1 && params.doIBOB && nCl == 7) {
376 resTrack.trIBOut = trFitOut; // outward track updated at outermost IB layer
377 resTrack.trOBInw = trFitInw; // inward track updated at innermost OB layer
378 o2::track::TrackPar refLinIBOut0, refLinIBIn0;
379 if (refLinOut) {
380 refLinIBOut = &(refLinIBOut0 = refLinOut0);
381 refLinOBInw = &(refLinOBInw0 = refLinInw0);
382 }
383 float xRref;
384 if (!resTrack.trOBInw.getXatLabR(params.rCompIBOB, xRref, bz) ||
385 !prop->propagateTo(resTrack.trOBInw, refLinOBInw, xRref, true) ||
386 !rotateTrack(resTrack.trOBInw, resTrack.trOBInw.getPhiPos(), refLinOBInw) || // propagate OB track to ref R and rotate
387 !rotateTrack(resTrack.trIBOut, resTrack.trOBInw.getAlpha(), refLinIBOut) ||
388 !prop->propagateTo(resTrack.trIBOut, refLinIBOut, resTrack.trOBInw.getX(), true)) { // rotate OB track to same frame and propagate to same X
389 // if any propagation or rotation steps fail, invalidate both tracks
390 return false;
391 }
392 }
393 }
394
395 bool innerDone = false;
396 if (params.doResid) {
397 for (int i = 0; i <= 7; i++) {
398 if (clArr[i]) {
399 // calculate interpolation as a weighted mean of inward/outward extrapolations to this layer
400 const auto &tInw = extrapInw[i], &tOut = extrapOut[i];
401 auto wInw = inv2d(tInw.getSigmaY2(), tInw.getSigmaZ2(), tInw.getSigmaZY());
402 auto wOut = inv2d(tOut.getSigmaY2(), tOut.getSigmaZ2(), tOut.getSigmaZY());
403 if (wInw[0] == 0.f || wOut[0] == 0.f) {
404 return false;
405 }
406 std::array<float, 3> wTot = {wInw[0] + wOut[0], wInw[1] + wOut[1], wInw[2] + wOut[2]};
407 auto cTot = inv2d(wTot[0], wTot[1], wTot[2]);
408 auto ywi = wInw[0] * tInw.getY() + wInw[2] * tInw.getZ() + wOut[0] * tOut.getY() + wOut[2] * tOut.getZ();
409 auto zwi = wInw[2] * tInw.getY() + wInw[1] * tInw.getZ() + wOut[2] * tOut.getY() + wOut[1] * tOut.getZ();
410 auto yw = ywi * cTot[0] + zwi * cTot[2];
411 auto zw = ywi * cTot[2] + zwi * cTot[1];
412 // posCl.push_back(clArr[i]->getXYZGlo(*o2::its::GeometryTGeo::Instance()));
413 auto phi = i == 0 ? tInw.getPhi() : tInw.getPhiPos();
414 o2::math_utils::bringTo02Pi(phi);
415 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);
416 if (!innerDone) {
417 resTrack.track = tInw;
418 innerDone = true;
419 }
420 } else {
421 LOGP(debug, "No cluster on lr {}", i);
422 }
423 }
424 }
425 return true;
426}
427
428bool CheckResidSpec::refitPV(o2::dataformats::PrimaryVertex& pv, int vid)
429{
431 std::vector<o2::track::TrackParCov> tracks;
432 std::vector<bool> useTrack;
433 std::vector<GTrackID> gidsITS;
434 int ntr = pv.getNContributors(), ntrIni = ntr;
435 tracks.reserve(ntr);
436 useTrack.reserve(ntr);
437 gidsITS.reserve(ntr);
438 const auto& vtref = mRecoData->getPrimaryVertexMatchedTrackRefs()[vid];
439 auto trackIndex = mRecoData->getPrimaryVertexMatchedTracks();
440 int itr = vtref.getFirstEntry(), itLim = itr + vtref.getEntries();
441 for (; itr < itLim; itr++) {
442 auto vid = trackIndex[itr];
443 if (vid.isPVContributor()) {
444 tracks.emplace_back().setPID(mRecoData->getTrackParam(vid).getPID());
445 gidsITS.push_back(mRecoData->getITSContributorGID(vid));
446 }
447 }
448 ntr = tracks.size();
449 useTrack.resize(ntr);
450#ifdef WITH_OPENMP
451#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
452#endif
453 for (int itr = 0; itr < ntr; itr++) {
454 if (!(useTrack[itr] = refitITStrack(tracks[itr], gidsITS[itr]))) {
455 tracks[itr] = mRecoData->getTrackParam(gidsITS[itr]); // this track will not be used but participates in prepareVertexRefit
456 }
457 }
458 ntr = 0;
459 for (auto v : useTrack) {
460 ntr++;
461 }
462 if (ntr < params.minPVContributors || !mVertexer.prepareVertexRefit(tracks, pv)) {
463 LOGP(warn, "Abandon vertex refit: NcontribNew = {} vs NcontribOld = {}", ntr, ntrIni);
464 return false;
465 }
466 LOGP(debug, "Original vtx: Nc:{} {}, chi2={}", pv.getNContributors(), pv.asString(), pv.getChi2());
467 auto pvSave = pv;
468 pv = mVertexer.refitVertexFull(useTrack, pv);
469 LOGP(debug, "Refitted vtx: Nc:{} {}, chi2={}", ntr, pv.asString(), pv.getChi2());
470 if (pv.getChi2() < 0.f) {
471 LOGP(warn, "Failed to refit PV {}", pvSave.asString());
472 return false;
473 }
474 return true;
475}
476
477bool CheckResidSpec::refitITStrack(o2::track::TrackParCov& track, GTrackID gid)
478{
479 // destination tack might have non-default PID assigned
480 const auto& trkITS = mRecoData->getITSTrack(gid);
481 const auto itsClRefs = mRecoData->getITSTracksClusterRefs();
482 const auto& params = CheckResidConfig::Instance();
483 auto pid = track.getPID();
484 track = trkITS.getParamOut();
485 track.resetCovariance();
486 track.setCov(track.getQ2Pt() * track.getQ2Pt() * track.getCov()[14], 14);
487 track.setPID(pid);
488 auto nCl = trkITS.getNumberOfClusters();
490 auto prop = o2::base::Propagator::Instance();
491 float bz = prop->getNominalBz();
492 o2::track::TrackPar refLin{track};
493
494 for (int iCl = 0; iCl < nCl; iCl++) { // clusters are stored from outer to inner layers
495 const auto& cls = mITSClustersArray[itsClRefs[trkITS.getClusterEntry(iCl)]];
496 auto alpha = geom->getSensorRefAlpha(cls.getSensorID());
497 if (!(params.useStableRef ? track.rotate(alpha, refLin, bz) : track.rotate(alpha)) ||
498 !prop->propagateTo(track, params.useStableRef ? &refLin : nullptr, cls.getX(), true)) {
499 LOGP(debug, "refitITStrack failed on propagation to cl#{}, alpha={}, x={} | {}", iCl, alpha, cls.getX(), track.asString());
500 return false;
501 }
502 if (!track.update(cls)) {
503 LOGP(debug, "refitITStrack failed on update with cl#{}, | {}", iCl, track.asString());
504 return false;
505 }
506 }
507 return true;
508}
509
511{
512 mDBGOut.reset();
513}
514
516{
518 return;
519 }
520 /*
521 if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) {
522 return;
523 }
524 if (mTPCCorrMapsLoader.accountCCDBInputs(matcher, obj)) {
525 return;
526 }
527 */
528 if (matcher == ConcreteDataMatcher("GLO", "MEANVERTEX", 0)) {
529 LOG(info) << "Imposing new MeanVertex: " << ((const o2::dataformats::MeanVertexObject*)obj)->asString();
530 mMeanVtx = *(const o2::dataformats::MeanVertexObject*)obj;
531 mMeanVertexUpdated = true;
532 return;
533 }
534 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
535 LOG(info) << "cluster dictionary updated";
536 mITSDict = (const o2::itsmft::TopologyDictionary*)obj;
537 return;
538 }
539}
540
541DataProcessorSpec getCheckResidSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool useMC /*, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts*/)
542{
543 std::vector<OutputSpec> outputs;
544 auto dataRequest = std::make_shared<DataRequest>();
545 dataRequest->requestTracks(srcTracks, useMC);
546 dataRequest->requestClusters(srcClusters, useMC);
547 dataRequest->requestPrimaryVertices(useMC);
548 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
549 true, // GRPECS=true
550 true, // GRPLHCIF
551 true, // GRPMagField
552 true, // askMatLUT
554 dataRequest->inputs,
555 true);
556 dataRequest->inputs.emplace_back("meanvtx", "GLO", "MEANVERTEX", 0, Lifetime::Condition, ccdbParamSpec("GLO/Calib/MeanVertex", {}, 1));
557 Options opts{
558 {"nthreads", VariantType::Int, 1, {"number of threads"}},
559 };
560 // o2::tpc::VDriftHelper::requestCCDBInputs(dataRequest->inputs);
561 // o2::tpc::CorrectionMapsLoader::requestCCDBInputs(dataRequest->inputs, opts, sclOpts);
562
563 return DataProcessorSpec{
564 "check-resid",
565 dataRequest->inputs,
566 outputs,
567 AlgorithmSpec{adaptFromTask<CheckResidSpec>(dataRequest, ggRequest, srcTracks, useMC /*, sclOpts*/)},
568 opts};
569}
570
571} // 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
void setMeanVertex(const o2d::MeanVertexObject *v)
Definition PVertexer.h:96
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.
Definition Cartesian.h:288
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"