Skip to content

Commit fcbb158

Browse files
committed
Support per-layer ITS clusters in check-resid-workfow and trackMCStudy-workflow
TrackMCStudy's ITS occupancy counting sums over the layer slots, each with its own ROF cursor advanced by DPLAlpideParam::getROFLengthInBC/ getROFBiasInBC(layer).
1 parent d82a9c3 commit fcbb158

6 files changed

Lines changed: 78 additions & 51 deletions

File tree

‎Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/CheckResidSpec.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
namespace o2::checkresid
2020
{
2121
/// create a processor spec
22-
o2::framework::DataProcessorSpec getCheckResidSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool drawOnly, bool postProcOnly);
22+
o2::framework::DataProcessorSpec getCheckResidSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool drawOnly, bool postProcOnly, bool itsStag);
2323

2424
} // namespace o2::checkresid
2525

‎Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace o2::trackstudy
2020
{
2121

2222
/// create a processor spec
23-
o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool checkSV);
23+
o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool checkSV, bool itsStag);
2424

2525
} // namespace o2::trackstudy
2626

‎Detectors/GlobalTrackingWorkflow/study/src/CheckResidSpec.cxx‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <TStopwatch.h>
1818
#include "DataFormatsGlobalTracking/RecoContainer.h"
1919
#include "DataFormatsITSMFT/TrkClusRef.h"
20+
#include "DataFormatsITSMFT/ClustersPerLayer.h"
2021
#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h"
2122
#include "ReconstructionDataFormats/TrackTPCITS.h"
2223
#include "ReconstructionDataFormats/GlobalTrackID.h"
@@ -70,6 +71,7 @@ using PVertex = o2::dataformats::PrimaryVertex;
7071
using V2TRef = o2::dataformats::VtxTrackRef;
7172
using VTIndex = o2::dataformats::VtxTrackIndex;
7273
using GTrackID = o2::dataformats::GlobalTrackID;
74+
using ITSClusters = o2::itsmft::ClustersPerLayer<o2::BaseCluster<float>>;
7375
using timeEst = o2::dataformats::TimeStampWithError<float, float>;
7476

7577
class CheckResidSpec final : public Task
@@ -101,7 +103,7 @@ class CheckResidSpec final : public Task
101103
bool mMeanVertexUpdated = false;
102104
float mITSROFrameLengthMUS = 0.f;
103105
o2::dataformats::MeanVertexObject mMeanVtx{};
104-
std::vector<o2::BaseCluster<float>> mITSClustersArray; ///< ITS clusters created in run() method from compact clusters
106+
ITSClusters mITSClustersArray; ///< ITS clusters from compact clusters, by composed ID
105107
const o2::itsmft::TopologyDictionary* mITSDict = nullptr; ///< cluster patterns dictionary
106108
o2::vertexing::PVertexer mVertexer;
107109
std::shared_ptr<DataRequest> mDataRequest;
@@ -240,14 +242,17 @@ void CheckResidSpec::process()
240242
const auto itsTracks = mRecoData->getITSTracks();
241243
// const auto itsLbls = mRecoData->getITSTracksMCLabels();
242244
const auto itsClRefs = mRecoData->getITSTracksClusterRefs();
243-
const auto clusITS = mRecoData->getITSClusters();
244-
const auto patterns = mRecoData->getITSClustersPatterns();
245245
const auto& params = o2::checkresid::CheckResidConfig::Instance();
246-
auto pattIt = patterns.begin();
247-
mITSClustersArray.clear();
248-
mITSClustersArray.reserve(clusITS.size());
249-
250-
o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict);
246+
int nLr = mDataRequest->getITSPerLayer() ? o2::globaltracking::MaxITSLayers : 1;
247+
mITSClustersArray.init(nLr);
248+
for (int lr = 0; lr < nLr; lr++) { // with a single (monolithic) input all clusters are in the layer slot 0
249+
mITSClustersArray.beginLayer(lr);
250+
const auto clusITS = mRecoData->getITSClusters(lr);
251+
auto pattIt = mRecoData->getITSClustersPatterns(lr).begin();
252+
mITSClustersArray.getClusters().reserve(mITSClustersArray.size() + clusITS.size());
253+
o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray.getClusters(), mITSDict);
254+
}
255+
mITSClustersArray.finalize();
251256

252257
auto pvvec = mRecoData->getPrimaryVertices();
253258
auto trackIndex = mRecoData->getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
@@ -990,10 +995,11 @@ void CheckResidSpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
990995
}
991996
}
992997

993-
DataProcessorSpec getCheckResidSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool drawOnly, bool postProcOnly)
998+
DataProcessorSpec getCheckResidSpec(GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, bool drawOnly, bool postProcOnly, bool itsStag)
994999
{
9951000
std::vector<OutputSpec> outputs;
9961001
auto dataRequest = std::make_shared<DataRequest>();
1002+
dataRequest->setITSPerLayer(itsStag);
9971003
if (!drawOnly && !postProcOnly) {
9981004
bool useMC = false;
9991005
dataRequest->requestTracks(srcTracks, useMC);

‎Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx‎

Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
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;
8081
using VTIndexV = std::pair<int, o2::dataformats::VtxTrackIndex>;
8182
using GTrackID = o2::dataformats::GlobalTrackID;
8283
using TBracket = o2::math_utils::Bracketf_t;
84+
using ITSClusters = o2::itsmft::ClustersPerLayer<o2::BaseCluster<float>>;
8385

8486
using 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);

‎Detectors/GlobalTrackingWorkflow/study/src/check-resid-workflow.cxx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
5959

6060
bool drawOnly = configcontext.options().get<bool>("draw-external-only");
6161
bool postProcOnly = configcontext.options().get<bool>("postproc-external-only");
62+
bool doStag = o2::itsmft::DPLAlpideParamInitializer::isITSStaggeringEnabled(configcontext);
6263
GID::mask_t allowedSourcesTrc = GID::getSourcesMask("ITS,TPC,ITS-TPC,ITS-TPC-TRD,ITS-TPC-TOF,ITS-TPC-TRD-TOF");
6364
GID::mask_t allowedSourcesClus = GID::getSourcesMask("ITS");
6465

@@ -75,7 +76,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
7576
allowedSourcesTrc = {};
7677
allowedSourcesClus = {};
7778
}
78-
specs.emplace_back(o2::checkresid::getCheckResidSpec(srcTrc, srcCls, drawOnly, postProcOnly));
79+
specs.emplace_back(o2::checkresid::getCheckResidSpec(srcTrc, srcCls, drawOnly, postProcOnly, doStag));
7980

8081
// configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit
8182
if (!drawOnly) {

‎Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
6060
WorkflowSpec specs;
6161
auto useMC = !configcontext.options().get<bool>("disable-mc");
6262
auto checkSV = !configcontext.options().get<bool>("ignore-sv-check");
63+
auto doStag = o2::itsmft::DPLAlpideParamInitializer::isITSStaggeringEnabled(configcontext);
6364
if (!useMC) {
6465
throw std::runtime_error("MC cannot be disabled for this workflow");
6566
}
@@ -86,7 +87,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
8687
specs.emplace_back(o2::tpc::getTPCScalerSpec(sclOpt));
8788
}
8889

89-
specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, checkSV));
90+
specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, checkSV, doStag));
9091
// configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit
9192
o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs);
9293

0 commit comments

Comments
 (0)