1717// / \author Stefano Politanò <stefano.politano@cern.ch>, Politecnico & INFN Torino
1818// / \author Fabrizio Chinu <fabrizio.chinu@cern.ch>, Universita and INFN Torino
1919
20+ #include < memory>
21+ #include < unordered_map>
22+ #include < vector>
23+ #include < map>
24+ #include < string>
25+
26+ #include " CCDB/BasicCCDBManager.h"
2027#include " CommonConstants/PhysicsConstants.h"
2128#include " Framework/AnalysisTask.h"
2229#include " Framework/HistogramRegistry.h"
2330#include " Framework/runDataProcessing.h"
31+ #include " MetadataHelper.h"
2432
2533#include " PWGHF/Core/HfHelper.h"
2634#include " PWGHF/Core/CentralityEstimation.h"
@@ -32,6 +40,8 @@ using namespace o2::analysis;
3240using namespace o2 ::framework;
3341using namespace o2 ::framework::expressions;
3442
43+ MetadataHelper metadataInfo; // Metadata helper
44+
3545enum FinalState { KKPi = 0 ,
3646 PiKK };
3747
@@ -65,14 +75,23 @@ struct HfTaskDs {
6575 Configurable<float > massDsSignalMax{" massDsSignalMax" , 1.994 , " max mass for Ds signal" };
6676 Configurable<float > massDplusSignalMin{" massDplusSignalMin" , 1.866 , " min mass for Dplus signal" };
6777 Configurable<float > massDplusSignalMax{" massDplusSignalMax" , 1.906 , " max mass for Dplus signal" };
78+ Configurable<bool > fillPercentiles{" fillPercentiles" , true , " Wheter to fill multiplicity axis with percentiles or raw information" };
6879
6980 ConfigurableAxis axisPt{" axisPt" , {VARIABLE_WIDTH, 1 .f , 2 .f , 3 .f , 4 .f , 5 .f , 6 .f , 8 .f , 12 .f , 24 .f }, " axis for pT" };
7081 ConfigurableAxis axisNPvContributors{" axisNPvContributors" , {200 , -0 .5f , 199 .5f }, " axis for NPvContributors" };
7182 ConfigurableAxis axisMlScore0{" axisMlScore0" , {100 , 0 ., 1 .}, " axis for ML output score 0" };
7283 ConfigurableAxis axisMlScore1{" axisMlScore1" , {100 , 0 ., 1 .}, " axis for ML output score 1" };
7384 ConfigurableAxis axisMlScore2{" axisMlScore2" , {100 , 0 ., 1 .}, " axis for ML output score 2" };
85+ ConfigurableAxis axisCentrality{" axisCentrality" , {100 , 0 ., 1 .}, " axis for centrality/multiplicity" };
86+
87+ struct : ConfigurableGroup {
88+ Configurable<std::string> ccdburl{" ccdburl" , " http://alice-ccdb.cern.ch" , " The CCDB endpoint url address" };
89+ Configurable<std::string> ccdbPath{" ccdbpath" , " Centrality/Calibration" , " The CCDB path for centrality/multiplicity information" };
90+ Configurable<std::string> reconstructionPass{" reconstructionPass" , " " , {" Apass to use when fetching the calibration tables. Empty (default) does not check for any pass. Use `metadata` to fetch it from the AO2D metadata. Otherwise it will override the metadata." }};
91+ } ccdbConfig;
7492
7593 HfHelper hfHelper;
94+ Service<o2::ccdb::BasicCCDBManager> ccdb;
7695
7796 using TH1_ptr = std::shared_ptr<TH1>;
7897 using TH2_ptr = std::shared_ptr<TH2>;
@@ -81,14 +100,14 @@ struct HfTaskDs {
81100 template <typename CandDs>
82101 using MemberFunctionPointer = bool (HfTaskDs::*)(const CandDs&);
83102
84- using CollisionsWithFT0C = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Cs>;
85- using CollisionsWithFT0M = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Ms>;
86- using CollisionsWithNTracksPV = soa::Join<aod::Collisions, aod::EvSels, aod::CentNTPVs>;
103+ using CollisionsWithFT0C = soa::Join<aod::Collisions, aod::EvSels, aod::FT0Mults, aod:: CentFT0Cs>;
104+ using CollisionsWithFT0M = soa::Join<aod::Collisions, aod::EvSels, aod::FT0Mults, aod:: CentFT0Ms>;
105+ using CollisionsWithNTracksPV = soa::Join<aod::Collisions, aod::EvSels, aod::PVMults, aod:: CentNTPVs>;
87106
88107 using CollisionsMc = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels>;
89- using CollisionsMcWithFT0C = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::CentFT0Cs>;
90- using CollisionsMcWithFT0M = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::CentFT0Ms>;
91- using CollisionsMcWithNTracksPV = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::CentNTPVs>;
108+ using CollisionsMcWithFT0C = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::FT0Mults, aod:: CentFT0Cs>;
109+ using CollisionsMcWithFT0M = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::FT0Mults, aod:: CentFT0Ms>;
110+ using CollisionsMcWithNTracksPV = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::PVMults, aod:: CentNTPVs>;
92111
93112 using CandDsData = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDsToKKPi>>;
94113 using CandDsDataWithMl = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelDsToKKPi, aod::HfMlDsToKKPi>>;
@@ -101,6 +120,12 @@ struct HfTaskDs {
101120 SliceCache cache;
102121
103122 int offsetDplusDecayChannel = aod::hf_cand_3prong::DecayChannelDToKKPi::DplusToPhiPi - aod::hf_cand_3prong::DecayChannelDToKKPi::DsToPhiPi; // Offset between Dplus and Ds to use the same decay channel. See aod::hf_cand_3prong::DecayChannelDToKKPi
123+ int mRunNumber {0 };
124+ bool lCalibLoaded;
125+ TList* lCalibObjects;
126+ TProfile* hVtxZFT0A;
127+ TProfile* hVtxZFT0C;
128+ TProfile* hVtxZNTracks;
104129
105130 Filter filterDsFlag = (o2::aod::hf_track_index::hfflag & static_cast <uint8_t >(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi))) != static_cast <uint8_t >(0 );
106131
@@ -252,13 +277,63 @@ struct HfTaskDs {
252277 return true ;
253278 }
254279
280+ // / Evaluate centrality/multiplicity percentile using FT0M estimator
281+ // / \param candidate is candidate
282+ // / \return centrality/multiplicity percentile of the collision
283+ template <o2::hf_centrality::hasFT0MCent Coll>
284+ float getZEqMultColl (const Coll& collision, uint8_t nProngsContributorsPV)
285+ {
286+ auto multFT0A = collision.multFT0A () - nProngsContributorsPV;
287+ auto multFT0C = collision.multFT0C () - nProngsContributorsPV;
288+ float multZeqFT0A = hVtxZFT0A->Interpolate (0.0 ) * multFT0A / hVtxZFT0A->Interpolate (collision.posZ ());
289+ float multZeqFT0C = hVtxZFT0C->Interpolate (0.0 ) * multFT0C / hVtxZFT0C->Interpolate (collision.posZ ());
290+ return multZeqFT0A + multZeqFT0C;
291+ }
292+
293+ // / Evaluate centrality/multiplicity percentile using NTracksPV estimator
294+ // / \param candidate is candidate
295+ // / \return centrality/multiplicity percentile of the collision
296+ template <o2::hf_centrality::hasNTracksPVCent Coll>
297+ float getZEqMultColl (const Coll& collision, uint8_t nProngsContributorsPV)
298+ {
299+ auto multNTracksPV = collision.multNTracksPV () - nProngsContributorsPV;
300+ float multZeqNTracksPV = hVtxZNTracks->Interpolate (0.0 ) * multNTracksPV / hVtxZNTracks->Interpolate (collision.posZ ());
301+ return multZeqNTracksPV;
302+ }
303+
304+ // / Default case if no centrality/multiplicity estimator is provided
305+ // / \param candidate is candidate
306+ // / \return dummy value for centrality/multiplicity percentile of the collision
307+ template <typename Coll>
308+ float getZEqMultColl (const Coll&, uint8_t )
309+ {
310+ return -1 .f ;
311+ }
312+
313+ // / Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table)
314+ // / \param candidate is candidate
315+ // / \return centrality/multiplicity percentile of the collision
316+ template <typename Coll, typename CandDs>
317+ float evaluateCentralityColl (const Coll& collision, const CandDs& candidate)
318+ {
319+ if (fillPercentiles) {
320+ return o2::hf_centrality::getCentralityColl<Coll>(collision);
321+ } else {
322+ return getZEqMultColl<Coll>(collision, candidate.nProngsContributorsPV ());
323+ }
324+ }
325+
255326 // / Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table)
256327 // / \param candidate is candidate
257328 // / \return centrality/multiplicity percentile of the collision
258329 template <typename Coll>
259330 float evaluateCentralityColl (const Coll& collision)
260331 {
261- return o2::hf_centrality::getCentralityColl<Coll>(collision);
332+ if (fillPercentiles) {
333+ return o2::hf_centrality::getCentralityColl<Coll>(collision);
334+ } else {
335+ return getZEqMultColl<Coll>(collision, 0 );
336+ }
262337 }
263338
264339 // / Evaluate centrality/multiplicity percentile
@@ -267,7 +342,7 @@ struct HfTaskDs {
267342 template <typename Coll, typename T1>
268343 float evaluateCentralityCand (const T1& candidate)
269344 {
270- return evaluateCentralityColl (candidate.template collision_as <Coll>());
345+ return evaluateCentralityColl (candidate.template collision_as <Coll>(), candidate );
271346 }
272347
273348 // / Fill histograms of quantities independent from the daugther-mass hypothesis
@@ -583,6 +658,41 @@ struct HfTaskDs {
583658 void runDataAnalysisPerCollision (const Coll& collisions, const CandsDs& candsDs)
584659 {
585660 for (const auto & collision : collisions) {
661+ /* check the previous run number */
662+ const auto & bc = collision.bc ();
663+ if (bc.runNumber () != mRunNumber ) {
664+ mRunNumber = bc.runNumber (); // mark this run as at least tried
665+ if (ccdbConfig.reconstructionPass .value == " " ) {
666+ lCalibObjects = ccdb->getForRun <TList>(ccdbConfig.ccdbPath , mRunNumber );
667+ } else if (ccdbConfig.reconstructionPass .value == " metadata" ) {
668+ std::map<std::string, std::string> metadata;
669+ metadata[" RecoPassName" ] = metadataInfo.get (" RecoPassName" );
670+ LOGF (info, " Loading CCDB for reconstruction pass (from metadata): %s" , metadataInfo.get (" RecoPassName" ));
671+ lCalibObjects = ccdb->getSpecificForRun <TList>(ccdbConfig.ccdbPath , mRunNumber , metadata);
672+ } else {
673+ std::map<std::string, std::string> metadata;
674+ metadata[" RecoPassName" ] = ccdbConfig.reconstructionPass .value ;
675+ LOGF (info, " Loading CCDB for reconstruction pass (from provided argument): %s" , ccdbConfig.reconstructionPass .value );
676+ lCalibObjects = ccdb->getSpecificForRun <TList>(ccdbConfig.ccdbPath , mRunNumber , metadata);
677+ }
678+
679+ if (lCalibObjects) {
680+ LOG (info) << " CCDB objects loaded successfully" ;
681+ hVtxZFT0A = static_cast <TProfile*>(lCalibObjects->FindObject (" hVtxZFT0A" ));
682+ hVtxZFT0C = static_cast <TProfile*>(lCalibObjects->FindObject (" hVtxZFT0C" ));
683+ hVtxZNTracks = static_cast <TProfile*>(lCalibObjects->FindObject (" hVtxZNTracksPV" ));
684+ lCalibLoaded = true ;
685+ // Capture error
686+ if (!hVtxZFT0A || !hVtxZFT0C || !hVtxZNTracks) {
687+ LOGF (error, " Problem loading CCDB objects! Please check" );
688+ lCalibLoaded = false ;
689+ }
690+ } else {
691+ LOGF (error, " Problem loading CCDB object! Please check" );
692+ lCalibLoaded = false ;
693+ }
694+ }
695+
586696 auto thisCollId = collision.globalIndex ();
587697 std::array<int , DataType::kDataTypes > nCandsPerType{0 };
588698 std::array<int , DataType::kDataTypes > nCandsInSignalRegionDsPerType{0 };
@@ -613,6 +723,41 @@ struct HfTaskDs {
613723 const CandDsMcGen& mcParticles)
614724 {
615725 for (const auto & collision : collisions) {
726+ /* check the previous run number */
727+ const auto & bc = collision.bc ();
728+ if (bc.runNumber () != mRunNumber ) {
729+ mRunNumber = bc.runNumber (); // mark this run as at least tried
730+ if (ccdbConfig.reconstructionPass .value == " " ) {
731+ lCalibObjects = ccdb->getForRun <TList>(ccdbConfig.ccdbPath , mRunNumber );
732+ } else if (ccdbConfig.reconstructionPass .value == " metadata" ) {
733+ std::map<std::string, std::string> metadata;
734+ metadata[" RecoPassName" ] = metadataInfo.get (" RecoPassName" );
735+ LOGF (info, " Loading CCDB for reconstruction pass (from metadata): %s" , metadataInfo.get (" RecoPassName" ));
736+ lCalibObjects = ccdb->getSpecificForRun <TList>(ccdbConfig.ccdbPath , mRunNumber , metadata);
737+ } else {
738+ std::map<std::string, std::string> metadata;
739+ metadata[" RecoPassName" ] = ccdbConfig.reconstructionPass .value ;
740+ LOGF (info, " Loading CCDB for reconstruction pass (from provided argument): %s" , ccdbConfig.reconstructionPass .value );
741+ lCalibObjects = ccdb->getSpecificForRun <TList>(ccdbConfig.ccdbPath , mRunNumber , metadata);
742+ }
743+
744+ if (lCalibObjects) {
745+ LOG (info) << " CCDB objects loaded successfully" ;
746+ hVtxZFT0A = static_cast <TProfile*>(lCalibObjects->FindObject (" hVtxZFT0A" ));
747+ hVtxZFT0C = static_cast <TProfile*>(lCalibObjects->FindObject (" hVtxZFT0C" ));
748+ hVtxZNTracks = static_cast <TProfile*>(lCalibObjects->FindObject (" hVtxZNTracksPV" ));
749+ lCalibLoaded = true ;
750+ // Capture error
751+ if (!hVtxZFT0A || !hVtxZFT0C || !hVtxZNTracks) {
752+ LOGF (error, " Problem loading CCDB objects! Please check" );
753+ lCalibLoaded = false ;
754+ }
755+ } else {
756+ LOGF (error, " Problem loading CCDB object! Please check" );
757+ lCalibLoaded = false ;
758+ }
759+ }
760+
616761 auto thisCollId = collision.globalIndex ();
617762 std::array<int , DataType::kDataTypes > nCandsPerType{0 };
618763 std::array<int , DataType::kDataTypes > nCandsInSignalRegionDsPerType{0 };
@@ -669,6 +814,7 @@ struct HfTaskDs {
669814
670815 void processDataWithCentFT0C (CollisionsWithFT0C const & collisions,
671816 CandDsData const & candsDs,
817+ aod::BCs const &,
672818 aod::Tracks const &)
673819 {
674820 runDataAnalysisPerCollision (collisions, candsDs);
@@ -677,6 +823,7 @@ struct HfTaskDs {
677823
678824 void processDataWithCentFT0M (CollisionsWithFT0M const & collisions,
679825 CandDsData const & candsDs,
826+ aod::BCs const &,
680827 aod::Tracks const &)
681828 {
682829 runDataAnalysisPerCollision (collisions, candsDs);
@@ -685,6 +832,7 @@ struct HfTaskDs {
685832
686833 void processDataWithCentNTracksPV (CollisionsWithNTracksPV const & collisions,
687834 CandDsData const & candsDs,
835+ aod::BCs const &,
688836 aod::Tracks const &)
689837 {
690838 runDataAnalysisPerCollision (collisions, candsDs);
@@ -693,6 +841,7 @@ struct HfTaskDs {
693841
694842 void processData (soa::Join<aod::Collisions, aod::EvSels> const & collisions,
695843 CandDsData const & candsDs,
844+ aod::BCs const &,
696845 aod::Tracks const &)
697846 {
698847 runDataAnalysisPerCollision (collisions, candsDs);
@@ -701,6 +850,7 @@ struct HfTaskDs {
701850
702851 void processDataWithMlAndCentFT0C (CollisionsWithFT0C const & collisions,
703852 CandDsDataWithMl const & candsDs,
853+ aod::BCs const &,
704854 aod::Tracks const &)
705855 {
706856 runDataAnalysisPerCollision (collisions, candsDs);
@@ -709,6 +859,7 @@ struct HfTaskDs {
709859
710860 void processDataWithMlAndCentFT0M (CollisionsWithFT0M const & collisions,
711861 CandDsDataWithMl const & candsDs,
862+ aod::BCs const &,
712863 aod::Tracks const &)
713864 {
714865 runDataAnalysisPerCollision (collisions, candsDs);
@@ -717,6 +868,7 @@ struct HfTaskDs {
717868
718869 void processDataWithMlAndCentNTracksPV (CollisionsWithNTracksPV const & collisions,
719870 CandDsDataWithMl const & candsDs,
871+ aod::BCs const &,
720872 aod::Tracks const &)
721873 {
722874 runDataAnalysisPerCollision (collisions, candsDs);
@@ -725,6 +877,7 @@ struct HfTaskDs {
725877
726878 void processDataWithMl (soa::Join<aod::Collisions, aod::EvSels> const & collisions,
727879 CandDsDataWithMl const & candsDs,
880+ aod::BCs const &,
728881 aod::Tracks const &)
729882 {
730883 runDataAnalysisPerCollision (collisions, candsDs);
@@ -734,6 +887,7 @@ struct HfTaskDs {
734887 void processMcWithCentFT0C (CollisionsMcWithFT0C const & collisions,
735888 CandDsMcReco const & candsDs,
736889 CandDsMcGen const & mcParticles,
890+ aod::BCs const &,
737891 aod::McCollisions const &,
738892 aod::TracksWMc const &)
739893 {
@@ -744,6 +898,7 @@ struct HfTaskDs {
744898 void processMcWithCentFT0M (CollisionsMcWithFT0M const & collisions,
745899 CandDsMcReco const & candsDs,
746900 CandDsMcGen const & mcParticles,
901+ aod::BCs const &,
747902 aod::McCollisions const &,
748903 aod::TracksWMc const &)
749904 {
@@ -754,6 +909,7 @@ struct HfTaskDs {
754909 void processMcWithCentNTracksPV (CollisionsMcWithNTracksPV const & collisions,
755910 CandDsMcReco const & candsDs,
756911 CandDsMcGen const & mcParticles,
912+ aod::BCs const &,
757913 aod::McCollisions const &,
758914 aod::TracksWMc const &)
759915 {
@@ -764,6 +920,7 @@ struct HfTaskDs {
764920 void processMc (CollisionsMc const & collisions,
765921 CandDsMcReco const & candsDs,
766922 CandDsMcGen const & mcParticles,
923+ aod::BCs const &,
767924 aod::McCollisions const &,
768925 aod::TracksWMc const &)
769926 {
@@ -774,6 +931,7 @@ struct HfTaskDs {
774931 void processMcWithMlAndCentFT0C (CollisionsMcWithFT0C const & collisions,
775932 CandDsMcRecoWithMl const & candsDs,
776933 CandDsMcGen const & mcParticles,
934+ aod::BCs const &,
777935 aod::McCollisions const &,
778936 aod::TracksWMc const &)
779937 {
@@ -784,6 +942,7 @@ struct HfTaskDs {
784942 void processMcWithMlAndCentFT0M (CollisionsMcWithFT0M const & collisions,
785943 CandDsMcRecoWithMl const & candsDs,
786944 CandDsMcGen const & mcParticles,
945+ aod::BCs const &,
787946 aod::McCollisions const &,
788947 aod::TracksWMc const &)
789948 {
@@ -794,6 +953,7 @@ struct HfTaskDs {
794953 void processMcWithMlAndCentNTracksPV (CollisionsMcWithNTracksPV const & collisions,
795954 CandDsMcRecoWithMl const & candsDs,
796955 CandDsMcGen const & mcParticles,
956+ aod::BCs const &,
797957 aod::McCollisions const &,
798958 aod::TracksWMc const &)
799959 {
@@ -804,6 +964,7 @@ struct HfTaskDs {
804964 void processMcWithMl (CollisionsMc const & collisions,
805965 CandDsMcRecoWithMl const & candsDs,
806966 CandDsMcGen const & mcParticles,
967+ aod::BCs const &,
807968 aod::McCollisions const &,
808969 aod::TracksWMc const &)
809970 {
@@ -814,5 +975,7 @@ struct HfTaskDs {
814975
815976WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
816977{
978+ // Parse the metadata
979+ metadataInfo.initMetadata (cfgc);
817980 return WorkflowSpec{adaptAnalysisTask<HfTaskDs>(cfgc)};
818981}
0 commit comments