1313// / \brief Compact forward-muon skim for offline MCH and MCH-MID efficiency studies
1414// / \author Nazar Burmasov (JINR)
1515
16+ #include " Common/CCDB/EventSelectionParams.h"
17+
1618#include < CCDB/BasicCCDBManager.h>
19+ #include < CommonConstants/LHCConstants.h>
20+ #include < DataFormatsFT0/Digit.h>
1721#include < DataFormatsParameters/AggregatedRunInfo.h>
22+ #include < DataFormatsParameters/GRPLHCIFData.h>
1823#include < DataFormatsParameters/GRPMagField.h>
1924#include < DetectorsBase/GeometryManager.h>
2025#include < DetectorsBase/Propagator.h>
2429#include < Framework/AnalysisTask.h>
2530#include < Framework/Configurable.h>
2631#include < Framework/DataTypes.h>
32+ #include < Framework/HistogramRegistry.h>
33+ #include < Framework/HistogramSpec.h>
2734#include < Framework/InitContext.h>
2835#include < Framework/Logger.h>
36+ #include < Framework/OutputObjHeader.h>
2937#include < Framework/runDataProcessing.h>
3038#include < GlobalTracking/MatchGlobalFwd.h>
3139#include < MCHTracking/TrackExtrap.h>
3442#include < Math/MatrixRepresentationsStatic.h>
3543#include < Math/SMatrix.h>
3644#include < TGeoManager.h>
45+ #include < TH1.h>
46+ #include < TH2.h>
3747
3848#include < array>
49+ #include < bitset>
3950#include < cstdint>
51+ #include < string>
4052#include < vector>
4153
4254using namespace o2 ;
@@ -98,16 +110,21 @@ struct MuonEfficiencyProducer {
98110 static constexpr float MaxEta = -2 .5f ;
99111 static constexpr float NoAmplitude = -1 .f;
100112 static constexpr float MaxFITTime = 30 .f;
113+ static constexpr int BCsPerOrbit = constants::lhc::LHCMaxBunches;
101114
102115 using Tracks = soa::Join<aod::FwdTracks, aod::FwdTracksCov>;
103116 using Matrix55 = ROOT ::Math::SMatrix<double , 5 , 5 , ROOT ::Math::MatRepSym<double , 5 >>;
104117 using Vector5 = ROOT ::Math::SVector<double , 5 >;
105118
106119 Produces<aod::MchEffBCs> outputBCs;
107120 Produces<aod::MchEffSkims> output;
121+ HistogramRegistry histos{" Histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
108122 Service<ccdb::BasicCCDBManager> ccdb{};
109123 globaltracking::MatchGlobalFwd matcher;
110- int cachedFieldRun = -1 ;
124+ bool conditionsInitialized = false ;
125+ std::bitset<BCsPerOrbit> collidingBCs;
126+ float zncBBLower = 0 .f;
127+ float zncBBUpper = 0 .f;
111128
112129 Configurable<float > minPt{" minPt" , 0 .4f , " Minimum track pT (Gev/c)" };
113130 Configurable<float > minRAbs{" minRAbs" , 17 .6f , " Minimum absorber-end radius (cm)" };
@@ -118,11 +135,19 @@ struct MuonEfficiencyProducer {
118135 void init (InitContext&)
119136 {
120137 ccdb->setLocalObjectValidityChecking ();
138+ const AxisSpec runAxis{1 , 0.5 , 1.5 , " Run" };
139+ const AxisSpec bcAxis{BCsPerOrbit, -0.5 , BCsPerOrbit - 0.5 , " BC in orbit" };
140+ histos.add (" hCounterTVX" , " TVX;Run;BC in orbit;Counts" , HistType::kTH2D , {runAxis, bcAxis});
141+ histos.add (" hCounterTCE" , " TCE;Run;BC in orbit;Counts" , HistType::kTH2D , {runAxis, bcAxis});
142+ histos.add (" hCounterZNC" , " ZNC;Run;BC in orbit;Counts" , HistType::kTH2D , {runAxis, bcAxis});
143+ histos.get <TH2 >(HIST (" hCounterTVX" ))->SetCanExtend (TH1 ::kXaxis );
144+ histos.get <TH2 >(HIST (" hCounterTCE" ))->SetCanExtend (TH1 ::kXaxis );
145+ histos.get <TH2 >(HIST (" hCounterZNC" ))->SetCanExtend (TH1 ::kXaxis );
121146 }
122147
123- void setField (int run)
148+ void initRunConditions (int run)
124149 {
125- if (cachedFieldRun == run ) {
150+ if (conditionsInitialized ) {
126151 return ;
127152 }
128153 const auto runInfo = parameters::AggregatedRunInfo::buildAggregatedRunInfo (ccdb->instance (), run);
@@ -136,7 +161,21 @@ struct MuonEfficiencyProducer {
136161 ccdb->get <TGeoManager>(" GLO/Config/GeometryAligned" );
137162 }
138163 mch::TrackExtrap::setField ();
139- cachedFieldRun = run;
164+ if (!runInfo.grpLHC ) {
165+ LOGF (fatal, " GRPLHCIFData not found for run %d" , run);
166+ }
167+ collidingBCs = runInfo.grpLHC ->getBunchFilling ().getBCPattern ();
168+ auto * params = ccdb->getForTimeStamp <EventSelectionParams>(" EventSelection/EventSelectionParams" , ts);
169+ if (!params) {
170+ LOGF (fatal, " EventSelectionParams not found for run %d" , run);
171+ }
172+ zncBBLower = params->fZNCBBlower ;
173+ zncBBUpper = params->fZNCBBupper ;
174+ const auto label = std::to_string (run);
175+ histos.get <TH2 >(HIST (" hCounterTVX" ))->GetXaxis ()->SetBinLabel (1 , label.c_str ());
176+ histos.get <TH2 >(HIST (" hCounterTCE" ))->GetXaxis ()->SetBinLabel (1 , label.c_str ());
177+ histos.get <TH2 >(HIST (" hCounterZNC" ))->GetXaxis ()->SetBinLabel (1 , label.c_str ());
178+ conditionsInitialized = true ;
140179 }
141180
142181 struct Kinematics {
@@ -165,19 +204,23 @@ struct MuonEfficiencyProducer {
165204 }
166205
167206 void process (aod::BCs const & bcs, aod::FT0s const & ft0s, aod::FV0As const & fv0as,
207+ aod::Zdcs const & zdcs,
168208 Tracks const & tracks, aod::Collisions const & collisions,
169209 aod::AmbiguousFwdTracks const & ambiguous)
170210 {
171211 if (bcs.size () == 0 ) {
172212 return ;
173213 }
174214 const int run = bcs.begin ().runNumber ();
175-
215+ initRunConditions (run);
216+ std::vector<uint8_t > ft0TriggersByBC (bcs.size (), 0 );
217+ std::vector<uint8_t > zncIsBBByBC (bcs.size (), 0 );
176218 std::vector<float > ft0aByBC (bcs.size (), NoAmplitude);
177219 std::vector<float > ft0cByBC (bcs.size (), NoAmplitude);
178220 std::vector<float > fv0aByBC (bcs.size (), NoAmplitude);
179221 std::vector<int32_t > skimBCIds (bcs.size (), -1 );
180222 for (const auto & ft0 : ft0s) {
223+ ft0TriggersByBC[ft0.bcId ()] |= ft0.triggerMask ();
181224 if (ft0.timeA () < MaxFITTime) {
182225 ft0aByBC[ft0.bcId ()] = ft0.sumAmpA ();
183226 }
@@ -198,6 +241,33 @@ struct MuonEfficiencyProducer {
198241 fv0aByBC[fv0.bcId ()] = amplitude;
199242 }
200243
244+ for (const auto & zdc : zdcs) {
245+ if (zdc.timeZNC () > zncBBLower && zdc.timeZNC () < zncBBUpper) {
246+ zncIsBBByBC[zdc.bcId ()] = 1 ;
247+ }
248+ }
249+
250+ auto hTVX = histos.get <TH2 >(HIST (" hCounterTVX" ));
251+ auto hTCE = histos.get <TH2 >(HIST (" hCounterTCE" ));
252+ auto hZNC = histos.get <TH2 >(HIST (" hCounterZNC" ));
253+ for (const auto & bc : bcs) {
254+ const auto slot = bc.globalBC () % BCsPerOrbit;
255+ if (!collidingBCs[slot]) {
256+ continue ;
257+ }
258+ const auto mask = ft0TriggersByBC[bc.globalIndex ()];
259+ const bool tvx = (mask & (1u << o2::ft0::Triggers::bitVertex)) != 0 ;
260+ if (tvx) {
261+ hTVX->Fill (1 ., static_cast <double >(slot));
262+ if ((mask & (1u << o2::ft0::Triggers::bitCen)) != 0 ) {
263+ hTCE->Fill (1 ., static_cast <double >(slot));
264+ }
265+ }
266+ if (zncIsBBByBC[bc.globalIndex ()] != 0u ) {
267+ hZNC->Fill (1 ., static_cast <double >(slot));
268+ }
269+ }
270+
201271 std::vector<int32_t > ambiguousBCIds (tracks.size (), -1 );
202272 for (const auto & entry : ambiguous) {
203273 const auto & ids = entry.bcIds ();
@@ -226,7 +296,6 @@ struct MuonEfficiencyProducer {
226296 vtxCov = {col.covXX (), col.covYY ()};
227297 referenceBCId = col.bcId ();
228298 }
229- setField (run);
230299 if (!propagateMCH (t, vtx, vtxCov, k)) {
231300 continue ;
232301 }
0 commit comments