156 std::vector<o2::InteractionTimeRecord> intRecs;
160 throw std::invalid_argument(
"initialization of MCKinematicsReader failed");
166 if (mTPCTracksArray.size()) {
167 LOGP(info,
"Found {} TPC tracks", mTPCTracksArray.size());
168 mTPCRefitter = std::make_unique<o2::gpu::GPUO2InterfaceRefit>(mTPCClusterIdxStruct, mTPCCorrMaps, prop->getNominalBz(), mTPCTrackClusIdx.data(), 0, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size(),
nullptr,
o2::base::Propagator::Instance());
172 std::vector<short> clSector, clRow;
173 std::vector<float> clX, clY, clZ;
175 auto dumpClusters = [
this] {
177 const auto* corrMap = this->mTPCCorrMaps;
178 for (
int sector = 0; sector < 36; sector++) {
179 float alp = ((sector % 18) * 20 + 10) * TMath::DegToRad();
180 float sn = TMath::Sin(alp), cs = TMath::Cos(alp);
182 for (
int ic = 0; ic < this->mTPCClusterIdxStruct->
nClusters[sector][
row]; ic++) {
183 const auto cl = this->mTPCClusterIdxStruct->
clusters[sector][
row][ic];
184 float x,
y,
z, xG, yG;
185 corrMap->TransformIdeal(sector,
row, cl.getPad(), cl.getTime(),
x,
y,
z, 0);
187 LOGP(
debug,
"tf:{} s:{} r:{} p:{} t:{} qm:{} qt:{} f:{} x:{} y:{} z:{}",
tf, sector,
row, cl.getPad(), cl.getTime(), cl.getQmax(), cl.getQtot(), cl.getFlags(),
x,
y,
z);
188 (*mDBGOutCl) <<
"tpccl"
189 <<
"tf=" <<
tf <<
"sect=" << sector <<
"row=" <<
row <<
"pad=" << cl.getPad() <<
"time=" << cl.getTime() <<
"qmax=" << cl.getQmax() <<
"qtot=" << cl.getQtot()
190 <<
"sigT=" << cl.getSigmaTime() <<
"sigP=" << cl.getSigmaPad()
191 <<
"flags=" << cl.getFlags()
192 <<
"x=" <<
x <<
"y=" <<
y <<
"z=" <<
z <<
"xg=" << xG <<
"yg=" << yG
204 for (
size_t itr = 0; itr < mTPCTracksArray.size(); itr++) {
205 auto tr = mTPCTracksArray[itr];
207 if (tr.hasBothSidesClusters()) {
210 side = tr.hasASideClustersOnly() ? 1 : -1;
215 int retVal = mUseGPUModel ? this->mTPCRefitter->RefitTrackAsGPU(trc, this->mTPCTracksArray[itr].getClusterRef(), t, &chi2Out,
false,
true) : this->mTPCRefitter->RefitTrackAsTrackParCov(trc, this->mTPCTracksArray[itr].getClusterRef(), t, &chi2Out,
false,
true);
217 LOGP(warn,
"Refit failed ({}) with time={}: track#{}[{}]",
retVal, t,
counter, trc.asString());
224 if (!trc.rotate(tr.getAlpha())) {
225 LOGP(warn,
"Rotation to original track alpha {} failed, track#{}[{}]", tr.getAlpha(),
counter, trc.asString());
228 float xtgt = this->mXRef;
233 if (!prop->PropagateToXBxByBz(trc, xtgt)) {
234 LOGP(warn,
"Propagation to X={} failed, track#{}[{}]", xtgt,
counter, trc.asString());
240 auto prepClus = [
this, &tr, &clSector, &clRow, &clX, &clY, &clZ](
float t) {
246 int count = tr.getNClusters();
248 for (
int ic =
count; ic--;) {
250 cl = &tr.getCluster(this->mTPCTrackClusIdx, ic, *this->mTPCClusterIdxStruct, sector,
row);
251 clSector.push_back(sector);
252 clRow.push_back(
row);
254 mTPCCorrMaps->Transform(sector,
row, cl->getPad(), cl->getTime(),
x,
y,
z, t);
263 auto trf = tr.getOuterParam();
264 if (!trackRefit(trf, tr.getTime0()) || !trackProp(trf)) {
269 if (!trackProp(tr)) {
273 prepClus(tr.getTime0());
276 (*mDBGOut) <<
"tpcIni"
279 <<
"iniTrackRef=" << trf
281 <<
"time=" << tr.getTime0()
282 <<
"clSector=" << clSector
294 auto lbl = mTPCTrkLabels[itr];
295 if (!lbl.isValid() || !(mcTrack = mcReader.
getTrack(lbl))) {
298 long bc = intRecs[lbl.getEventID()].toLong();
299 float bcTB =
bc / 8. + tpcTBBias;
303 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrack->
GetPdgCode());
310 if (!mctrO2.rotate(tr.getAlpha()) || !prop->PropagateToXBxByBz(mctrO2, tr.getX())) {
315 auto trfm = tr.getOuterParam();
317 if (!trackRefit(trfm, bcTB) || !trfm.rotate(tr.getAlpha()) || !prop->PropagateToXBxByBz(trfm, tr.getX())) {
318 LOGP(warn,
"Failed to propagate MC-time refitted track#{} [{}] to X/alpha of original track [{}]",
counter, trfm.asString(), tr.asString());
322 dz = (tr.getTime0() - bcTB) * vdriftTB;
323 if (tr.hasCSideClustersOnly()) {
328 (*mDBGOut) <<
"tpcMC"
330 <<
"movTrackRef=" << trfm
331 <<
"mcTrack=" << mctrO2
333 <<
"imposedTB=" << bcTB
343 float tmin = tr.getTime0() - tr.getDeltaTBwd();
344 float tmax = tr.getTime0() + tr.getDeltaTFwd();
345 for (
int it = 0; it < mNMoves; it++) {
346 float tb = tmin + it * (tmax - tmin) / (mNMoves - 1);
347 auto trfm = tr.getOuterParam();
349 if (!trackRefit(trfm, tb) || !trfm.rotate(tr.getAlpha()) || !prop->PropagateToXBxByBz(trfm, tr.getX())) {
350 LOGP(warn,
"Failed to propagate time={} refitted track#{} [{}] to X/alpha of original track [{}]", tb,
counter, trfm.asString(), tr.asString());
354 dz = (tr.getTime0() - tb) * vdriftTB;
355 if (tr.hasCSideClustersOnly()) {
359 int mnm = mNMoves - 1;
361 (*mDBGOut) <<
"tpcMov"
365 <<
"movTrackRef=" << trfm;
367 (*mDBGOut) <<
"tpcMov"
368 <<
"iniTrackRef=" << trf <<
"time=" << tr.getTime0();
370 (*mDBGOut) <<
"tpcMov"
372 <<
"imposedTB=" << tb
400 std::vector<OutputSpec> outputs;
402 {
"target-x", VariantType::Float, 70.f, {
"Try to propagate to this radius"}},
403 {
"n-moves", VariantType::Int, 6, {
"Number of moves in allow range"}},
404 {
"dump-clusters", VariantType::Bool,
false, {
"dump clusters"}},
405 {
"tf-start", VariantType::Int, 0, {
"1st TF to process"}},
406 {
"tf-end", VariantType::Int, 999999999, {
"last TF to process"}},
407 {
"use-gpu-fitter", VariantType::Bool,
false, {
"use GPU track model for refit instead of TrackParCov"}},
408 {
"repeat-ini-ref", VariantType::Bool,
false, {
"store ini-refit param with every moved track"}},
409 {
"use-r-as-x", VariantType::Bool,
false, {
"Use radius instead of target sector X"}}};
410 auto dataRequest = std::make_shared<DataRequest>();
412 dataRequest->requestTracks(srcTracks, useMC);
413 dataRequest->requestClusters(srcClusters, useMC);
414 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
429 AlgorithmSpec{adaptFromTask<TPCTrackStudySpec>(dataRequest, ggRequest, srcTracks, useMC)},
ServiceRegistryRef services()
The services registry associated with this processing context.