3333#include " Framework/ConfigParamRegistry.h"
3434#include " Framework/CCDBParamSpec.h"
3535#include " FT0Reconstruction/InteractionTag.h"
36+ #include " DataFormatsITSMFT/ClustersPerLayer.h"
3637#include " DataFormatsITSMFT/DPLAlpideParam.h"
3738#include " DetectorsCommonDataFormats/DetID.h"
3839#include " DetectorsBase/GRPGeomHelper.h"
@@ -80,6 +81,7 @@ using VTIndex = o2::dataformats::VtxTrackIndex;
8081using VTIndexV = std::pair<int , o2::dataformats::VtxTrackIndex>;
8182using GTrackID = o2::dataformats::GlobalTrackID;
8283using TBracket = o2::math_utils::Bracketf_t;
84+ using ITSClusters = o2::itsmft::ClustersPerLayer<o2::BaseCluster<float >>;
8385
8486using timeEst = o2::dataformats::TimeStampWithError<float , float >;
8587
@@ -121,7 +123,7 @@ class TrackMCStudy final : public Task
121123 std::vector<long > mIntBC ; // /< interaction global BC wrt TF start
122124 std::vector<float > mTPCOcc ; // /< TPC occupancy for this interaction time
123125 std::vector<int > mITSOcc ; // < N ITS clusters in the ROF containing collision
124- std::vector<o2::BaseCluster< float >> mITSClustersArray ; // /< ITS clusters created in run() method from compact clusters
126+ ITSClusters mITSClustersArray ; // /< ITS clusters from compact clusters, by composed ID
125127 const o2::itsmft::TopologyDictionary* mITSDict = nullptr ; // /< cluster patterns dictionary
126128
127129 bool mCheckSV = false ; // < check SV binding (apart from prongs availability)
@@ -321,10 +323,18 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData)
321323 {
322324 const auto * digconst = mcReader.getDigitizationContext ();
323325 const auto & mcEvRecords = digconst->getEventRecords (false );
324- int ITSTimeBias = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS >::Instance ().roFrameBiasInBC ;
325- int ITSROFLen = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS >::Instance ().roFrameLengthInBC ;
326- unsigned int rofCount = 0 ;
327- const auto ITSClusROFRec = recoData.getITSClustersROFRecords ();
326+ // in the staggered readout every layer has its own ROF length, bias and ROFRecords, hence the
327+ // occupancy is summed over the layer slots, each with its own (monotonic) ROF cursor
328+ const int nLrOcc = recoData.getITSPerLayer () ? o2::globaltracking::MaxITSLayers : 1 ;
329+ const auto & alpParITS = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS >::Instance ();
330+ std::array<gsl::span<const o2::itsmft::ROFRecord>, o2::globaltracking::MaxITSLayers> ITSClusROFRec{};
331+ std::array<int , o2::globaltracking::MaxITSLayers> ITSTimeBias{}, ITSROFLen{};
332+ std::array<unsigned int , o2::globaltracking::MaxITSLayers> rofCount{};
333+ for (int lr = 0 ; lr < nLrOcc; lr++) {
334+ ITSClusROFRec[lr] = recoData.getITSClustersROFRecords (lr);
335+ ITSTimeBias[lr] = alpParITS.getROFBiasInBC (lr);
336+ ITSROFLen[lr] = alpParITS.getROFLengthInBC (lr);
337+ }
328338 for (const auto & mcIR : mcEvRecords) {
329339 long tbc = mcIR.differenceInBC (recoData.startIR );
330340 auto & mcVtx = mMCVtVec .emplace_back ();
@@ -335,18 +345,21 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData)
335345 mTPCOcc .push_back (occBin < 0 ? mTBinClOcc [0 ] : (occBin >= mTBinClOcc .size () ? mTBinClOcc .back () : mTBinClOcc [occBin]));
336346 // fill ITS occupancy
337347 long gbc = mcIR.toLong ();
338- while (rofCount < ITSClusROFRec.size ()) {
339- long rofbcMin = ITSClusROFRec[rofCount].getBCData ().toLong () + ITSTimeBias, rofbcMax = rofbcMin + ITSROFLen;
340- if (gbc < rofbcMin) { // IRs and ROFs are sorted, so this IR is prior of all ROFs
341- mITSOcc .push_back (0 );
342- } else if (gbc < rofbcMax) {
343- mITSOcc .push_back (ITSClusROFRec[rofCount].getNEntries ());
344- } else {
345- rofCount++; // test next ROF
346- continue ;
348+ int itsOcc = 0 ;
349+ for (int lr = 0 ; lr < nLrOcc; lr++) {
350+ const auto & rofs = ITSClusROFRec[lr];
351+ while (rofCount[lr] < rofs.size ()) {
352+ long rofbcMin = rofs[rofCount[lr]].getBCData ().toLong () + ITSTimeBias[lr], rofbcMax = rofbcMin + ITSROFLen[lr];
353+ if (gbc < rofbcMin) { // IRs and ROFs are sorted, so this IR is prior of all remaining ROFs of this layer
354+ break ;
355+ } else if (gbc < rofbcMax) {
356+ itsOcc += rofs[rofCount[lr]].getNEntries ();
357+ break ;
358+ }
359+ rofCount[lr]++; // test next ROF
347360 }
348- break ;
349361 }
362+ mITSOcc .push_back (itsOcc); // 0 if the IR is before the 1st or after the last ROF of every layer
350363 if (mNTPCOccBinLengthInv > 0 .f ) {
351364 mcVtx.occTPCV .resize (params.nOccBinsDrift );
352365 int grp = TMath::Max (1 , TMath::Nint (params.nTBPerOccBin * mNTPCOccBinLengthInv ));
@@ -362,9 +375,6 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData)
362375 mcVtx.occTPCV [ib] = smb;
363376 }
364377 }
365- if (rofCount >= ITSClusROFRec.size ()) {
366- mITSOcc .push_back (0 ); // IR after the last ROF
367- }
368378 }
369379 }
370380 // collect interesting MC particle (tracks and parents)
@@ -940,18 +950,21 @@ void TrackMCStudy::fillMCClusterInfo(const o2::globaltracking::RecoContainer& re
940950 }
941951 }
942952 // fill ITS cluster info
943- const auto * mcITSClusters = recoData.getITSClustersMCLabels ();
944- const auto & ITSClusters = recoData.getITSClusters ();
945- for (unsigned int icl = 0 ; icl < ITSClusters.size (); icl++) {
946- const auto labels = mcITSClusters->getLabels (icl);
947- for (const auto & lbl : labels) {
948- auto entry = mSelMCTracks .find (lbl);
949- if (entry == mSelMCTracks .end ()) { // not selected
950- continue ;
953+ int nLrCl = recoData.getITSPerLayer () ? o2::globaltracking::MaxITSLayers : 1 ;
954+ for (int lr = 0 ; lr < nLrCl; lr++) { // with a single (monolithic) input all clusters are in the layer slot 0
955+ const auto * mcITSClusters = recoData.getITSClustersMCLabels (lr);
956+ const auto & ITSClusters = recoData.getITSClusters (lr);
957+ for (unsigned int icl = 0 ; icl < ITSClusters.size (); icl++) {
958+ const auto labels = mcITSClusters->getLabels (icl);
959+ for (const auto & lbl : labels) {
960+ auto entry = mSelMCTracks .find (lbl);
961+ if (entry == mSelMCTracks .end ()) { // not selected
962+ continue ;
963+ }
964+ auto & mctr = entry->second .mcTrackInfo ;
965+ mctr.nITSCl ++;
966+ mctr.pattITSCl |= 0x1 << o2::itsmft::ChipMappingITS::getLayer (ITSClusters[icl].getChipID ());
951967 }
952- auto & mctr = entry->second .mcTrackInfo ;
953- mctr.nITSCl ++;
954- mctr.pattITSCl |= 0x1 << o2::itsmft::ChipMappingITS::getLayer (ITSClusters[icl].getChipID ());
955968 }
956969 }
957970
@@ -1306,17 +1319,22 @@ void TrackMCStudy::processITSTracks(const o2::globaltracking::RecoContainer& rec
13061319 const auto itsTracks = recoData.getITSTracks ();
13071320 const auto itsLbls = recoData.getITSTracksMCLabels ();
13081321 const auto itsClRefs = recoData.getITSTracksClusterRefs ();
1309- const auto clusITS = recoData.getITSClusters ();
1310- const auto patterns = recoData.getITSClustersPatterns ();
13111322 const auto & params = o2::trackstudy::TrackMCStudyConfig::Instance ();
1312- auto pattIt = patterns.begin ();
1313- mITSClustersArray .clear ();
1314- mITSClustersArray .reserve (clusITS.size ());
1315-
1316- o2::its::ioutils::convertCompactClusters (clusITS, pattIt, mITSClustersArray , mITSDict );
1323+ int nLr = recoData.getITSPerLayer () ? o2::globaltracking::MaxITSLayers : 1 ;
1324+ mITSClustersArray .init (nLr);
1325+ for (int lr = 0 ; lr < nLr; lr++) { // with a single (monolithic) input all clusters are in the layer slot 0
1326+ mITSClustersArray .beginLayer (lr);
1327+ const auto clusITS = recoData.getITSClusters (lr);
1328+ const auto patterns = recoData.getITSClustersPatterns (lr);
1329+ auto pattIt = patterns.begin ();
1330+ mITSClustersArray .getClusters ().reserve (mITSClustersArray .size () + clusITS.size ());
1331+ o2::its::ioutils::convertCompactClusters (clusITS, pattIt, mITSClustersArray .getClusters (), mITSDict );
1332+ LOGP (info, " We have {} ITS clusters and the number of patterns is {} on the layer slot {}" , clusITS.size (), patterns.size (), lr);
1333+ }
1334+ mITSClustersArray .finalize ();
13171335 auto geom = o2::its::GeometryTGeo::Instance ();
13181336 int ntr = itsLbls.size ();
1319- LOGP (info, " We have {} ITS clusters and the number of patterns is {} , ITSdict:{} NMCLabels: {}" , clusITS. size (), patterns .size (), mITSDict != nullptr , itsLbls.size ());
1337+ LOGP (info, " In total {} ITS clusters, ITSdict:{} NMCLabels: {}" , mITSClustersArray .size (), mITSDict != nullptr , itsLbls.size ());
13201338
13211339 std::vector<int > evord (ntr);
13221340 std::iota (evord.begin (), evord.end (), 0 );
@@ -1376,7 +1394,7 @@ void TrackMCStudy::processITSTracks(const o2::globaltracking::RecoContainer& rec
13761394 }
13771395}
13781396
1379- DataProcessorSpec getTrackMCStudySpec (GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool checkSV)
1397+ DataProcessorSpec getTrackMCStudySpec (GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool checkSV, bool itsStag )
13801398{
13811399 std::vector<OutputSpec> outputs;
13821400 Options opts{
@@ -1387,6 +1405,7 @@ DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask
13871405 {" max-tpc-dcaz" , VariantType::Float, 2 .f , {" Cut on TPC dcaZ" }},
13881406 {" min-x-prop" , VariantType::Float, 6 .f , {" track should be propagated to this X at least" }}};
13891407 auto dataRequest = std::make_shared<DataRequest>();
1408+ dataRequest->setITSPerLayer (itsStag);
13901409 bool useMC = true ;
13911410 dataRequest->requestTracks (srcTracks, useMC);
13921411 dataRequest->requestClusters (srcClusters, useMC);
0 commit comments