Skip to content

Commit a23c62a

Browse files
committed
Add residuals for external detectors
1 parent 7262c36 commit a23c62a

File tree

2 files changed

+160
-46
lines changed

2 files changed

+160
-46
lines changed

Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,14 @@ struct TrackData {
121121
float chi2TPC{}; ///< chi2 of TPC track
122122
float chi2ITS{}; ///< chi2 of ITS track
123123
float chi2TRD{}; ///< chi2 of TRD track
124+
124125
unsigned short nClsTPC{}; ///< number of attached TPC clusters
125126
unsigned short nClsITS{}; ///< number of attached ITS clusters
126127
unsigned short nTrkltsTRD{}; ///< number of attached TRD tracklets
127128
unsigned short clAvailTOF{}; ///< whether or not track seed has a matched TOF cluster
128-
o2::dataformats::RangeReference<> clIdx{}; ///< index of first cluster residual and total number of cluster residuals of this track
129-
ClassDefNV(TrackData, 6);
129+
uint8_t nExtDetResid = 0; ///< number of external detectors (to TPC) residuals stored, on top of clIdx.getEntries
130+
o2::dataformats::RangeReference<> clIdx{}; ///< index of first cluster residual and total number of TPC cluster residuals of this track
131+
ClassDefNV(TrackData, 7);
130132
};
131133

132134
/// \class TrackInterpolation
@@ -265,6 +267,8 @@ class TrackInterpolation
265267
/// Set the centre of mass energy required for pT downsampling Tsalis function
266268
void setSqrtS(float s) { mSqrtS = s; }
267269

270+
int processTRDLayer(const o2::trd::TrackTRD& trkTRD, int iLayer, o2::track::TracParCov& trkWork, std::array<float, 2>* trkltTRDYZ = nullptr, std::array<float, 3>* trkltTRDCov = nullptr);
271+
268272
// --------------------------------- output ---------------------------------------------
269273
std::vector<UnbinnedResid>& getClusterResiduals() { return mClRes; }
270274
std::vector<TrackDataCompact>& getTrackDataCompact() { return mTrackDataCompact; }
@@ -297,6 +301,7 @@ class TrackInterpolation
297301
std::vector<o2::globaltracking::RecoContainer::GlobalIDSet> mGIDtables{}; ///< GIDs of contributors from single detectors for each seed
298302
std::vector<float> mTrackTimes{}; ///< time estimates for all input tracks in micro seconds
299303
std::vector<o2::track::TrackParCov> mSeeds{}; ///< seeding track parameters (ITS tracks)
304+
std::vector<int> mParentID{}; ///< entry of more global parent track for skimmed seeds (-1: no parent)
300305
std::map<int, int> mTrackTypes; ///< mapping of track source to array index in mTrackIndices
301306
std::array<std::vector<uint32_t>, 4> mTrackIndices; ///< keep GIDs of input tracks separately for each track type
302307
gsl::span<const TPCClRefElem> mTPCTracksClusIdx; ///< input TPC cluster indices from span

Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx

Lines changed: 153 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "SpacePoints/TrackInterpolation.h"
1919
#include "SpacePoints/TrackResiduals.h"
2020
#include "ITStracking/IOUtils.h"
21+
#include "ITSBase/GeometryTGeo.h"
2122
#include "TPCBase/ParameterElectronics.h"
2223
#include "DataFormatsTPC/TrackTPC.h"
2324
#include "DataFormatsTPC/Defs.h"
@@ -65,6 +66,9 @@ void TrackInterpolation::init(o2::dataformats::GlobalTrackID::mask_t src, o2::da
6566
mTrackTypes.insert({GTrackID::ITSTPCTOF, 2});
6667
mTrackTypes.insert({GTrackID::ITSTPCTRDTOF, 3});
6768

69+
o2::its::GeometryTGeo* geom = GeometryTGeo::Instance();
70+
geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G));
71+
6872
mInitDone = true;
6973
LOGP(info, "Done initializing TrackInterpolation. Configured track input: {}. Track input specifically for map: {}",
7074
GTrackID::getSourcesNames(mSourcesConfigured), mSingleSourcesConfigured ? "identical" : GTrackID::getSourcesNames(mSourcesConfiguredMap));
@@ -273,6 +277,9 @@ void TrackInterpolation::process()
273277
trackIndices.insert(trackIndices.end(), mTrackIndices[mTrackTypes[GTrackID::ITSTPC]].begin(), mTrackIndices[mTrackTypes[GTrackID::ITSTPC]].end());
274278

275279
int nSeeds = mSeeds.size(), lastChecked = 0;
280+
mParentID.clear();
281+
mParentID.resize(nSeeds, -1);
282+
276283
int maxOutputTracks = (mMaxTracksPerTF >= 0) ? mMaxTracksPerTF + mAddTracksForMapPerTF : nSeeds;
277284
mTrackData.reserve(maxOutputTracks);
278285
mClRes.reserve(maxOutputTracks * param::NPadRows);
@@ -292,6 +299,7 @@ void TrackInterpolation::process()
292299
this->mGIDtables.push_back(this->mRecoCont->getSingleDetectorRefs(this->mGIDs.back()));
293300
this->mTrackTimes.push_back(this->mTrackTimes[seedIndex]);
294301
this->mSeeds.push_back(this->mSeeds[seedIndex]);
302+
this->mParentID.push_back(seedIndex); // store parent seed id
295303
};
296304

297305
GTrackID::mask_t partsAdded;
@@ -457,41 +465,15 @@ void TrackInterpolation::interpolateTrack(int iSeed)
457465
(*trackDataExtended).trkTRD = trkTRD;
458466
}
459467
for (int iLayer = o2::trd::constants::NLAYER - 1; iLayer >= 0; --iLayer) {
460-
int trkltIdx = trkTRD.getTrackletIndex(iLayer);
461-
if (trkltIdx < 0) {
462-
// no TRD tracklet in this layer
468+
std::array<float, 2> trkltTRDYZ{};
469+
std::array<float, 3> trkltTRDCov{};
470+
int res = processTRDLayer(trkTRD, iLayer, trkWork, &trkltTRDYZ, &trkltTRDCov);
471+
if (res == 0) { // no TRD tracklet in this layer
463472
continue;
464473
}
465-
const auto& trdSP = mRecoCont->getTRDCalibratedTracklets()[trkltIdx];
466-
const auto& trdTrklt = mRecoCont->getTRDTracklets()[trkltIdx];
467-
if (mDumpTrackPoints) {
468-
(*trackDataExtended).trkltTRD.push_back(trdTrklt);
469-
(*trackDataExtended).clsTRD.push_back(trdSP);
470-
}
471-
auto trkltDet = trdTrklt.getDetector();
472-
auto trkltSec = trkltDet / (o2::trd::constants::NLAYER * o2::trd::constants::NSTACK);
473-
if (trkltSec != o2::math_utils::angle2Sector(trkWork.getAlpha())) {
474-
if (!trkWork.rotate(o2::math_utils::sector2Angle(trkltSec))) {
475-
LOG(debug) << "Track could not be rotated in TRD tracklet coordinate system in layer " << iLayer;
476-
return;
477-
}
478-
}
479-
if (!propagator->PropagateToXBxByBz(trkWork, trdSP.getX(), mParams->maxSnp, mParams->maxStep, mMatCorr)) {
480-
LOG(debug) << "Failed propagation to TRD layer " << iLayer;
474+
if (res < 0) { // failed to reach this layer
481475
return;
482476
}
483-
484-
const auto* pad = mGeoTRD->getPadPlane(trkltDet);
485-
float tilt = tan(TMath::DegToRad() * pad->getTiltingAngle()); // tilt is signed! and returned in degrees
486-
float tiltCorrUp = tilt * (trdSP.getZ() - trkWork.getZ());
487-
float zPosCorrUp = trdSP.getZ() + mRecoParam.getZCorrCoeffNRC() * trkWork.getTgl(); // maybe Z can be corrected on avarage already by the tracklet transformer?
488-
float padLength = pad->getRowSize(trdTrklt.getPadRow());
489-
if (!((trkWork.getSigmaZ2() < (padLength * padLength / 12.f)) && (std::fabs(trdSP.getZ() - trkWork.getZ()) < padLength))) {
490-
tiltCorrUp = 0.f;
491-
}
492-
std::array<float, 2> trkltTRDYZ{trdSP.getY() - tiltCorrUp, zPosCorrUp};
493-
std::array<float, 3> trkltTRDCov;
494-
mRecoParam.recalcTrkltCov(tilt, trkWork.getSnp(), pad->getRowSize(trdTrklt.getPadRow()), trkltTRDCov);
495477
if (!trkWork.update(trkltTRDYZ, trkltTRDCov)) {
496478
LOG(debug) << "Failed to update track at TRD layer " << iLayer;
497479
return;
@@ -611,6 +593,46 @@ void TrackInterpolation::interpolateTrack(int iSeed)
611593
}
612594
}
613595

596+
int TrackInterpolation::processTRDLayer(const o2::trd::TrackTRD& trkTRD, int iLayer, o2::track::TracParCov& trkWork,
597+
std::array<float, 2>* trkltTRDYZ, std::array<float, 3>* trkltTRDCov)
598+
{
599+
// return 1 in case of successful processing, 0 if there is no TRD tracklet at given layer, -1 if processing failed
600+
int trkltIdx = trkTRD.getTrackletIndex(iLayer);
601+
if (trkltIdx < 0) {
602+
return 0; // no TRD tracklet in this layer
603+
}
604+
const auto& trdSP = mRecoCont->getTRDCalibratedTracklets()[trkltIdx];
605+
const auto& trdTrklt = mRecoCont->getTRDTracklets()[trkltIdx];
606+
auto trkltDet = trdTrklt.getDetector();
607+
auto trkltSec = trkltDet / (o2::trd::constants::NLAYER * o2::trd::constants::NSTACK);
608+
if (trkltSec != o2::math_utils::angle2Sector(trkWork.getAlpha())) {
609+
if (!trkWork.rotate(o2::math_utils::sector2Angle(trkltSec))) {
610+
LOG(debug) << "Track could not be rotated in TRD tracklet coordinate system in layer " << iLayer;
611+
return -1;
612+
}
613+
}
614+
if (!propagator->PropagateToXBxByBz(trkWork, trdSP.getX(), mParams->maxSnp, mParams->maxStep, mMatCorr)) {
615+
LOG(debug) << "Failed propagation to TRD layer " << iLayer;
616+
return -1;
617+
}
618+
if (trkltTRDYZ) {
619+
const auto* pad = mGeoTRD->getPadPlane(trkltDet);
620+
float tilt = tan(TMath::DegToRad() * pad->getTiltingAngle()); // tilt is signed! and returned in degrees
621+
float tiltCorrUp = tilt * (trdSP.getZ() - trkWork.getZ());
622+
float zPosCorrUp = trdSP.getZ() + mRecoParam.getZCorrCoeffNRC() * trkWork.getTgl(); // maybe Z can be corrected on avarage already by the tracklet transformer?
623+
float padLength = pad->getRowSize(trdTrklt.getPadRow());
624+
if (!((trkWork.getSigmaZ2() < (padLength * padLength / 12.f)) && (std::fabs(trdSP.getZ() - trkWork.getZ()) < padLength))) {
625+
tiltCorrUp = 0.f;
626+
}
627+
(*trkltTRDYZ)[0] = trdSP.getY() - tiltCorrUp;
628+
(*trkltTRDYZ)[1] = zPosCorrUp;
629+
if (trkltTRDCov) {
630+
mRecoParam.recalcTrkltCov(tilt, trkWork.getSnp(), pad->getRowSize(trdTrklt.getPadRow()), *trkltTRDCov);
631+
}
632+
}
633+
return 1;
634+
}
635+
614636
void TrackInterpolation::extrapolateTrack(int iSeed)
615637
{
616638
// extrapolate ITS-only track through TPC and store residuals to TPC clusters in the output vectors
@@ -638,7 +660,7 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
638660
trackData.gid = mGIDs[iSeed];
639661
trackData.par = mSeeds[iSeed];
640662

641-
auto& trkWork = mSeeds[iSeed];
663+
auto trkWork = mSeeds[iSeed];
642664
float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
643665
auto propagator = o2::base::Propagator::Instance();
644666
unsigned short rowPrev = 0; // used to calculate dRow of two consecutive cluster residuals
@@ -681,6 +703,13 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
681703
rowPrev = row;
682704
++nMeasurements;
683705
}
706+
707+
TrackParams params; // for refitted track parameters and flagging rejected clusters
708+
if (clusterResiduals.size() > constants::MAXGLOBALPADROW) {
709+
LOGP(warn, "Extrapolated ITS-TPC track and found more reesiduals than possible ({})", clusterResiduals.size());
710+
return;
711+
}
712+
684713
trackData.chi2TPC = trkTPC.getChi2();
685714
trackData.chi2ITS = trkITS.getChi2();
686715
trackData.nClsTPC = trkTPC.getNClusterReferences();
@@ -691,19 +720,14 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
691720
(*trackDataExtended).trkOuter = trkWork;
692721
}
693722

694-
TrackParams params; // for refitted track parameters and flagging rejected clusters
695-
if (clusterResiduals.size() > constants::MAXGLOBALPADROW) {
696-
LOGP(warn, "Extrapolated ITS-TPC track and found more reesiduals than possible ({})", clusterResiduals.size());
697-
return;
698-
}
699723
if (mParams->skipOutlierFiltering || validateTrack(trackData, params, clusterResiduals)) {
700-
// track is good
701-
int nClValidated = 0;
702-
int iRow = 0;
703-
for (unsigned int iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
724+
// track is good, store TPC part
725+
726+
int nClValidated = 0, iRow = 0;
727+
unsigned int iCl = 0;
728+
for (iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
704729
iRow += clusterResiduals[iCl].dRow;
705-
if (params.flagRej[iCl]) {
706-
// skip masked cluster residual
730+
if (iRow < param::NPadRows && params.flagRej[iCl]) { // skip masked cluster residual
707731
continue;
708732
}
709733
++nClValidated;
@@ -720,9 +744,94 @@ void TrackInterpolation::extrapolateTrack(int iSeed)
720744
}
721745
}
722746
trackData.clIdx.setEntries(nClValidated);
747+
748+
// do we have TRD residuals to add?
749+
int iSeedFull = mParentID[iSeed] == -1 ? iSeed : mParentID[iSeed];
750+
auto gidFull = mGIDs[iSeedFull];
751+
const auto& gidTableFull = mGIDtables[iSeedFull];
752+
bool stopPropagation = false;
753+
if (gidTableFull[GTrackID::TRD].isIndexSet()) {
754+
const auto& trkTRD = mRecoCont->getITSTPCTRDTrack<o2::trd::TrackTRD>(gidTableFull[GTrackID::ITSTPCTRD]);
755+
for (int iLayer = 0; iLayer < o2::trd::constants::NLAYER; iLayer++) {
756+
std::array<float, 2> trkltTRDYZ{};
757+
int res = processTRDLayer(trkTRD, iLayer, trkWork, &trkltTRDYZ);
758+
if (res == 0) { // no traklet on this layer
759+
continue;
760+
}
761+
if (res < 0) { // failed to reach this layer
762+
stopPropagation = true;
763+
break;
764+
}
765+
766+
float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
767+
auto dy = trkltTRDYZ[0] - trkWork.getY();
768+
auto dz = trkltTRDYZ[1] - trkWork.getZ();
769+
const auto sec = clusterResiduals[iCl].sec;
770+
if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWork.getY()) < param::MaxY) && (std::abs(trkWork.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
771+
mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 160 + iLayer, o2::math_utils::angle2Sector(trkWork.getAlpha()));
772+
trackData.nTrkltsTRD++;
773+
trackData.nExtDetResid++;
774+
// NEED TO STORE: TRD X
775+
}
776+
}
777+
}
778+
779+
// do we have TOF residual to add?
780+
while (gidTableFull[GTrackID::TOF].isIndexSet() && !stopPropagation) {
781+
const auto& clTOF = mRecoCont->getTOFClusters()[gidTableFull[GTrackID::TOF]];
782+
const float clTOFAlpha = o2::math_utils::sector2Angle(clTOF.getCount());
783+
if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
784+
LOG(debug) << "Failed to rotate into TOF cluster sector frame";
785+
stopPropagation = true;
786+
break;
787+
}
788+
if (!propagator->PropagateToXBxByBz(trkWork, clTOF.getX(), mParams->maxSnp, mParams->maxStep, mMatCorr)) {
789+
LOG(debug) << "Failed final propagation to TOF radius";
790+
break;
791+
}
792+
793+
float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
794+
auto dy = clTOF.getY() - trkWork.getY();
795+
auto dz = clTOF.getZ() - trkWork.getZ();
796+
if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWork.getY()) < param::MaxY) && (std::abs(trkWork.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
797+
mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount());
798+
trackData.clAvailTOF = 1;
799+
trackData.nExtDetResid++;
800+
// NEED TO STORE: TOF X
801+
}
802+
break;
803+
}
804+
805+
// add ITS residuals
806+
while (!stopPropagation) {
807+
auto trkWorkITS = trackData.par; // this is ITS outer param
808+
auto nClITS = trkITS.getNumberOfClusters();
809+
auto clEntryITS = trkITS.getFirstClusterEntry();
810+
o2::its::GeometryTGeo* geom = GeometryTGeo::Instance();
811+
for (int iCl = 0; iCl < nCl; iCl++) { // clusters are stored from outer to inner layers
812+
const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
813+
int chip = clsITS.getSensorID();
814+
float chipX, chipAlpha;
815+
geom->getSensorXAlphaRefPlane(clsITS.getSensorID(), chipX, chipAlpha);
816+
if (!trkWorkITS.rotate(chipAlpha) || !propagator->PropagateToXBxByBz(trkWorkITS, chipX, mParams->maxSnp, mParams->maxStep, mMatCorr)) {
817+
LOGP(debug, "Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
818+
stopPropagation = true;
819+
break;
820+
}
821+
float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
822+
auto dy = clsITS.getY() - trkWorkITS.getY();
823+
auto dz = clsITS.getZ() - trkWorkITS.getZ();
824+
if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWorkITS.getY()) < param::MaxY) && (std::abs(trkWorkITS.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
825+
mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(clsITS.getSensorID()), 0);
826+
trackData.nExtDetResid++;
827+
// NEED TO STORE: ITS X, alpha
828+
}
829+
}
830+
break;
831+
}
723832
mTrackData.push_back(std::move(trackData));
724833
mGIDsSuccess.push_back(mGIDs[iSeed]);
725-
mTrackDataCompact.emplace_back(mClRes.size() - nClValidated, nClValidated, mGIDs[iSeed].getSource());
834+
mTrackDataCompact.emplace_back(mClRes.size() - nClValidated, nClValidated, mGIDs[iSeed].getSource()); // RS Check
726835
if (mDumpTrackPoints) {
727836
(*trackDataExtended).clIdx.setEntries(nClValidated);
728837
mTrackDataExtended.push_back(std::move(*trackDataExtended));

0 commit comments

Comments
 (0)