@@ -294,10 +294,10 @@ struct TableMaker {
294294 Configurable<bool > fConfigSaveElectronSample {" cfgSaveElectronSample" , false , " If true, only save electron sample" };
295295 } fConfigPostCalibTPC ;
296296
297- //
297+ //
298298 struct : ConfigurableGroup {
299- Configurable<bool > fConfigFT0CCumulant {" cfgFT0CCumulant" , false ,
300- " If true, compute RefFlow cumulants from FT0C amplitudes (requires FT0s subscription) " };
299+ Configurable<bool > fConfigFT0CCumulant {" cfgFT0CCumulant" , false , " If true, compute RefFlow cumulants from FT0C amplitudes (requires FT0s subscription) " };
300+ Configurable<std::string> fConfigQvecCalibPath { " cfgQvecCalibPath " , " Analysis/EventPlane/QVecCorrections " , " CCDB path for qvector calibration objects; used only to check availability per run " };
301301 } fConfigQvector ;
302302
303303 struct : ConfigurableGroup {
@@ -335,6 +335,7 @@ struct TableMaker {
335335
336336 bool fDoDetailedQA = false ; // Bool to set detailed QA true, if QA is set true
337337 int fCurrentRun ; // needed to detect if the run changed and trigger update of calibrations etc.
338+ bool fQvectCalibAvailable = false ; // Whether the Q-vector calibration is available for the current run
338339
339340 // maps used to store index info; NOTE: std::map are sorted in ascending order by default (needed for track to collision indices)
340341 std::map<uint32_t , uint32_t > fCollIndexMap ; // key: old collision index, value: skimmed collision index
@@ -480,7 +481,7 @@ struct TableMaker {
480481
481482 // Check whether we have to define barrel or muon histograms
482483 bool enableBarrelHistos = (context.mOptions .get <bool >(" processPPWithFilter" ) || context.mOptions .get <bool >(" processPPWithFilterBarrelOnly" ) || context.mOptions .get <bool >(" processPPBarrelOnly" ) ||
483- context.mOptions .get <bool >(" processPbPb" ) || context.mOptions .get <bool >(" processPbPbBarrelOnly" ) || context.mOptions .get <bool >(" processPbPbBarrelOnlyWithQvect " ) || context. mOptions . get < bool >( " processPbPbBarrelOnlyWithV0Bits" ) || context.mOptions .get <bool >(" processPbPbBarrelOnlyWithV0BitsNoTOF" )) ||
484+ context.mOptions .get <bool >(" processPbPb" ) || context.mOptions .get <bool >(" processPbPbBarrelOnly" ) || context.mOptions .get <bool >(" processPbPbBarrelOnlyWithV0Bits" ) || context.mOptions .get <bool >(" processPbPbBarrelOnlyWithV0BitsNoTOF" )) ||
484485 context.mOptions .get <bool >(" processPbPbWithFilterBarrelOnly" ) || context.mOptions .get <bool >(" processPPBarrelOnlyWithV0s" ) || context.mOptions .get <bool >(" processPbPbBarrelOnlyNoTOF" );
485486
486487 bool enableMuonHistos = (context.mOptions .get <bool >(" processPPWithFilter" ) || context.mOptions .get <bool >(" processPPWithFilterMuonOnly" ) || context.mOptions .get <bool >(" processPPWithFilterMuonMFT" ) || context.mOptions .get <bool >(" processPPMuonOnly" ) || context.mOptions .get <bool >(" processPPRealignedMuonOnly" ) || context.mOptions .get <bool >(" processPPMuonMFT" ) || context.mOptions .get <bool >(" processPPMuonMFTWithMultsExtra" ) ||
@@ -1190,38 +1191,39 @@ struct TableMaker {
11901191 eventInfo (collision.globalIndex ());
11911192
11921193 if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionQvectCentr) > 0 ) {
1193- qvecGroup.eventQvectorCentr (collision.qvecFT0ARe (), collision.qvecFT0AIm (), collision.qvecFT0CRe (), collision.qvecFT0CIm (), collision.qvecFT0MRe (), collision.qvecFT0MIm (), collision.qvecFV0ARe (), collision.qvecFV0AIm (), collision.qvecTPCposRe (), collision.qvecTPCposIm (), collision.qvecTPCnegRe (), collision.qvecTPCnegIm (),
1194- collision.sumAmplFT0A (), collision.sumAmplFT0C (), collision.sumAmplFT0M (), collision.sumAmplFV0A (), collision.nTrkTPCpos (), collision.nTrkTPCneg ());
1195- qvecGroup.eventQvectorCentrExtra (collision.qvecTPCallRe (), collision.qvecTPCallIm (), collision.nTrkTPCall ());
1196-
1197- if (fConfigQvector .fConfigFT0CCumulant ) {
1198- // FT0C cumulants for RefFlow and QvectorExtra
1199- float S11C = collision.sumAmplFT0C ();
1200- float S12C = 0 .f ;
1201- if constexpr (!std::is_same_v<std::decay_t <TFt0s>, std::nullptr_t >) {
1202- if (collision.has_foundFT0 ()) {
1203- auto ft0 = collision.foundFT0 ();
1204- for (auto amp : ft0.amplitudeC ()) {
1205- if (amp > 0 .f ) {
1206- S12C += amp * amp;
1194+ if (fQvectCalibAvailable ) {
1195+ qvecGroup.eventQvectorCentr (collision.qvecFT0ARe (), collision.qvecFT0AIm (), collision.qvecFT0CRe (), collision.qvecFT0CIm (), collision.qvecFT0MRe (), collision.qvecFT0MIm (), collision.qvecFV0ARe (), collision.qvecFV0AIm (), collision.qvecTPCposRe (), collision.qvecTPCposIm (), collision.qvecTPCnegRe (), collision.qvecTPCnegIm (),
1196+ collision.sumAmplFT0A (), collision.sumAmplFT0C (), collision.sumAmplFT0M (), collision.sumAmplFV0A (), collision.nTrkTPCpos (), collision.nTrkTPCneg ());
1197+ qvecGroup.eventQvectorCentrExtra (collision.qvecTPCallRe (), collision.qvecTPCallIm (), collision.nTrkTPCall ());
1198+
1199+ if (fConfigQvector .fConfigFT0CCumulant ) {
1200+ // FT0C cumulants for RefFlow and QvectorExtra
1201+ float S11C = collision.sumAmplFT0C ();
1202+ float S12C = 0 .f ;
1203+ if constexpr (!std::is_same_v<std::decay_t <TFt0s>, std::nullptr_t >) {
1204+ if (collision.has_foundFT0 ()) {
1205+ auto ft0 = collision.foundFT0 ();
1206+ for (auto amp : ft0.amplitudeC ()) {
1207+ if (amp > 0 .f ) {
1208+ S12C += amp * amp;
1209+ }
12071210 }
12081211 }
12091212 }
1213+ float S21C = S11C * S11C;
1214+ float M11REF = S21C - S12C;
1215+ std::complex <double > Q21C (collision.qvecFT0CRe () * S11C, collision.qvecFT0CIm () * S11C);
1216+ float CORR2REF = (std::norm (Q21C) - S12C) / M11REF;
1217+
1218+ if (std::isnan (M11REF) || std::isinf (M11REF) || std::isnan (CORR2REF) || std::isinf (CORR2REF)) {
1219+ M11REF = 0 .f ;
1220+ CORR2REF = 0 .f ;
1221+ }
1222+ qvecGroup.eventRefFlow (M11REF, -9999 , -9999 , CORR2REF, -9999 , -9999 , VarManager::fgValues[VarManager::kCentFT0C ]);
1223+ qvecGroup.eventQvectorExtra (-9999 , -9999 , -9999 , -9999 , S11C, S12C, -9999 , -9999 );
12101224 }
1211- float S21C = S11C * S11C;
1212- float M11REF = S21C - S12C;
1213- std::complex <double > Q21C (collision.qvecFT0CRe () * S11C, collision.qvecFT0CIm () * S11C);
1214- float CORR2REF = (std::norm (Q21C) - S12C) / M11REF;
1215-
1216- if (std::isnan (M11REF) || std::isinf (M11REF) || std::isnan (CORR2REF) || std::isinf (CORR2REF)) {
1217- M11REF = 0 .f ;
1218- CORR2REF = 0 .f ;
1219- }
1220- qvecGroup.eventRefFlow (M11REF, -9999 , -9999 , CORR2REF, -9999 , -9999 , VarManager::fgValues[VarManager::kCentFT0C ]);
1221- qvecGroup.eventQvectorExtra (-9999 , -9999 , -9999 , -9999 , S11C, S12C, -9999 , -9999 );
12221225 }
12231226 }
1224-
12251227 if constexpr ((TEventFillMap & VarManager::ObjTypes::Zdc) > 0 ) {
12261228 if constexpr ((TEventFillMap & VarManager::ObjTypes::RapidityGapFilter) > 0 ) {
12271229 // The DQRapidityGapFilter contains the index of the bc we want to get ZDC info from
@@ -1771,6 +1773,29 @@ struct TableMaker {
17711773 }
17721774 std::map<std::string, std::string> metadataRCT, header;
17731775 header = fCCDBApi .retrieveHeaders (Form (" RCT/Info/RunInformation/%i" , bcs.begin ().runNumber ()), metadataRCT, -1 );
1776+
1777+ // Check if qvector calibration objects are available in CCDB for this run
1778+ if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionQvectCentr) > 0 ) {
1779+ std::map<std::string, std::string> metadataQvect;
1780+ const std::array<std::string, 3 > subfolders = {" v2" , " v3" , " v4" };
1781+ bool anyFound = false ;
1782+ for (const auto & sub : subfolders) {
1783+ std::string fullPath = fConfigQvector .fConfigQvecCalibPath .value + " /" + sub;
1784+ auto headers = fCCDBApi .retrieveHeaders (fullPath, metadataQvect, bcs.begin ().timestamp ());
1785+ if (headers.empty ()) {
1786+ LOG (warn) << " Qvector calibration not found at CCDB path '" << fullPath
1787+ << " ' for run " << bcs.begin ().runNumber ();
1788+ } else {
1789+ anyFound = true ;
1790+ }
1791+ }
1792+ fQvectCalibAvailable = anyFound;
1793+ if (!fQvectCalibAvailable ) {
1794+ LOG (warn) << " No qvector calibration found in any subfolder under '"
1795+ << fConfigQvector .fConfigQvecCalibPath .value
1796+ << " ' — qvector tables will not be filled for this run." ;
1797+ }
1798+ }
17741799 uint64_t sor = std::atol (header[" SOR" ].c_str ());
17751800 uint64_t eor = std::atol (header[" EOR" ].c_str ());
17761801 VarManager::SetSORandEOR (sor, eor);
@@ -1946,43 +1971,33 @@ struct TableMaker {
19461971 }
19471972
19481973 // produce the full DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter
1949- void processPbPb (MyEventsWithCentAndMults const & collisions, MyBCs const & bcs,
1974+ void processPbPb (MyEventsWithCentAndMultsQvect const & collisions, MyBCs const & bcs,
19501975 MyBarrelTracksWithCov const & tracksBarrel,
19511976 MyMuonsWithCov const & muons, MFTTracks const & mftTracks,
19521977 TrackAssoc const & trackAssocs, FwdTrackAssoc const & fwdTrackAssocs,
1953- MFTTrackAssoc const & mftAssocs)
1978+ MFTTrackAssoc const & mftAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds )
19541979 {
1955- fullSkimming<gkEventFillMapWithCentAndMults , gkTrackFillMapWithCov, gkMuonFillMapWithCov, gkMFTFillMap>(collisions, bcs, nullptr , tracksBarrel, muons, mftTracks, trackAssocs, fwdTrackAssocs, mftAssocs, nullptr , nullptr , nullptr , nullptr );
1980+ fullSkimming<gkEventFillMapWithCentAndMultsQvect , gkTrackFillMapWithCov, gkMuonFillMapWithCov, gkMFTFillMap>(collisions, bcs, nullptr , tracksBarrel, muons, mftTracks, trackAssocs, fwdTrackAssocs, mftAssocs, nullptr , ft0s, fv0as, fdds );
19561981 }
19571982
19581983 // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter
1959- void processPbPbBarrelOnly (MyEventsWithCentAndMults const & collisions, MyBCs const & bcs,
1984+ void processPbPbBarrelOnly (MyEventsWithCentAndMultsQvect const & collisions, MyBCs const & bcs,
19601985 MyBarrelTracksWithCov const & tracksBarrel,
1961- TrackAssoc const & trackAssocs)
1986+ TrackAssoc const & trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds )
19621987 {
19631988 computeOccupancyEstimators (collisions, tracksPosWithCov, tracksNegWithCov, presliceWithCov, bcs);
19641989 computeCollMergingTag (collisions, tracksBarrel, presliceWithCov);
1965- fullSkimming<gkEventFillMapWithCentAndMults, gkTrackFillMapWithCov, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , nullptr , nullptr , nullptr );
1966- }
1967-
1968- // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter
1969- void processPbPbBarrelOnlyWithQvect (MyEventsWithCentAndMultsQvect const & collisions, MyBCs const & bcs,
1970- MyBarrelTracksWithCov const & tracksBarrel,
1971- TrackAssoc const & trackAssocs, aod::FT0s& ft0s)
1972- {
1973- computeOccupancyEstimators (collisions, tracksPosWithCov, tracksNegWithCov, presliceWithCov, bcs);
1974- computeCollMergingTag (collisions, tracksBarrel, presliceWithCov);
1975- fullSkimming<gkEventFillMapWithCentAndMultsQvect, gkTrackFillMapWithCov, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , ft0s, nullptr , nullptr );
1990+ fullSkimming<gkEventFillMapWithCentAndMultsQvect, gkTrackFillMapWithCov, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , ft0s, fv0as, fdds);
19761991 }
19771992
19781993 // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no TOF
1979- void processPbPbBarrelOnlyNoTOF (MyEventsWithCentAndMults const & collisions, MyBCs const & bcs,
1994+ void processPbPbBarrelOnlyNoTOF (MyEventsWithCentAndMultsQvect const & collisions, MyBCs const & bcs,
19801995 MyBarrelTracksWithCovNoTOF const & tracksBarrel,
1981- TrackAssoc const & trackAssocs)
1996+ TrackAssoc const & trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds )
19821997 {
19831998 computeOccupancyEstimators (collisions, tracksPosWithCovNoTOF, tracksNegWithCovNoTOF, presliceWithCovNoTOF, bcs);
19841999 computeCollMergingTag (collisions, tracksBarrel, presliceWithCovNoTOF);
1985- fullSkimming<gkEventFillMapWithCentAndMults , gkTrackFillMapNoTOF, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , nullptr , nullptr , nullptr );
2000+ fullSkimming<gkEventFillMapWithCentAndMultsQvect , gkTrackFillMapNoTOF, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , ft0s, fv0as, fdds );
19862001 }
19872002
19882003 // produce the barrel-only DQ skimmed data model typically for UPC Pb-Pb (no centrality), subscribe to the DQ rapidity gap event filter (filter-PbPb)
@@ -1996,23 +2011,23 @@ struct TableMaker {
19962011 }
19972012
19982013 // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter
1999- void processPbPbBarrelOnlyWithV0Bits (MyEventsWithCentAndMults const & collisions, MyBCs const & bcs,
2014+ void processPbPbBarrelOnlyWithV0Bits (MyEventsWithCentAndMultsQvect const & collisions, MyBCs const & bcs,
20002015 MyBarrelTracksWithV0Bits const & tracksBarrel,
2001- TrackAssoc const & trackAssocs)
2016+ TrackAssoc const & trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds )
20022017 {
20032018 computeOccupancyEstimators (collisions, tracksPos, tracksNeg, preslice, bcs);
20042019 computeCollMergingTag (collisions, tracksBarrel, preslice);
2005- fullSkimming<gkEventFillMapWithCentAndMults , gkTrackFillMapWithV0Bits, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , nullptr , nullptr , nullptr );
2020+ fullSkimming<gkEventFillMapWithCentAndMultsQvect , gkTrackFillMapWithV0Bits, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , ft0s, fv0as, fdds );
20062021 }
20072022
20082023 // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter
2009- void processPbPbBarrelOnlyWithV0BitsNoTOF (MyEventsWithCentAndMults const & collisions, MyBCs const & bcs,
2024+ void processPbPbBarrelOnlyWithV0BitsNoTOF (MyEventsWithCentAndMultsQvect const & collisions, MyBCs const & bcs,
20102025 MyBarrelTracksWithV0BitsNoTOF const & tracksBarrel,
2011- TrackAssoc const & trackAssocs)
2026+ TrackAssoc const & trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds )
20122027 {
20132028 computeOccupancyEstimators (collisions, tracksPosNoTOF, tracksNegNoTOF, presliceNoTOF, bcs);
20142029 computeCollMergingTag (collisions, tracksBarrel, presliceNoTOF);
2015- fullSkimming<gkEventFillMapWithCentAndMults , gkTrackFillMapWithV0BitsNoTOF, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , nullptr , nullptr , nullptr );
2030+ fullSkimming<gkEventFillMapWithCentAndMultsQvect , gkTrackFillMapWithV0BitsNoTOF, 0u , 0u >(collisions, bcs, nullptr , tracksBarrel, nullptr , nullptr , trackAssocs, nullptr , nullptr , nullptr , ft0s, fv0as, fdds );
20162031 }
20172032
20182033 // produce the muon only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter
@@ -2076,7 +2091,6 @@ struct TableMaker {
20762091 PROCESS_SWITCH (TableMaker, processPPMuonMFTWithMultsExtra, " Build muon + mft DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb" , false );
20772092 PROCESS_SWITCH (TableMaker, processPbPb, " Build full DQ skimmed data model typically for Pb-Pb, w/o event filtering" , false );
20782093 PROCESS_SWITCH (TableMaker, processPbPbBarrelOnly, " Build barrel only DQ skimmed data model typically for Pb-Pb, w/o event filtering" , false );
2079- PROCESS_SWITCH (TableMaker, processPbPbBarrelOnlyWithQvect, " Build barrel only DQ skimmed data model typically for Pb-Pb, w/o event filtering with event properties and flow" , false );
20802094 PROCESS_SWITCH (TableMaker, processPbPbBarrelOnlyNoTOF, " Build barrel only DQ skimmed data model typically for Pb-Pb, w/o event filtering, no TOF" , false );
20812095 PROCESS_SWITCH (TableMaker, processPbPbWithFilterBarrelOnly, " Build barrel only DQ skimmed data model typically for UPC Pb-Pb, w/ event filtering" , false );
20822096 PROCESS_SWITCH (TableMaker, processPbPbBarrelOnlyWithV0Bits, " Build barrel only DQ skimmed data model typically for Pb-Pb, w/ V0 bits, w/o event filtering" , false );
0 commit comments