3131#include < RtypesCore.h>
3232
3333#include < cstdint>
34+ #include < vector>
3435
3536using namespace o2 ;
3637using namespace o2 ::framework;
@@ -51,31 +52,54 @@ struct integrationTest {
5152 Configurable<bool > do2DNTrackCorr{" do2DNTrackCorr" , true , " Do 2D Ntrack correlation plots" };
5253
5354 Configurable<bool > doBasicQA{" doBasicQA" , true , " Do basic QA" };
55+ Configurable<bool > checkThinning{" checkThinning" , true , " Check thinning-related quantities (retaining of TPC-only tracks)" };
5456 ConfigurableAxis axisHasDetector{" axisHasDetector" , {16 , -0 .5f , 15 .5f }, " " };
5557 ConfigurableAxis axisEta{" axisEta" , {200 , -2 .0f , 2 .0f }, " " };
5658 ConfigurableAxis axisPhi{" axisPhi" , {200 , 0 .0f , +2 * TMath::Pi ()}, " " };
5759 ConfigurableAxis axisNclu{" axisNclu" , {10 , -0 .5f , 9 .5f }, " " };
5860 ConfigurableAxis axisPt{" axisPt" , {VARIABLE_WIDTH, 0 .0f , 0 .1f , 0 .2f , 0 .3f , 0 .4f , 0 .5f , 0 .6f , 0 .7f , 0 .8f , 0 .9f , 1 .0f , 1 .1f , 1 .2f , 1 .3f , 1 .4f , 1 .5f , 1 .6f , 1 .7f , 1 .8f , 1 .9f , 2 .0f , 2 .2f , 2 .4f , 2 .6f , 2 .8f , 3 .0f , 3 .2f , 3 .4f , 3 .6f , 3 .8f , 4 .0f , 4 .4f , 4 .8f , 5 .2f , 5 .6f , 6 .0f , 6 .5f , 7 .0f , 7 .5f , 8 .0f , 9 .0f , 10 .0f , 11 .0f , 12 .0f , 13 .0f , 14 .0f , 15 .0f , 17 .0f , 19 .0f , 21 .0f , 23 .0f , 25 .0f , 30 .0f , 35 .0f , 40 .0f , 50 .0f }, " pt axis for analysis" };
5961
62+ enum kTrackType { kTrackUsedV0 = 0 ,
63+ kTrackUsedCascade ,
64+ kTrackUsedDecay3Body ,
65+ kTrackUsedTrackedV0 ,
66+ kTrackUsedTrackedCascade ,
67+ kTrackUsedQA ,
68+ kNTrackTypes };
69+
6070 enum kTable { kBC = 0 ,
71+ kBCFlag ,
6172 kCollision ,
73+ kOrigin ,
6274 kTrack ,
6375 kTrackCov ,
6476 kTrackExtra ,
6577 kMftTrack ,
78+ kMftTrackCov ,
6679 kFwdTrack ,
6780 kFwdTrackCov ,
81+ kFwdTrackCl ,
6882 kAmbiguousTrack ,
6983 kAmbiguousMftTrack ,
7084 kAmbiguousFwdTrack ,
85+ kTracked3Body ,
86+ kTrackedCascade ,
87+ kTrackedV0 ,
88+ kTrackQA ,
7189 kV0 ,
7290 kCascade ,
91+ kDecay3Body ,
7392 kCalo ,
7493 kCaloTrigger ,
94+ kCpvCluster ,
7595 kFDD ,
96+ kFDDExtra ,
7697 kFT0 ,
77- kV0A ,
98+ kFT0Extra ,
99+ kFV0A ,
100+ kFV0AExtra ,
78101 kZDC ,
102+ kHMPID ,
79103 kMcCollision ,
80104 kMcCollisionLabel ,
81105 kMcParticle ,
@@ -91,24 +115,38 @@ struct integrationTest {
91115 TString lTableNames[] =
92116 {
93117 " bc" ,
118+ " bcflag" ,
94119 " collision" ,
120+ " origin" ,
95121 " track_iu" ,
96122 " trackcov_iu" ,
97123 " trackextra" ,
98124 " mfttrack" ,
125+ " mfttrackcov" ,
99126 " fwdtrack" ,
100127 " fwdtrackcov" ,
128+ " fwdtrkcl" ,
101129 " ambiguoustrack" ,
102130 " ambiguousmfttrack" ,
103131 " ambiguousfwdtrack" ,
132+ " tracked3body" ,
133+ " trackedcascade" ,
134+ " trackedv0" ,
135+ " trackqa" ,
104136 " v0" ,
105137 " cascade" ,
138+ " decay3body" ,
106139 " calo" ,
107- " calotrigger"
140+ " calotrigger" ,
141+ " cpvcluster" ,
108142 " fdd" ,
143+ " fddextra" ,
109144 " ft0" ,
145+ " ft0extra" ,
110146 " fv0a" ,
147+ " fv0aextra" ,
111148 " zdc" ,
149+ " hmpid" ,
112150 " mccollision" ,
113151 " mccollisionlabel" ,
114152 " mcparticle" ,
@@ -118,7 +156,7 @@ struct integrationTest {
118156 " Total count" ,
119157 " " // empty (last)
120158 };
121- const AxisSpec axisTables{30 , 0 .0f , 30 .0f , " " };
159+ const AxisSpec axisTables{40 , 0 .0f , 40 .0f , " " };
122160 const AxisSpec axisTracks{nBinsTracks, -0 .5f , MaxNTrack - 0 .5f , " N_{tracks}" };
123161 const AxisSpec axisCollisions{nBinsCollisions, -0 .5f , nBinsCollisions - 0 .5f , " N_{collisions}" };
124162 // Label correctly to avoid confusion
@@ -171,6 +209,31 @@ struct integrationTest {
171209 histos.add <TH1>(" hNCluAll" , " hNCluAll" , HistType::kTH1D , {axisNclu});
172210 histos.add <TH1>(" hNCluNoTPCOnly" , " hNCluNoTPCOnly" , HistType::kTH1D , {axisNclu});
173211 }
212+ if (checkThinning) {
213+ auto hThinningQA = histos.add <TH2>(" hThinningQA" , " hThinningQA" , HistType::kTH2D , {{64 , -0 .5f , 63 .5f }, {2 , -0 .5f , 1 .5f }});
214+
215+ TString kTrackTypeNames [] =
216+ {
217+ " V" ,
218+ " tV" ,
219+ " 3b" ,
220+ " C" ,
221+ " tC" ,
222+ " QA" };
223+
224+ // construct labels to make this plot easier to understand
225+ for (uint8_t i = 0 ; i < (1 << kNTrackTypes ); i++) {
226+ TString trackTypeString = " " ;
227+ for (uint8_t j = 0 ; j < kTrackUsedQA + 1 ; j++) {
228+ if (((i) & (1 << (j)))) {
229+ trackTypeString.Append (Form (" %s " , kTrackTypeNames [j].Data ()));
230+ }
231+ }
232+ hThinningQA->GetXaxis ()->SetBinLabel (i + 1 , trackTypeString.Data ());
233+ }
234+ hThinningQA->GetYaxis ()->SetBinLabel (0 , " Not TPConly" );
235+ hThinningQA->GetYaxis ()->SetBinLabel (1 , " TPConly" );
236+ }
174237 }
175238 // *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*
176239 // Standard sizes (uncorrelated)
@@ -193,42 +256,163 @@ struct integrationTest {
193256 aod::FDDs const & fdds,
194257 aod::FT0s const & ft0s,
195258 aod::FV0As const & fv0as,
259+ aod::Zdcs const & zdcs)
260+ {
261+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kBC ) + 0 .5f , bcs.size ());
262+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCollision ) + 0 .5f , collisions.size ());
263+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrack ) + 0 .5f , tracks.size ());
264+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrackCov ) + 0 .5f , trackcovs.size ());
265+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrackExtra ) + 0 .5f , trackextras.size ());
266+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMftTrack ) + 0 .5f , mfttracks.size ());
267+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFwdTrack ) + 0 .5f , fwdtracks.size ());
268+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFwdTrackCov ) + 0 .5f , fwdtrackcovs.size ());
269+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kAmbiguousTrack ) + 0 .5f , ambitracks.size ());
270+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kAmbiguousMftTrack ) + 0 .5f , ambimfttracks.size ());
271+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kAmbiguousFwdTrack ) + 0 .5f , ambifwdtracks.size ());
272+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kV0 ) + 0 .5f , v0s.size ());
273+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCascade ) + 0 .5f , cascades.size ());
274+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCalo ) + 0 .5f , calos.size ());
275+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCaloTrigger ) + 0 .5f , calotriggers.size ());
276+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFDD ) + 0 .5f , fdds.size ());
277+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFT0 ) + 0 .5f , ft0s.size ());
278+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFV0A ) + 0 .5f , fv0as.size ());
279+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kZDC ) + 0 .5f , zdcs.size ());
280+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFrameCounter ) + 0 .5f );
281+ }
282+ PROCESS_SWITCH (integrationTest, processDataModel, " Check data model" , true );
283+
284+ // *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*
285+ // Revised tables for newer data
286+ // Warning: will not work for legacy AO2Ds
287+ void processDataModel2026 (
288+ aod::BCs const & bcs,
289+ aod::BCFlags const & bcflags,
290+ aod::Collisions const & collisions,
291+ aod::Origins const & origins,
292+ aod::TracksIU const & tracks,
293+ aod::TracksCovIU const & trackcovs,
294+ aod::TracksExtra const & trackextras,
295+ aod::MFTTracks const & mfttracks,
296+ aod::MFTTracksCov const & mfttrackcovs,
297+ aod::FwdTracks const & fwdtracks,
298+ aod::FwdTracksCov const & fwdtrackcovs,
299+ aod::FwdTrkCls const & fwdtrkcls,
300+ aod::AmbiguousTracks const & ambitracks,
301+ aod::AmbiguousMFTTracks const & ambimfttracks,
302+ aod::AmbiguousFwdTracks const & ambifwdtracks,
303+ aod::Tracked3Bodys const & tracked3bodys,
304+ aod::TrackedCascades const & trackedcascades,
305+ aod::TrackedV0s const & trackedv0s,
306+ aod::TracksQAVersion const & tracksQA, // does not comply with normal iterator naming
307+ aod::V0s const & v0s,
308+ aod::Cascades const & cascades,
309+ aod::Decay3Bodys const & decay3bodys,
310+ aod::Calos const & calos,
311+ aod::CaloTriggers const & calotriggers,
312+ aod::CPVClusters const & cpvclusters,
313+ aod::FDDs const & fdds,
314+ aod::FDDsExtra const & fddsextra,
315+ aod::FT0s const & ft0s,
316+ aod::FT0sExtra const & ft0sextra,
317+ aod::FV0As const & fv0as,
318+ aod::FV0AsExtra const & fv0asextra,
196319 aod::Zdcs const & zdcs,
197- aod::McCollisions const & mccollisions,
198- aod::McCollisionLabels const & mccollisionlabels,
199- aod::McParticles const & mcparticles,
200- aod::McTrackLabels const & mctracklabels,
201- aod::McMFTTrackLabels const & mcmfttracklabels,
202- aod::McFwdTrackLabels const & mcfwdtracklabels)
320+ aod::HMPIDs const & hmpids)
203321 {
204322 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kBC ) + 0 .5f , bcs.size ());
323+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kBCFlag ) + 0 .5f , bcflags.size ());
205324 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCollision ) + 0 .5f , collisions.size ());
325+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kOrigin ) + 0 .5f , origins.size ());
206326 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrack ) + 0 .5f , tracks.size ());
207327 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrackCov ) + 0 .5f , trackcovs.size ());
208328 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrackExtra ) + 0 .5f , trackextras.size ());
209329 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMftTrack ) + 0 .5f , mfttracks.size ());
330+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMftTrackCov ) + 0 .5f , mfttrackcovs.size ());
210331 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFwdTrack ) + 0 .5f , fwdtracks.size ());
211332 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFwdTrackCov ) + 0 .5f , fwdtrackcovs.size ());
333+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFwdTrackCl ) + 0 .5f , fwdtrkcls.size ());
212334 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kAmbiguousTrack ) + 0 .5f , ambitracks.size ());
213335 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kAmbiguousMftTrack ) + 0 .5f , ambimfttracks.size ());
214336 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kAmbiguousFwdTrack ) + 0 .5f , ambifwdtracks.size ());
337+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTracked3Body ) + 0 .5f , tracked3bodys.size ());
338+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrackedCascade ) + 0 .5f , trackedcascades.size ());
339+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrackedV0 ) + 0 .5f , trackedv0s.size ());
340+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kTrackQA ) + 0 .5f , tracksQA.size ());
215341 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kV0 ) + 0 .5f , v0s.size ());
216342 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCascade ) + 0 .5f , cascades.size ());
343+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kDecay3Body ) + 0 .5f , decay3bodys.size ());
217344 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCalo ) + 0 .5f , calos.size ());
218345 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCaloTrigger ) + 0 .5f , calotriggers.size ());
346+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kCpvCluster ) + 0 .5f , cpvclusters.size ());
219347 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFDD ) + 0 .5f , fdds.size ());
348+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFDDExtra ) + 0 .5f , fddsextra.size ());
220349 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFT0 ) + 0 .5f , ft0s.size ());
221- histos.fill (HIST (" hTableSizes" ), static_cast <float >(kV0A ) + 0 .5f , fv0as.size ());
350+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFT0Extra ) + 0 .5f , ft0sextra.size ());
351+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFV0A ) + 0 .5f , fv0as.size ());
352+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFV0AExtra ) + 0 .5f , fv0asextra.size ());
222353 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kZDC ) + 0 .5f , zdcs.size ());
354+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kHMPID ) + 0 .5f , hmpids.size ());
355+ histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFrameCounter ) + 0 .5f );
356+
357+ if (checkThinning) {
358+ // perform checks regarding thinning
359+ std::vector<uint8_t > trackBits (tracks.size (), 0 );
360+
361+ if (tracks.size () != trackextras.size ()) {
362+ LOGF (fatal, " Check thinning requested and Tracks.size() != TracksExtra.size(). Very bad. Quitting..." );
363+ }
364+
365+ // mark tracks that are used by each kind of composite object
366+ for (const auto & v0 : v0s) {
367+ trackBits[v0.negTrackId ()] = trackBits[v0.negTrackId ()] | (1 << kTrackUsedV0 );
368+ trackBits[v0.posTrackId ()] = trackBits[v0.posTrackId ()] | (1 << kTrackUsedV0 );
369+ }
370+ for (const auto & cascade : cascades) {
371+ auto v0 = cascade.v0 (); // simple de-ref, no table joining
372+ trackBits[v0.negTrackId ()] = trackBits[v0.negTrackId ()] | (1 << kTrackUsedCascade );
373+ trackBits[v0.posTrackId ()] = trackBits[v0.posTrackId ()] | (1 << kTrackUsedCascade );
374+ trackBits[cascade.bachelorId ()] = trackBits[cascade.bachelorId ()] | (1 << kTrackUsedCascade );
375+ }
376+ for (const auto & trackedv0 : trackedv0s) {
377+ auto v0 = trackedv0.v0 (); // simple de-ref, no table joining
378+ trackBits[v0.negTrackId ()] = trackBits[v0.negTrackId ()] | (1 << kTrackUsedTrackedV0 );
379+ trackBits[v0.posTrackId ()] = trackBits[v0.posTrackId ()] | (1 << kTrackUsedTrackedV0 );
380+ }
381+ for (const auto & trackedcascade : trackedcascades) {
382+ auto cascade = trackedcascade.cascade (); // simple de-ref, no table joining
383+ auto v0 = cascade.v0 (); // simple de-ref, no table joining
384+ trackBits[v0.negTrackId ()] = trackBits[v0.negTrackId ()] | (1 << kTrackUsedTrackedCascade );
385+ trackBits[v0.posTrackId ()] = trackBits[v0.posTrackId ()] | (1 << kTrackUsedTrackedCascade );
386+ trackBits[cascade.bachelorId ()] = trackBits[cascade.bachelorId ()] | (1 << kTrackUsedTrackedCascade );
387+ }
388+ for (const auto & trackQA : tracksQA) {
389+ trackBits[trackQA.trackId ()] = trackBits[trackQA.trackId ()] | (1 << kTrackUsedQA );
390+ }
391+ for (uint32_t iTrack = 0 ; iTrack < trackextras.size (); iTrack++) {
392+ auto track = trackextras.rawIteratorAt (iTrack);
393+ bool isTPConly = track.hasTPC () && !track.hasTOF () && !track.hasTRD () && !track.hasITS ();
394+ histos.fill (HIST (" hThinningQA" ), static_cast <float >(trackBits[iTrack]), static_cast <float >(isTPConly));
395+ }
396+ }
397+ }
398+ PROCESS_SWITCH (integrationTest, processDataModel2026, " Check data model, 2026 version" , false );
399+
400+ void processDataModelMC (
401+ aod::McCollisions const & mccollisions,
402+ aod::McCollisionLabels const & mccollisionlabels,
403+ aod::McParticles const & mcparticles,
404+ aod::McTrackLabels const & mctracklabels,
405+ aod::McMFTTrackLabels const & mcmfttracklabels,
406+ aod::McFwdTrackLabels const & mcfwdtracklabels)
407+ {
223408 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMcCollision ) + 0 .5f , mccollisions.size ());
224409 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMcCollisionLabel ) + 0 .5f , mccollisionlabels.size ());
225410 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMcParticle ) + 0 .5f , mcparticles.size ());
226411 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMcTrackLabel ) + 0 .5f , mctracklabels.size ());
227412 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMcMftTrackLabel ) + 0 .5f , mcmfttracklabels.size ());
228413 histos.fill (HIST (" hTableSizes" ), static_cast <float >(kMcFwdTrackLabel ) + 0 .5f , mcfwdtracklabels.size ());
229- histos.fill (HIST (" hTableSizes" ), static_cast <float >(kFrameCounter ) + 0 .5f );
230414 }
231- PROCESS_SWITCH (integrationTest, processDataModel , " Check data model" , true );
415+ PROCESS_SWITCH (integrationTest, processDataModelMC , " Check data model for MC tables " , false );
232416
233417 void processBCs (aod::BC const &, aod::Collisions const & collisions)
234418 {
@@ -239,7 +423,7 @@ struct integrationTest {
239423 void processCollisions (aod::Collision const &, FullTracksIU const & tracks, aod::V0s const & v0s, aod::Cascades const & cascades)
240424 {
241425 Int_t lHasITS = 0 , lHasTPC = 0 , lHasTRD = 0 , lHasTOF = 0 , lNotTPCOnly = 0 ;
242- for (auto & track : tracks) {
426+ for (const auto & track : tracks) {
243427 // TPC only bool
244428 bool isTPConly = track.hasTPC () && !track.hasTOF () && !track.hasTRD () && !track.hasITS ();
245429 histos.fill (HIST (" hPt" ), track.pt ());
0 commit comments