@@ -40,16 +40,17 @@ struct BcOccupancyQaTask {
4040 Configurable<float > maxOccupancyByTracks{" maxOccupancyByTracks" , 25000 ., " upper edge of the axis for the occupancy by ITS tracks" };
4141 Configurable<int > nBinsOccupancyByFT0C{" nBinsOccupancyByFT0C" , 500 , " number of bins for the occupancy by FT0C amplitudes" };
4242 Configurable<float > maxOccupancyByFT0C{" maxOccupancyByFT0C" , 250000 ., " upper edge of the axis for the occupancy by FT0C amplitudes" };
43+ Configurable<int > nBinsNumCollsInRof{" nBinsNumCollsInRof" , 50 , " number of bins for the number of collisions in the ITS ROF (also the upper edge of the axis)" };
4344 Configurable<int > nBinsBcInTF{" nBinsBcInTF" , 1188 , " number of bins for the BC position in the TF" };
4445 Configurable<int > nOrbitsPerTF{" nOrbitsPerTF" , 32 , " number of orbits per TF, for the histograms vs BC position in the TF (128 in 2022)" };
4546
4647 HistogramRegistry histos{" histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
4748
48- static constexpr int NFlags = 6 ;
49+ static constexpr int NFlags = 7 ;
4950 static constexpr std::array<int , NFlags> FlagBits = {aod::bcocc::kNoCollInTimeRangeNarrow , aod::bcocc::kNoCollInTimeRangeStrict , aod::bcocc::kNoCollInTimeRangeStandard ,
50- aod::bcocc::kNoCollInRofStrict , aod::bcocc::kNoCollInRofStandard , aod::bcocc::kNoHighMultCollInPrevRof };
51+ aod::bcocc::kNoCollInRofStrict , aod::bcocc::kNoCollInRofStandard , aod::bcocc::kNoHighMultCollInPrevRof , aod::bcocc:: kUpcMode };
5152 static constexpr std::array<const char *, NFlags> FlagNames = {" NoCollInTimeRangeNarrow" , " NoCollInTimeRangeStrict" , " NoCollInTimeRangeStandard" ,
52- " NoCollInRofStrict" , " NoCollInRofStandard" , " NoHighMultCollInPrevRof" };
53+ " NoCollInRofStrict" , " NoCollInRofStandard" , " NoHighMultCollInPrevRof" , " UpcMode " };
5354 static constexpr int NBCsPerOrbit = 3564 ;
5455 int64_t nBCsPerTF = 0 ;
5556
@@ -60,6 +61,7 @@ struct BcOccupancyQaTask {
6061 const AxisSpec axisOccupancyByFT0C{nBinsOccupancyByFT0C.value , 0 ., maxOccupancyByFT0C.value , " occupancy by FT0C amplitudes" };
6162 const AxisSpec axisMedianTime{280 , -40 ., 100 ., " median time of the occupancy (#mus)" };
6263 const AxisSpec axisNumCollsInBC{11 , -0.5 , 10.5 , " number of collisions found in the BC" };
64+ const AxisSpec axisNumCollsInRof{nBinsNumCollsInRof.value + 1 , -1.5 , nBinsNumCollsInRof.value - 0.5 , " number of collisions found in the ITS ROF of the BC" };
6365 const AxisSpec axisBcInTF{nBinsBcInTF.value , 0 ., static_cast <double >(nBCsPerTF), " BC in TF" };
6466 const AxisSpec axisBcInOrbit{NBCsPerOrbit, -0.5 , NBCsPerOrbit - 0.5 , " BC in orbit" };
6567 const AxisSpec axisFlags{NFlags + 1 , -0.5 , NFlags + 0.5 , " " };
@@ -69,6 +71,9 @@ struct BcOccupancyQaTask {
6971 // all BCs
7072 histos.add (" hBcCounter" , " number of BCs" , kTH1D , {axisBcCounter});
7173 histos.add (" hNumCollsInBC" , " all BCs" , kTH1D , {axisNumCollsInBC});
74+ histos.add (" hNumCollsInRof" , " all BCs" , kTH1D , {axisNumCollsInRof});
75+ histos.add (" hNumCollsInRofVsInBC" , " all BCs" , kTH2D , {axisNumCollsInBC, axisNumCollsInRof});
76+ histos.add (" hNumCollsInRofUpcMode" , " all BCs in ITS ROFs in UPC mode (kUpcMode)" , kTH1D , {axisNumCollsInRof});
7277 histos.add (" hBcInTF" , " all BCs" , kTH1D , {axisBcInTF});
7378 // BCs with calculated occupancy
7479 histos.add (" hBcInTFOccupancyDefined" , " BCs with calculated occupancy" , kTH1D , {axisBcInTF});
@@ -103,9 +108,39 @@ struct BcOccupancyQaTask {
103108 hBcIndexCheck->GetXaxis ()->SetBinLabel (4 , " BC found in BcOccsAll" );
104109 hBcIndexCheck->GetXaxis ()->SetBinLabel (5 , " BC found, same global BC" );
105110 hBcIndexCheck->GetXaxis ()->SetBinLabel (6 , " BC not found" );
111+
112+ // aod::BcOccs (joinable with aod::BCs)
113+ histos.add (" BcOccs/hBcCounter" , " number of BCs" , kTH1D , {axisBcCounter});
114+ histos.add (" BcOccs/hNumCollsInBC" , " all BCs" , kTH1D , {axisNumCollsInBC});
115+ histos.add (" BcOccs/hNumCollsInRof" , " all BCs" , kTH1D , {axisNumCollsInRof});
116+ histos.add (" BcOccs/hOccupancyByTracks" , " BCs with calculated occupancy" , kTH1D , {axisOccupancyByTracks});
117+ histos.add (" BcOccs/hOccupancyByFT0C" , " BCs with calculated occupancy" , kTH1D , {axisOccupancyByFT0C});
118+ histos.add (" BcOccs/hOccupancyByTracksVsFT0C" , " BCs with calculated occupancy" , kTH2D , {axisOccupancyByFT0C, axisOccupancyByTracks});
119+ histos.add (" BcOccs/hOccupancyFlags" , " BCs with calculated occupancy" , kTH1D , {axisFlags});
120+ auto hBcCounterBcOccs = histos.get <TH1 >(HIST (" BcOccs/hBcCounter" ));
121+ hBcCounterBcOccs->GetXaxis ()->SetBinLabel (1 , " all" );
122+ hBcCounterBcOccs->GetXaxis ()->SetBinLabel (2 , " occupancy calculated" );
123+ hBcCounterBcOccs->GetXaxis ()->SetBinLabel (3 , " occupancy not available" );
124+ auto hFlagsBcOccs = histos.get <TH1 >(HIST (" BcOccs/hOccupancyFlags" ));
125+ hFlagsBcOccs->GetXaxis ()->SetBinLabel (1 , " all" );
126+ for (int i = 0 ; i < NFlags; i++) {
127+ hFlagsBcOccs->GetXaxis ()->SetBinLabel (i + 2 , FlagNames[i]);
128+ }
129+
130+ // comparison of aod::BcOccs with aod::BcOccsAll for the BCs of aod::BCs
131+ histos.add (" BcOccsVsBcOccsAll/hCheck" , " BcOccs vs BcOccsAll" , kTH1D , {{7 , -0.5 , 6.5 , " " }});
132+ auto hCheck = histos.get <TH1 >(HIST (" BcOccsVsBcOccsAll/hCheck" ));
133+ hCheck->GetXaxis ()->SetBinLabel (1 , " BCs in BcOccs" );
134+ hCheck->GetXaxis ()->SetBinLabel (2 , " found in BcOccsAll" );
135+ hCheck->GetXaxis ()->SetBinLabel (3 , " same numCollsInBC, numCollsInRof" );
136+ hCheck->GetXaxis ()->SetBinLabel (4 , " same kUpcMode" );
137+ hCheck->GetXaxis ()->SetBinLabel (5 , " occupancy calculated in both" );
138+ hCheck->GetXaxis ()->SetBinLabel (6 , " same occupancy and flags" );
139+ hCheck->GetXaxis ()->SetBinLabel (7 , " not found in BcOccsAll" );
106140 }
107141
108- void process (aod::BcOccsAll const & bcOccs, aod::BCs const & bcs)
142+ // QA of aod::BcOccsAll (all BCs of the TFs), with the cross-check of the lookup by global BC
143+ void processBcOccsAll (aod::BcOccsAll const & bcOccs, aod::BCs const & bcs)
109144 {
110145 // cross-check of the lookup by global BC: every BC of the BC table should be found, with the same global BC
111146 // (not found: BCs before the start of run, or no BcOccsAll entries for this DF)
@@ -140,6 +175,11 @@ struct BcOccupancyQaTask {
140175 const int bcInOrbit = static_cast <int >(globalBC % NBCsPerOrbit);
141176 histos.fill (HIST (" hBcCounter" ), 0 );
142177 histos.fill (HIST (" hNumCollsInBC" ), bcOcc.numCollsInBC ());
178+ histos.fill (HIST (" hNumCollsInRof" ), bcOcc.numCollsInRof ());
179+ histos.fill (HIST (" hNumCollsInRofVsInBC" ), bcOcc.numCollsInBC (), bcOcc.numCollsInRof ());
180+ if (bcOcc.occupancyFlags_bit (aod::bcocc::kUpcMode )) { // set for all BCs, also without calculated occupancy
181+ histos.fill (HIST (" hNumCollsInRofUpcMode" ), bcOcc.numCollsInRof ());
182+ }
143183 histos.fill (HIST (" hBcIndexCheck" ), 0 );
144184 if (bcOccAllIndexed.contains (globalBC) && bcOccAllIndexed[globalBC].globalBC () == globalBC) { // global BCs are unique: same row
145185 histos.fill (HIST (" hBcIndexCheck" ), 1 );
@@ -176,6 +216,64 @@ struct BcOccupancyQaTask {
176216 }
177217 }
178218 }
219+ PROCESS_SWITCH (BcOccupancyQaTask, processBcOccsAll, " QA of aod::BcOccsAll (all BCs of the TFs)" , true );
220+
221+ // QA of aod::BcOccs (joinable with aod::BCs)
222+ void processBcOccs (soa::Join<aod::BCs, aod::BcOccs> const & bcs)
223+ {
224+ for (const auto & bc : bcs) {
225+ histos.fill (HIST (" BcOccs/hBcCounter" ), 0 );
226+ histos.fill (HIST (" BcOccs/hNumCollsInBC" ), bc.numCollsInBC ());
227+ histos.fill (HIST (" BcOccs/hNumCollsInRof" ), bc.numCollsInRof ());
228+ const int occByTracks = bc.trackOccupancyInTimeRange ();
229+ const float occByFT0C = bc.ft0cOccupancyInTimeRange ();
230+ if (occByTracks < 0 || occByFT0C < 0 ) {
231+ histos.fill (HIST (" BcOccs/hBcCounter" ), 2 );
232+ continue ;
233+ }
234+ histos.fill (HIST (" BcOccs/hBcCounter" ), 1 );
235+ histos.fill (HIST (" BcOccs/hOccupancyByTracks" ), occByTracks);
236+ histos.fill (HIST (" BcOccs/hOccupancyByFT0C" ), occByFT0C);
237+ histos.fill (HIST (" BcOccs/hOccupancyByTracksVsFT0C" ), occByFT0C, occByTracks);
238+ histos.fill (HIST (" BcOccs/hOccupancyFlags" ), 0 );
239+ for (int i = 0 ; i < NFlags; i++) {
240+ if (bc.occupancyFlags_bit (FlagBits[i])) {
241+ histos.fill (HIST (" BcOccs/hOccupancyFlags" ), i + 1 );
242+ }
243+ }
244+ }
245+ }
246+ PROCESS_SWITCH (BcOccupancyQaTask, processBcOccs, " QA of aod::BcOccs (joinable with aod::BCs)" , true );
247+
248+ // comparison of aod::BcOccs with aod::BcOccsAll for the BCs of aod::BCs: the same calculation, so the values should be identical
249+ // (occupancy and flags are compared only if calculated in both, since bcsForOccupancy can differ for the two tables)
250+ void processBcOccsVsBcOccsAll (soa::Join<aod::BCs, aod::BcOccs> const & bcs, aod::BcOccsAll const & bcOccsAll)
251+ {
252+ aod::bcocc::BcOccAllIndex bcOccAllIndexed (bcOccsAll);
253+ for (const auto & bc : bcs) {
254+ histos.fill (HIST (" BcOccsVsBcOccsAll/hCheck" ), 0 );
255+ if (!bcOccAllIndexed.contains (bc.globalBC ())) {
256+ histos.fill (HIST (" BcOccsVsBcOccsAll/hCheck" ), 6 );
257+ continue ;
258+ }
259+ histos.fill (HIST (" BcOccsVsBcOccsAll/hCheck" ), 1 );
260+ const auto occAll = bcOccAllIndexed[bc.globalBC ()];
261+ if (bc.numCollsInBC () == occAll.numCollsInBC () && bc.numCollsInRof () == occAll.numCollsInRof ()) {
262+ histos.fill (HIST (" BcOccsVsBcOccsAll/hCheck" ), 2 );
263+ }
264+ if (bc.occupancyFlags_bit (aod::bcocc::kUpcMode ) == occAll.occupancyFlags_bit (aod::bcocc::kUpcMode )) {
265+ histos.fill (HIST (" BcOccsVsBcOccsAll/hCheck" ), 3 );
266+ }
267+ if (bc.trackOccupancyInTimeRange () >= 0 && occAll.trackOccupancyInTimeRange () >= 0 ) {
268+ histos.fill (HIST (" BcOccsVsBcOccsAll/hCheck" ), 4 );
269+ if (bc.trackOccupancyInTimeRange () == occAll.trackOccupancyInTimeRange () && bc.ft0cOccupancyInTimeRange () == occAll.ft0cOccupancyInTimeRange () &&
270+ bc.occupancyMedianTime () == occAll.occupancyMedianTime () && bc.occupancyFlags () == occAll.occupancyFlags ()) {
271+ histos.fill (HIST (" BcOccsVsBcOccsAll/hCheck" ), 5 );
272+ }
273+ }
274+ }
275+ }
276+ PROCESS_SWITCH (BcOccupancyQaTask, processBcOccsVsBcOccsAll, " comparison of aod::BcOccs with aod::BcOccsAll for the BCs of aod::BCs (requires both tables)" , true );
179277};
180278
181279WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments