88// In applying this license CERN does not waive the privileges and immunities
99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
11+ //
12+ // / \file SGCandProducer.cxx
13+ // / \brief Produces PWGUD derived table from standard tables
14+ // /
15+ // / \author Alexander Bylinkin <roman.lavicka@cern.ch>, Uniersity of Bergen
16+ // / \since 23.11.2023
17+ //
1118
1219#include < cmath>
1320#include < vector>
2128#include " DataFormatsFIT/Triggers.h"
2229#include " DataFormatsParameters/GRPMagField.h"
2330#include " DataFormatsParameters/GRPObject.h"
31+ #include " DataFormatsParameters/GRPLHCIFData.h"
32+ #include " DataFormatsParameters/AggregatedRunInfo.h"
2433
2534#include " Framework/AnalysisTask.h"
2635#include " Framework/ASoAHelpers.h"
@@ -74,6 +83,7 @@ struct SGCandProducer {
7483 // Configurables to decide which tables are filled
7584 Configurable<bool > fillTrackTables{" fillTrackTables" , true , " Fill track tables" };
7685 Configurable<bool > fillFwdTrackTables{" fillFwdTrackTables" , true , " Fill forward track tables" };
86+
7787 // SG selector
7888 SGSelector sgSelector;
7989 ctpRateFetcher mRateFetcher ;
@@ -103,6 +113,8 @@ struct SGCandProducer {
103113 {}};
104114 std::map<std::string, HistPtr> histPointers;
105115
116+ int runNumber = -1 ;
117+
106118 // function to update UDFwdTracks, UDFwdTracksExtra
107119 template <typename TFwdTrack>
108120 void updateUDFwdTrackTables (TFwdTrack const & fwdtrack, uint64_t const & bcnum)
@@ -180,6 +192,78 @@ struct SGCandProducer {
180192 outputTracksLabel (track.globalIndex ());
181193 }
182194
195+ // function to process trigger counters, accounting for BC selection bits
196+ void processCountersTrg (BCs const & bcs, aod::FT0s const &, aod::Zdcs const &)
197+ {
198+ const auto & firstBc = bcs.iteratorAt (0 );
199+ if (runNumber != firstBc.runNumber ())
200+ runNumber = firstBc.runNumber ();
201+
202+ auto hCountersTrg = getHist (TH1, " reco/hCountersTrg" );
203+ auto hCountersTrgBcSel = getHist (TH1, " reco/hCountersTrgBcSel" );
204+ auto hLumi = getHist (TH1, " reco/hLumi" );
205+ auto hLumiBcSel = getHist (TH1, " reco/hLumiBcSel" );
206+
207+ // Cross sections in ub. Using dummy -1 if lumi estimator is not reliable
208+ float csTCE = 10.36e6 ;
209+ float csZEM = 415.2e6 ; // see AN: https://alice-notes.web.cern.ch/node/1515
210+ float csZNC = 214.5e6 ; // see AN: https://alice-notes.web.cern.ch/node/1515
211+ if (runNumber > 543437 && runNumber < 543514 ) {
212+ csTCE = 8.3e6 ;
213+ }
214+ if (runNumber >= 543514 ) {
215+ csTCE = 4.10e6 ; // see AN: https://alice-notes.web.cern.ch/node/1515
216+ }
217+
218+ for (const auto & bc : bcs) {
219+ bool hasFT0 = bc.has_foundFT0 ();
220+ bool hasZDC = bc.has_foundZDC ();
221+ if (!hasFT0 && !hasZDC)
222+ continue ;
223+ bool isSelectedBc = true ;
224+ if (rejectAtTFBoundary && !bc.selection_bit (aod::evsel::kNoTimeFrameBorder ))
225+ isSelectedBc = false ;
226+ if (noITSROFrameBorder && !bc.selection_bit (aod::evsel::kNoITSROFrameBorder ))
227+ isSelectedBc = false ;
228+ if (hasFT0) {
229+ auto ft0TrgMask = bc.ft0 ().triggerMask ();
230+ if (TESTBIT (ft0TrgMask, o2::fit::Triggers::bitVertex)) {
231+ hCountersTrg->Fill (" TVX" , 1 );
232+ if (isSelectedBc)
233+ hCountersTrgBcSel->Fill (" TVX" , 1 );
234+ }
235+ if (TESTBIT (ft0TrgMask, o2::fit::Triggers::bitVertex) && TESTBIT (ft0TrgMask, o2::fit::Triggers::bitCen)) {
236+ hCountersTrg->Fill (" TCE" , 1 );
237+ hLumi->Fill (" TCE" , 1 . / csTCE);
238+ if (isSelectedBc) {
239+ hCountersTrgBcSel->Fill (" TCE" , 1 );
240+ hLumiBcSel->Fill (" TCE" , 1 . / csTCE);
241+ }
242+ }
243+ }
244+ if (hasZDC) {
245+ if (bc.selection_bit (aod::evsel::kIsBBZNA ) || bc.selection_bit (aod::evsel::kIsBBZNC )) {
246+ hCountersTrg->Fill (" ZEM" , 1 );
247+ hLumi->Fill (" ZEM" , 1 . / csZEM);
248+ if (isSelectedBc) {
249+ hCountersTrgBcSel->Fill (" ZEM" , 1 );
250+ hLumiBcSel->Fill (" ZEM" , 1 . / csZEM);
251+ }
252+ }
253+ if (bc.selection_bit (aod::evsel::kIsBBZNC )) {
254+ hCountersTrg->Fill (" ZNC" , 1 );
255+ hLumi->Fill (" ZNC" , 1 . / csZNC);
256+ if (isSelectedBc) {
257+ hCountersTrgBcSel->Fill (" ZNC" , 1 );
258+ hLumiBcSel->Fill (" ZNC" , 1 . / csZNC);
259+ }
260+ }
261+ }
262+ }
263+ }
264+
265+ PROCESS_SWITCH (SGCandProducer, processCountersTrg, " Produce trigger counters and luminosity histograms" , true );
266+
183267 // function to process reconstructed data
184268 template <typename TCol>
185269 void processReco (std::string histdir, TCol const & collision, BCs const & bcs,
@@ -289,7 +373,7 @@ struct SGCandProducer {
289373 }
290374 // update SGTracks tables
291375 if (fillTrackTables) {
292- for (auto & track : tracks) {
376+ for (const auto & track : tracks) {
293377 if (track.pt () > sameCuts.minPt () && track.eta () > sameCuts.minEta () && track.eta () < sameCuts.maxEta ()) {
294378 if (track.isPVContributor ()) {
295379 updateUDTrackTables (outputCollisions.lastIndex (), track, bc.globalBC ());
@@ -304,7 +388,7 @@ struct SGCandProducer {
304388 // update SGFwdTracks tables
305389 if (fillFwdTrackTables) {
306390 if (sameCuts.withFwdTracks ()) {
307- for (auto & fwdtrack : fwdtracks) {
391+ for (const auto & fwdtrack : fwdtracks) {
308392 if (!sgSelector.FwdTrkSelector (fwdtrack))
309393 updateUDFwdTrackTables (fwdtrack, bc.globalBC ());
310394 }
@@ -324,6 +408,22 @@ struct SGCandProducer {
324408 histPointers.clear ();
325409 if (context.mOptions .get <bool >(" processData" )) {
326410 histPointers.insert ({" reco/Stat" , registry.add (" reco/Stat" , " Cut statistics; Selection criterion; Collisions" , {HistType::kTH1F , {{14 , -0.5 , 13.5 }}})});
411+
412+ const AxisSpec axisCountersTrg{10 , 0.5 , 10.5 , " " };
413+ histPointers.insert ({" reco/hCountersTrg" , registry.add (" reco/hCountersTrg" , " Trigger counts before selections; Trigger; Counts" , {HistType::kTH1F , {axisCountersTrg}})});
414+ histPointers.insert ({" reco/hCountersTrgBcSel" , registry.add (" reco/hCountersTrgSel" , " Trigger counts after BC selections; Trigger; Counts" , {HistType::kTH1F , {axisCountersTrg}})});
415+ histPointers.insert ({" reco/hLumi" , registry.add (" reco/hLumi" , " Integrated luminosity before selections; Trigger; Luminosity, 1/#mub" , {HistType::kTH1F , {axisCountersTrg}})});
416+ histPointers.insert ({" reco/hLumiBcSel" , registry.add (" reco/hLumiBcSel" , " Integrated luminosity before selections; Trigger; Luminosity, 1/#mub" , {HistType::kTH1F , {axisCountersTrg}})});
417+ auto hCountersTrg = getHist (TH1, " reco/hCountersTrg" );
418+ auto hCountersTrgBcSel = getHist (TH1, " reco/hCountersTrgBcSel" );
419+ auto hLumi = getHist (TH1, " reco/hLumi" );
420+ auto hLumiBcSel = getHist (TH1, " reco/hLumiBcSel" );
421+ for (const auto & h : {hCountersTrg, hCountersTrgBcSel, hLumi, hLumiBcSel}) {
422+ h->GetXaxis ()->SetBinLabel (1 , " TVX" );
423+ h->GetXaxis ()->SetBinLabel (2 , " TCE" );
424+ h->GetXaxis ()->SetBinLabel (3 , " ZEM" );
425+ h->GetXaxis ()->SetBinLabel (4 , " ZNC" );
426+ }
327427 }
328428 if (context.mOptions .get <bool >(" processMcData" )) {
329429 histPointers.insert ({" MCreco/Stat" , registry.add (" MCreco/Stat" , " Cut statistics; Selection criterion; Collisions" , {HistType::kTH1F , {{14 , -0.5 , 13.5 }}})});
@@ -441,7 +541,7 @@ struct McSGCandProducer {
441541 // This is needed to be able to assign the new daughter indices
442542 std::map<int64_t , int64_t > oldnew;
443543 auto lastId = outputMcParticles.lastIndex ();
444- for (auto mcpart : McParts) {
544+ for (const auto & mcpart : McParts) {
445545 auto oldId = mcpart.globalIndex ();
446546 if (mcPartIsSaved.find (oldId) != mcPartIsSaved.end ()) {
447547 oldnew[oldId] = mcPartIsSaved[oldId];
@@ -452,12 +552,12 @@ struct McSGCandProducer {
452552 }
453553
454554 // all particles of the McCollision are saved
455- for (auto mcpart : McParts) {
555+ for (const auto & mcpart : McParts) {
456556 if (mcPartIsSaved.find (mcpart.globalIndex ()) == mcPartIsSaved.end ()) {
457557 // mothers
458558 newmids.clear ();
459559 auto oldmids = mcpart.mothersIds ();
460- for (auto oldmid : oldmids) {
560+ for (const auto & oldmid : oldmids) {
461561 auto m = McParts.rawIteratorAt (oldmid);
462562 if (verboseInfoMC)
463563 LOGF (debug, " m %d" , m.globalIndex ());
@@ -524,7 +624,7 @@ struct McSGCandProducer {
524624 void updateUDMcTrackLabels (TTrack const & udtracks, std::map<int64_t , int64_t >& mcPartIsSaved)
525625 {
526626 // loop over all tracks
527- for (auto udtrack : udtracks) {
627+ for (const auto & udtrack : udtracks) {
528628 // udtrack (UDTCs) -> track (TCs) -> mcTrack (McParticles) -> udMcTrack (UDMcParticles)
529629 auto trackId = udtrack.trackId ();
530630 if (trackId >= 0 ) {
@@ -634,7 +734,7 @@ struct McSGCandProducer {
634734
635735 // update UDMcParticles and UDMcTrackLabels (for each UDTrack -> UDMcParticles)
636736 // loop over tracks of dgcand
637- for (auto sgtrack : sgTracks) {
737+ for (const auto & sgtrack : sgTracks) {
638738 if (sgtrack.has_track ()) {
639739 auto track = sgtrack.track_as <TCs>();
640740 if (track.has_mcParticle ()) {
0 commit comments