1919#include " TPCCalibration/VDriftHelper.h"
2020#include " TPCCalibration/CorrectionMapsLoader.h"
2121#include " ITSMFTReconstruction/ChipMappingITS.h"
22+ #include " ITStracking/IOUtils.h"
2223#include " DetectorsBase/Propagator.h"
2324#include " DetectorsBase/GeometryManager.h"
25+ #include " ITSBase/GeometryTGeo.h"
2426#include " SimulationDataFormat/MCEventLabel.h"
2527#include " SimulationDataFormat/MCUtils.h"
2628#include " SimulationDataFormat/O2DatabasePDG.h"
29+ #include " SimulationDataFormat/TrackReference.h"
2730#include " CommonDataFormat/BunchFilling.h"
2831#include " CommonUtils/NameConf.h"
2932#include " DataFormatsFT0/RecPoints.h"
@@ -99,6 +102,7 @@ class TrackMCStudy : public Task
99102
100103 private:
101104 void processTPCTrackRefs ();
105+ void processITSTracks (const o2::globaltracking::RecoContainer& recoData);
102106 void loadTPCOccMap (const o2::globaltracking::RecoContainer& recoData);
103107 void fillMCClusterInfo (const o2::globaltracking::RecoContainer& recoData);
104108 void prepareITSData (const o2::globaltracking::RecoContainer& recoData);
@@ -122,6 +126,9 @@ class TrackMCStudy : public Task
122126 std::vector<long > mIntBC ; // /< interaction global BC wrt TF start
123127 std::vector<float > mTPCOcc ; // /< TPC occupancy for this interaction time
124128 std::vector<int > mITSOcc ; // < N ITS clusters in the ROF containing collision
129+ std::vector<o2::BaseCluster<float >> mITSClustersArray ; // /< ITS clusters created in run() method from compact clusters
130+ const o2::itsmft::TopologyDictionary* mITSDict = nullptr ; // /< cluster patterns dictionary
131+
125132 bool mCheckSV = false ; // < check SV binding (apart from prongs availability)
126133 bool mRecProcStage = false ; // < flag that the MC particle was added only at the stage of reco tracks processing
127134 int mNTPCOccBinLength = 0 ; // /< TPC occ. histo bin length in TBs
@@ -221,7 +228,7 @@ void TrackMCStudy::updateTimeDependentParams(ProcessingContext& pc)
221228
222229 auto & elParam = o2::tpc::ParameterElectronics::Instance ();
223230 mTPCTBinMUS = elParam.ZbinWidth ;
224-
231+ o2::its::GeometryTGeo::Instance ()-> fillMatrixCache ( o2::math_utils::bit2Mask (o2::math_utils::TransformType::T2GRot) | o2::math_utils::bit2Mask (o2::math_utils::TransformType::T2L));
225232 if (mCheckSV ) {
226233 const auto & svparam = o2::vertexing::SVertexerParams::Instance ();
227234 mFitterV0 .setBz (o2::base::Propagator::Instance ()->getNominalBz ());
@@ -751,6 +758,10 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData)
751758 });
752759 (*mDBGOut ) << " mcVtxTree" << " mcVtx=" << mcVtx << " \n " ;
753760 }
761+
762+ if (params.storeITSInfo ) {
763+ processITSTracks (recoData);
764+ }
754765}
755766
756767void TrackMCStudy::processTPCTrackRefs ()
@@ -1023,6 +1034,11 @@ void TrackMCStudy::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
10231034 mITSROFrameLengthMUS = par.roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3 ;
10241035 return ;
10251036 }
1037+ if (matcher == ConcreteDataMatcher (" ITS" , " CLUSDICT" , 0 )) {
1038+ LOG (info) << " cluster dictionary updated" ;
1039+ mITSDict = (const o2::itsmft::TopologyDictionary*)obj;
1040+ return ;
1041+ }
10261042}
10271043
10281044// _____________________________________________________
@@ -1276,6 +1292,84 @@ void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoDa
12761292 }
12771293}
12781294
1295+ void TrackMCStudy::processITSTracks (const o2::globaltracking::RecoContainer& recoData)
1296+ {
1297+ if (!mITSDict ) {
1298+ LOGP (warn, " ITS data is not loaded" );
1299+ return ;
1300+ }
1301+ const auto itsTracks = recoData.getITSTracks ();
1302+ const auto itsLbls = recoData.getITSTracksMCLabels ();
1303+ const auto itsClRefs = recoData.getITSTracksClusterRefs ();
1304+ const auto clusITS = recoData.getITSClusters ();
1305+ const auto patterns = recoData.getITSClustersPatterns ();
1306+ auto pattIt = patterns.begin ();
1307+ mITSClustersArray .clear ();
1308+ mITSClustersArray .reserve (clusITS.size ());
1309+
1310+ o2::its::ioutils::convertCompactClusters (clusITS, pattIt, mITSClustersArray , mITSDict );
1311+ auto geom = o2::its::GeometryTGeo::Instance ();
1312+ int ntr = itsLbls.size ();
1313+ LOGP (info, " We have {} ITS clusters and the number of patterns is {}, ITSdict:{} NMCLabels: {}" , clusITS.size (), patterns.size (), mITSDict != nullptr , itsLbls.size ());
1314+
1315+ std::vector<int > evord (ntr);
1316+ std::iota (evord.begin (), evord.end (), 0 );
1317+ std::sort (evord.begin (), evord.end (), [&](int i, int j) { return itsLbls[i] < itsLbls[j]; });
1318+ std::vector<ITSHitInfo> outHitInfo;
1319+ std::array<int , 7 > cl2arr{};
1320+
1321+ for (int itr0 = 0 ; itr0 < ntr; itr0++) {
1322+ auto itr = evord[itr0];
1323+ const auto & itsTr = itsTracks[itr];
1324+ const auto & itsLb = itsLbls[itr];
1325+ // LOGP(info,"proc {} {} {}",itr0, itr, itsLb.asString());
1326+ int nCl = itsTr.getNClusters ();
1327+ if (itsLb.isFake () || nCl != 7 ) {
1328+ continue ;
1329+ }
1330+ auto entrySel = mSelMCTracks .find (itsLb);
1331+ if (entrySel == mSelMCTracks .end ()) {
1332+ continue ;
1333+ }
1334+ outHitInfo.clear ();
1335+ cl2arr.fill (-1 );
1336+ auto clEntry = itsTr.getFirstClusterEntry ();
1337+ for (int iCl = nCl; iCl--;) { // clusters are stored from outer to inner layers
1338+ const auto & cls = mITSClustersArray [itsClRefs[clEntry + iCl]];
1339+ int hpos = outHitInfo.size ();
1340+ auto & hinf = outHitInfo.emplace_back ();
1341+ hinf.clus = cls;
1342+ hinf.clus .setCount (geom->getLayer (cls.getSensorID ()));
1343+ geom->getSensorXAlphaRefPlane (cls.getSensorID (), hinf.chipX , hinf.chipAlpha );
1344+ cl2arr[hinf.clus .getCount ()] = hpos; // to facilitate finding the cluster of the layer
1345+ }
1346+ auto trspan = mcReader.getTrackRefs (itsLb.getSourceID (), itsLb.getEventID (), itsLb.getTrackID ());
1347+ int ilrc = -1 , nrefAcc = 0 ;
1348+ for (const auto & trf : trspan) {
1349+ if (trf.getDetectorId () != 0 ) { // process ITS only
1350+ continue ;
1351+ }
1352+ int lrt = trf.getUserId (); // layer of the reference, but there might be multiple hits on the same layer
1353+ int clEnt = cl2arr[lrt];
1354+ if (clEnt < 0 ) {
1355+ continue ;
1356+ }
1357+ auto & hinf = outHitInfo[clEnt];
1358+ float traX, traY;
1359+ o2::math_utils::rotateZInv (trf.X (), trf.Y (), traX, traY, std::sin (hinf.chipAlpha ), std::cos (hinf.chipAlpha )); // tracking coordinates of the reference
1360+ if (hinf.trefXT < 1 || std::abs (traX - hinf.chipX ) < std::abs (hinf.trefXT - hinf.chipX )) {
1361+ if (hinf.trefXT < 1 ) {
1362+ nrefAcc++;
1363+ }
1364+ hinf.tref = trf;
1365+ hinf.trefXT = traX;
1366+ hinf.trefYT = traY;
1367+ }
1368+ }
1369+ (*mDBGOut ) << " itsTree" << " hits=" << outHitInfo << " trIn=" << ((o2::track::TrackParCov&)itsTr) << " trOut=" << itsTr.getParamOut () << " mcTr=" << entrySel->second .mcTrackInfo .track << " nTrefs=" << nrefAcc << " \n " ;
1370+ }
1371+ }
1372+
12791373DataProcessorSpec getTrackMCStudySpec (GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool checkSV)
12801374{
12811375 std::vector<OutputSpec> outputs;
0 commit comments