17#include <TStopwatch.h>
63 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(
src), mUseMC(useMC)
80 bool refitPV(
o2::dataformats::PrimaryVertex& pv,
int vid);
82 bool processITSTrack(const
o2::its::
TrackITS& iTrack, const
o2::dataformats::PrimaryVertex& pv,
o2::checkresid::
Track& resTrack);
84 o2::globaltracking::RecoContainer* mRecoData =
nullptr;
86 float mITSROFrameLengthMUS = 0.
f;
87 o2::dataformats::MeanVertexObject mMeanVtx{};
88 std::vector<o2::BaseCluster<float>> mITSClustersArray;
91 std::shared_ptr<DataRequest> mDataRequest;
92 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
94 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
103 std::string dbgnm = maxLanes == 1 ?
"checkResid.root" : fmt::format(
"checkResid_t{}.root", lane);
104 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(dbgnm.c_str(),
"recreate");
105 mNThreads = ic.
options().
get<
int>(
"nthreads");
108 LOGP(warn,
"No OpenMP");
118 mRecoData = &recoData;
120 mRecoData = &recoData;
121 updateTimeDependentParams(pc);
132 static bool initOnceDone =
false;
138 if (!grp->isDetContinuousReadOut(
DetID::ITS)) {
139 mITSROFrameLengthMUS = alpParams.roFrameLengthTrig / 1.e3;
148 bool updateMaps =
false;
171 LOGP(fatal,
"ITS data is not loaded");
179 auto pattIt = patterns.begin();
180 mITSClustersArray.clear();
181 mITSClustersArray.reserve(clusITS.size());
189 static int TFCount = 0;
190 int nv = vtxRefs.size() - 1;
191 std::vector<std::vector<checkresid::Track>> slots;
192 slots.resize(mNThreads);
193 int nvGood = 0, nvUse = 0, nvRefFail = 0;
194 long pvFitDuration{};
195 for (
int iv = 0; iv < nv; iv++) {
196 const auto& vtref = vtxRefs[iv];
197 auto pve = pvvec[iv];
198 if (pve.getNContributors() <
params.minPVContributors) {
203 auto tStartPVF = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
204 bool res = refitPV(pve, iv);
205 pvFitDuration += std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count() - tStartPVF;
216 int idMin = vtref.getFirstEntryOfSource(is), idMax = idMin + vtref.getEntriesOfSource(is);
222 LOGP(fatal,
"Cut on TPC tracks is requested by they are not loaded");
225#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
227 for (
int i = idMin;
i < idMax;
i++) {
228 auto vid = trackIndex[
i];
229 bool pvCont = vid.isPVContributor();
230 if (!pvCont &&
params.pvcontribOnly) {
241 auto pt = trc.getPt();
242 if (pt < params.minPt || pt >
params.maxPt) {
245 const auto& itsTrack = mRecoData->
getITSTrack(gidITS);
246 if (itsTrack.getNClusters() <
params.minITSCl) {
250 auto& accum = slots[omp_get_thread_num()];
252 auto& accum = slots[0];
254 auto& resTrack = accum.emplace_back();
255 if (!processITSTrack(itsTrack, pve, resTrack)) {
263 for (
const auto& accum : slots) {
264 for (
const auto& tr : accum) {
265 (*mDBGOut) <<
"res" <<
"tr=" << tr <<
"\n";
268 LOGP(info,
"processed {} PVs out of {} good vertices (out of {} in total), PV refits took {} mus, {} refits failed", nvUse, nvGood, nv, pvFitDuration, nvRefFail);
275 auto trFitInw = iTrack.getParamOut();
276 auto trFitOut = iTrack.getParamIn();
280 float bz = prop->getNominalBz();
281 std::array<const o2::BaseCluster<float>*, 8> clArr{};
283 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
286 return refLin ? tr.rotate(
alpha, *refLin, bz) : tr.rotate(
alpha);
291 if (!rotateTrack(tr,
i == 0 ? pvAlpha : geom->getSensorRefAlpha(clArr[
i]->getSensorID()), refLin) ||
292 !prop->propagateTo(tr, refLin, clArr[
i]->getX(), true)) {
296 if (!tr.update(*clArr[
i])) {
300 extrapDest[
i].invalidate();
306 auto inv2d = [](
float s00,
float s11,
float s01) -> std::array<float, 3> {
307 auto det = s00 * s11 - s01 * s01;
309 return {0.f, 0.f, 0.f};
312 return {s11 * det, s00 * det, -s01 * det};
316 if (!prop->propagateToDCA(pv, trFitOut, bz)) {
319 float cosAlp, sinAlp;
320 pvAlpha = trFitOut.getAlpha();
321 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
323 if (
params.addPVAsCluster) {
324 bcPV.
setXYZ(pv.getX() * cosAlp + pv.getY() * sinAlp, -pv.getX() * sinAlp + pv.getY() * cosAlp, pv.getZ());
325 bcPV.
setSigmaY2(0.5 * (pv.getSigmaX2() + pv.getSigmaY2()));
331 int nCl = iTrack.getNClusters();
332 for (
int i = 0;
i < nCl;
i++) {
333 const auto& curClu = mITSClustersArray[itsClRefs[iTrack.
getClusterEntry(
i)]];
335 int llr = geom->getLayer(curClu.getSensorID());
336 if (clArr[1 + llr]) {
337 LOGP(error,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), curClu.getSensorID());
339 clArr[1 + geom->getLayer(curClu.getSensorID())] = &curClu;
342 o2::track::TrackPar refLinIBOut0, refLinOBInw0, *refLinOBInw =
nullptr, *refLinIBOut =
nullptr;
343 if (
params.useStableRef) {
344 refLinOut = &(refLinOut0 = trFitOut);
345 refLinInw = &(refLinInw0 = trFitInw);
347 trFitOut.resetCovariance();
348 trFitOut.setCov(trFitOut.getQ2Pt() * trFitOut.getQ2Pt() * trFitOut.getCov()[14], 14);
349 trFitInw.resetCovariance();
350 trFitInw.setCov(trFitInw.getQ2Pt() * trFitInw.getQ2Pt() * trFitInw.getCov()[14], 14);
352 for (
int i = 0;
i <= 7;
i++) {
355 if (!(resOut = accountCluster(
i, extrapOut, trFitOut, refLinOut)) || !(resInw = accountCluster(7 -
i, extrapInw, trFitInw, refLinInw))) {
361 if (
i == 3 && resOut == 1 && resInw == 1 &&
params.doIBOB && nCl == 7) {
366 refLinIBOut = &(refLinIBOut0 = refLinOut0);
367 refLinOBInw = &(refLinOBInw0 = refLinInw0);
370 if (!resTrack.
trOBInw.getXatLabR(
params.rCompIBOB, xRref, bz) ||
371 !prop->propagateTo(resTrack.
trOBInw, refLinOBInw, xRref,
true) ||
372 !rotateTrack(resTrack.
trOBInw, resTrack.
trOBInw.getPhiPos(), refLinOBInw) ||
373 !rotateTrack(resTrack.
trIBOut, resTrack.
trOBInw.getAlpha(), refLinIBOut) ||
374 !prop->propagateTo(resTrack.
trIBOut, refLinIBOut, resTrack.
trOBInw.getX(),
true)) {
381 bool innerDone =
false;
383 for (
int i = 0;
i <= 7;
i++) {
386 const auto &tInw = extrapInw[
i], &tOut = extrapOut[
i];
387 auto wInw = inv2d(tInw.getSigmaY2(), tInw.getSigmaZ2(), tInw.getSigmaZY());
388 auto wOut = inv2d(tOut.getSigmaY2(), tOut.getSigmaZ2(), tOut.getSigmaZY());
389 if (wInw[0] == 0.f || wOut[0] == 0.f) {
392 std::array<float, 3> wTot = {wInw[0] + wOut[0], wInw[1] + wOut[1], wInw[2] + wOut[2]};
393 auto cTot = inv2d(wTot[0], wTot[1], wTot[2]);
394 auto ywi = wInw[0] * tInw.getY() + wInw[2] * tInw.getZ() + wOut[0] * tOut.getY() + wOut[2] * tOut.getZ();
395 auto zwi = wInw[2] * tInw.getY() + wInw[1] * tInw.getZ() + wOut[2] * tOut.getY() + wOut[1] * tOut.getZ();
396 auto yw = ywi * cTot[0] + zwi * cTot[2];
397 auto zw = ywi * cTot[2] + zwi * cTot[1];
399 auto phi =
i == 0 ? tInw.getPhi() : tInw.getPhiPos();
400 o2::math_utils::bringTo02Pi(phi);
401 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);
403 resTrack.
track = tInw;
407 LOGP(
debug,
"No cluster on lr {}",
i);
417 std::vector<o2::track::TrackParCov>
tracks;
418 std::vector<bool> useTrack;
419 std::vector<GTrackID> gidsITS;
420 int ntr = pv.getNContributors();
422 useTrack.reserve(ntr);
423 gidsITS.reserve(ntr);
426 int itr = vtref.getFirstEntry(), itLim = itr + vtref.getEntries();
427 for (; itr < itLim; itr++) {
428 auto vid = trackIndex[itr];
429 if (vid.isPVContributor()) {
435 useTrack.resize(ntr);
437#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
439 for (
int itr = 0; itr < ntr; itr++) {
440 if (!(useTrack[itr] = refitITStrack(tracks[itr], gidsITS[itr]))) {
445 for (
auto v : useTrack) {
454 for (
const auto& t : pool) {
458 pv.
setZ(zUpd / pool.size());
462 return pv.getChi2() > 0.f;
471 auto pid = track.getPID();
472 track = trkITS.getParamOut();
474 auto nCl = trkITS.getNumberOfClusters();
477 float bz = prop->getNominalBz();
480 for (
int iCl = 0; iCl < nCl; iCl++) {
481 const auto& cls = mITSClustersArray[itsClRefs[trkITS.getClusterEntry(iCl)]];
482 auto alpha = geom->getSensorRefAlpha(cls.getSensorID());
483 if (!(
params.useStableRef ? track.rotate(
alpha, refLin, bz) : track.rotate(
alpha)) ||
484 !prop->propagateTo(track,
params.useStableRef ? &refLin : nullptr, cls.
getX(), true)) {
485 LOGP(
debug,
"refitITStrack failed on propagation to cl#{}, alpha={}, x={} | {}", iCl,
alpha, cls.getX(), track.asString());
488 if (!track.update(cls)) {
489 LOGP(
debug,
"refitITStrack failed on update with cl#{}, | {}", iCl, track.asString());
520 LOG(info) <<
"cluster dictionary updated";
528 std::vector<OutputSpec> outputs;
529 auto dataRequest = std::make_shared<DataRequest>();
530 dataRequest->requestTracks(srcTracks, useMC);
531 dataRequest->requestClusters(srcClusters, useMC);
532 dataRequest->requestPrimaryVertices(useMC);
533 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
541 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
543 {
"nthreads", VariantType::Int, 1, {
"number of threads"}},
552 AlgorithmSpec{adaptFromTask<CheckResidSpec>(dataRequest, ggRequest, srcTracks, useMC )},
Definition of the GeometryManager class.
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.
Wrapper container for different reconstructed object types.
o2::track::TrackParCov TrackParCov
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 setSensorID(std::int16_t sid)
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)
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)
~CheckResidSpec() final=default
void run(ProcessingContext &pc) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void init(InitContext &ic) final
static const DPLAlpideParam< N > & Instance()
static void updateFromString(std::string const &)
Static class with identifiers, bitmasks and names for ALICE detectors.
T get(const char *key) const
ServiceRegistryRef services()
ConfigParamRegistry const & options()
InputRecord & inputs()
The inputs associated with this processing context.
static GeometryTGeo * Instance()
int getClusterEntry(int i) const
auto & getTracksPool() const
bool prepareVertexRefit(const TR &tracks, const o2d::VertexBase &vtxSeed)
PVertex refitVertex(const std::vector< bool > useTrack, const o2d::VertexBase &vtxSeed)
GLfloat GLfloat GLfloat alpha
GLenum const GLfloat * params
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
double * getX(double *xyDxy, int N)
double * getY(double *xyDxy, int N)
struct o2::upgrades_utils::@454 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
auto getITSTracks() const
GTrackID getITSContributorGID(GTrackID source) const
bool isTrackSourceLoaded(int src) const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
auto getITSTracksClusterRefs() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
auto getPrimaryVertexMatchedTrackRefs() const
auto getITSClustersPatterns() 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
auto getITSClusters() const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"