diff --git a/Analysis/Core/include/Analysis/VarManager.h b/Analysis/Core/include/Analysis/VarManager.h index ebe8127dec4c7..10681af192486 100644 --- a/Analysis/Core/include/Analysis/VarManager.h +++ b/Analysis/Core/include/Analysis/VarManager.h @@ -59,6 +59,12 @@ class VarManager : public TObject Pair = BIT(11) }; + enum PairCandidateType { + kJpsiToEE, // J/psi -> e+ e- + kJpsiToMuMu, // J/psi -> mu+ mu- + kNMaxCandidateTypes + }; + public: enum Variables { kNothing = -1, @@ -209,13 +215,21 @@ class VarManager : public TObject } static void SetRunNumbers(int n, int* runs); + static int GetNRuns() + { + return fgRunMap.size(); + } + static TString GetRunStr() + { + return fgRunStr; + } template static void FillEvent(T const& event, float* values = nullptr); template static void FillTrack(T const& track, float* values = nullptr); template - static void FillPair(T const& t1, T const& t2, float* values = nullptr); + static void FillPair(T const& t1, T const& t2, float* values = nullptr, PairCandidateType pairType = kJpsiToEE); template static void FillDileptonHadron(T1 const& dilepton, T2 const& hadron, float* values = nullptr, float hadronMass = 0.0f); @@ -231,6 +245,7 @@ class VarManager : public TObject static void SetVariableDependencies(); // toggle those variables on which other used variables might depend static std::map fgRunMap; // map of runs to be used in histogram axes + static TString fgRunStr; // semi-colon separated list of runs, to be used for histogram axis labels static void FillEventDerived(float* values = nullptr); static void FillTrackDerived(float* values = nullptr); @@ -454,32 +469,21 @@ void VarManager::FillTrack(T const& track, float* values) } template -void VarManager::FillPair(T const& t1, T const& t2, float* values) +void VarManager::FillPair(T const& t1, T const& t2, float* values, PairCandidateType pairType) { if (!values) { values = fgValues; } - float mass1 = fgkElectronMass; - float mass2 = fgkElectronMass; - - bool isMuon1 = t1.filteringFlags() & (1 << 0); - bool isMuon2 = t2.filteringFlags() & (1 << 0); - - if (isMuon1) { - mass1 = fgkMuonMass; - } else { - mass1 = fgkElectronMass; - } - - if (isMuon2) { - mass2 = fgkMuonMass; - } else { - mass2 = fgkElectronMass; + float m1 = fgkElectronMass; + float m2 = fgkElectronMass; + if (pairType == kJpsiToMuMu) { + m1 = fgkMuonMass; + m2 = fgkMuonMass; } - ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), mass1); - ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), mass2); + ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), m1); + ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), m2); ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; values[kMass] = v12.M(); values[kPt] = v12.Pt(); diff --git a/Analysis/Core/src/VarManager.cxx b/Analysis/Core/src/VarManager.cxx index 211e3a33fb6de..31e20f0e91104 100644 --- a/Analysis/Core/src/VarManager.cxx +++ b/Analysis/Core/src/VarManager.cxx @@ -19,6 +19,7 @@ TString VarManager::fgVariableUnits[VarManager::kNVars] = {""}; bool VarManager::fgUsedVars[VarManager::kNVars] = {kFALSE}; float VarManager::fgValues[VarManager::kNVars] = {0.0}; std::map VarManager::fgRunMap; +TString VarManager::fgRunStr = ""; //__________________________________________________________________ VarManager::VarManager() : TObject() @@ -66,6 +67,7 @@ void VarManager::SetRunNumbers(int n, int* runs) // for (int i = 0; i < n; ++i) { fgRunMap[runs[i]] = i + 1; + fgRunStr += Form("%d;", runs[i]); } } diff --git a/Analysis/DataModel/include/Analysis/ReducedInfoTables.h b/Analysis/DataModel/include/Analysis/ReducedInfoTables.h index 2bb1e7d4f617d..cd047877470c2 100644 --- a/Analysis/DataModel/include/Analysis/ReducedInfoTables.h +++ b/Analysis/DataModel/include/Analysis/ReducedInfoTables.h @@ -24,6 +24,14 @@ namespace o2::aod { + +namespace dqppfilter +{ +DECLARE_SOA_COLUMN(EventFilter, eventFilter, uint64_t); +} +// Table to be used for storing event-level decisions (DQ high level triggers) +DECLARE_SOA_TABLE(DQEventFilter, "AOD", "EVENTFILTER", dqppfilter::EventFilter); + namespace reducedevent { diff --git a/Analysis/Tasks/PWGDQ/CMakeLists.txt b/Analysis/Tasks/PWGDQ/CMakeLists.txt index 470f00fd682e6..fa46f30e0675c 100644 --- a/Analysis/Tasks/PWGDQ/CMakeLists.txt +++ b/Analysis/Tasks/PWGDQ/CMakeLists.txt @@ -1,3 +1,11 @@ +o2_add_library(PWGDQCore + SOURCES + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisCore) + +o2_target_root_dictionary(PWGDQCore + HEADERS CutsLibrary.h HistogramsLibrary.h + LINKDEF PWGDQCoreLinkDef.h) + o2_add_dpl_workflow(table-maker SOURCES tableMaker.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::DetectorsBase O2::AnalysisCore @@ -22,7 +30,12 @@ o2_add_dpl_workflow(table-maker-pp SOURCES tableMaker_pp.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::DetectorsBase O2::AnalysisCore COMPONENT_NAME Analysis) - + +o2_add_dpl_workflow(dq-filter-pp + SOURCES filterPP.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::DetectorsBase O2::AnalysisCore + COMPONENT_NAME Analysis) + o2_add_dpl_workflow(table-maker-muon-pp SOURCES tableMakerMuon_pp.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::DetectorsBase O2::AnalysisCore diff --git a/Analysis/Tasks/PWGDQ/CutsLibrary.h b/Analysis/Tasks/PWGDQ/CutsLibrary.h new file mode 100644 index 0000000000000..87423e236ffb9 --- /dev/null +++ b/Analysis/Tasks/PWGDQ/CutsLibrary.h @@ -0,0 +1,194 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// +#include "Analysis/AnalysisCut.h" +#include "Analysis/AnalysisCompositeCut.h" +#include "Analysis/VarManager.h" + +namespace o2::aod +{ +namespace dqcuts +{ +AnalysisCompositeCut* GetCompositeCut(const char* cutName); +AnalysisCut* GetAnalysisCut(const char* cutName); +} // namespace dqcuts +} // namespace o2::aod + +AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) +{ + // + // define composie cuts, typically combinations of all the ingredients needed for a full cut + // + // TODO: Agree on some conventions for the naming + // Possibly think of possible customization of the predefined cuts + + AnalysisCompositeCut* cut = new AnalysisCompositeCut(cutName, cutName); + std::string nameStr = cutName; + + if (!nameStr.compare("jpsiKineAndQuality")) { + cut->AddCut(GetAnalysisCut("jpsiStandardKine")); + cut->AddCut(GetAnalysisCut("electronStandardQuality")); + cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); + return cut; + } + + if (!nameStr.compare("jpsiPID1")) { + cut->AddCut(GetAnalysisCut("jpsiStandardKine")); + cut->AddCut(GetAnalysisCut("electronStandardQuality")); + cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); + cut->AddCut(GetAnalysisCut("electronPID1")); + return cut; + } + + if (!nameStr.compare("jpsiPID2")) { + cut->AddCut(GetAnalysisCut("jpsiStandardKine")); + cut->AddCut(GetAnalysisCut("electronStandardQuality")); + cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); + cut->AddCut(GetAnalysisCut("electronPID2")); + return cut; + } + + if (!nameStr.compare("pairNoCut")) { + cut->AddCut(GetAnalysisCut("pairNoCut")); + return cut; + } + + if (!nameStr.compare("pairMassLow")) { + cut->AddCut(GetAnalysisCut("pairMassLow")); + return cut; + } + + if (!nameStr.compare("pairJpsi")) { + cut->AddCut(GetAnalysisCut("pairJpsi")); + return cut; + } + + if (!nameStr.compare("pairPsi2S")) { + cut->AddCut(GetAnalysisCut("pairPsi2S")); + return cut; + } + + if (!nameStr.compare("pairUpsilon")) { + cut->AddCut(GetAnalysisCut("pairUpsilon")); + return cut; + } + + if (!nameStr.compare("pairJpsiLowPt1")) { + cut->AddCut(GetAnalysisCut("pairJpsi")); + cut->AddCut(GetAnalysisCut("pairPtLow1")); + return cut; + } + + if (!nameStr.compare("pairJpsiLowPt2")) { + cut->AddCut(GetAnalysisCut("pairJpsi")); + cut->AddCut(GetAnalysisCut("pairPtLow2")); + return cut; + } + + delete cut; + return nullptr; +} + +AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) +{ + // + // define here cuts which are likely to be used often + // + AnalysisCut* cut = new AnalysisCut(cutName, cutName); + std::string nameStr = cutName; + + if (!nameStr.compare("eventStandard")) { + cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); + cut->AddCut(VarManager::kIsINT7, 0.5, 1.5); + return cut; + } + + if (!nameStr.compare("int7vtxZ5")) { + cut->AddCut(VarManager::kVtxZ, -5.0, 5.0); + cut->AddCut(VarManager::kIsINT7, 0.5, 1.5); + return cut; + } + + if (!nameStr.compare("jpsiStandardKine")) { + cut->AddCut(VarManager::kPt, 1.0, 1000.0); + cut->AddCut(VarManager::kEta, -0.9, 0.9); + return cut; + } + + if (!nameStr.compare("electronStandardQuality")) { + cut->AddCut(VarManager::kIsSPDany, 0.5, 1.5); + cut->AddCut(VarManager::kIsITSrefit, 0.5, 1.5); + cut->AddCut(VarManager::kIsTPCrefit, 0.5, 1.5); + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kITSchi2, 0.1, 36.0); + cut->AddCut(VarManager::kTPCncls, 100.0, 161.); + return cut; + } + + if (!nameStr.compare("standardPrimaryTrack")) { + cut->AddCut(VarManager::kTrackDCAxy, -1.0, 1.0); + cut->AddCut(VarManager::kTrackDCAz, -3.0, 3.0); + return cut; + } + + TF1* cutLow1 = new TF1("cutLow1", "pol1", 0., 10.); + cutLow1->SetParameters(130., -40.0); + if (!nameStr.compare("electronPID1")) { + cut->AddCut(VarManager::kTPCsignal, 70., 100.); + cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); + return cut; + } + + if (!nameStr.compare("electronPID2")) { + cut->AddCut(VarManager::kTPCsignal, 73., 100.); + cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); + return cut; + } + + if (!nameStr.compare("pairNoCut")) { + cut->AddCut(VarManager::kMass, 0.0, 1000.0); + return cut; + } + + if (!nameStr.compare("pairMassLow")) { + cut->AddCut(VarManager::kMass, 2.5, 1000.0); + return cut; + } + + if (!nameStr.compare("pairJpsi")) { + cut->AddCut(VarManager::kMass, 2.8, 3.3); + return cut; + } + + if (!nameStr.compare("pairPsi2S")) { + cut->AddCut(VarManager::kMass, 3.4, 3.9); + return cut; + } + + if (!nameStr.compare("pairUpsilon")) { + cut->AddCut(VarManager::kMass, 8.0, 11.0); + return cut; + } + + if (!nameStr.compare("pairPtLow1")) { + cut->AddCut(VarManager::kPt, 2.0, 1000.0); + return cut; + } + + if (!nameStr.compare("pairPtLow2")) { + cut->AddCut(VarManager::kPt, 5.0, 1000.0); + return cut; + } + + delete cut; + return nullptr; +} diff --git a/Analysis/Tasks/PWGDQ/HistogramsLibrary.h b/Analysis/Tasks/PWGDQ/HistogramsLibrary.h new file mode 100644 index 0000000000000..03c7ce56950e2 --- /dev/null +++ b/Analysis/Tasks/PWGDQ/HistogramsLibrary.h @@ -0,0 +1,126 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// +#include "Analysis/HistogramManager.h" +#include "Analysis/VarManager.h" + +namespace o2::aod +{ +namespace dqhistograms +{ +void DefineHistograms(HistogramManager* hm, const char* histClass, const char* groupName, const char* subGroupName = ""); +} +} // namespace o2::aod + +void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* histClass, const char* groupName, const char* subGroupName) +{ + // + // Add a predefined group of histograms to the HistogramManager hm and histogram class histClass + // NOTE: The groupName and subGroupName arguments may contain several keywords, but the user should take care of + // ambiguities. TODO: fix it! + // NOTE: All of the histograms which match any of the group or subgroup names will be added to the same histogram class !! + // So one has to make sure not to mix e.g. event-wise with track-wise histograms + // NOTE: The subgroup name can be empty. In this case just a minimal set of histograms corresponding to the group name will be defined + // + TString groupStr = groupName; + groupStr.ToLower(); + TString subGroupStr = subGroupName; + subGroupStr.ToLower(); + if (groupStr.Contains("event")) { + hm->AddHistogram(histClass, "VtxZ", "Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ); + + if (subGroupStr.Contains("trigger")) { + hm->AddHistogram(histClass, "IsINT7", "Is INT7", false, 2, -0.5, 1.5, VarManager::kIsINT7); + hm->AddHistogram(histClass, "IsINT7inMUON", "INT7inMUON", false, 2, -0.5, 1.5, VarManager::kIsINT7inMUON); + hm->AddHistogram(histClass, "IsMuonSingleLowPt7", "Is MuonSingleLowPt7", false, 2, -0.5, 1.5, VarManager::kIsMuonSingleLowPt7); + hm->AddHistogram(histClass, "IsMuonUnlikeLowPt7", "Is MuonUnlikeLowPt7", false, 2, -0.5, 1.5, VarManager::kIsMuonUnlikeLowPt7); + hm->AddHistogram(histClass, "IsMuonLikeLowPt7", "Is MuonLikeLowPt7", false, 2, -0.5, 1.5, VarManager::kIsMuonLikeLowPt7); + } + if (subGroupStr.Contains("vtx")) { + hm->AddHistogram(histClass, "VtxX", "Vtx X", false, 100, -0.5, 0.5, VarManager::kVtxX); + hm->AddHistogram(histClass, "VtxY", "Vtx Y", false, 100, -0.5, 0.5, VarManager::kVtxY); + hm->AddHistogram(histClass, "VtxYVtxX", "Vtx Y vs Vtx X", false, 50, -0.5, 0.5, VarManager::kVtxX, 50, -0.5, 0.5, VarManager::kVtxY); + } + if (subGroupStr.Contains("vtxpp")) { + hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 100.0, VarManager::kVtxNcontrib); + } + if (subGroupStr.Contains("vtxPbPb")) { + hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 20000.0, VarManager::kVtxNcontrib); + } + if (subGroupStr.Contains("cent")) { + hm->AddHistogram(histClass, "CentV0M", "CentV0M", false, 100, 0., 100., VarManager::kCentVZERO); + hm->AddHistogram(histClass, "CentV0M_vtxZ", "CentV0M vs Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ, 20, 0., 100., VarManager::kCentVZERO); + } + } + + if (groupStr.Contains("track")) { + hm->AddHistogram(histClass, "Pt", "p_{T} distribution", false, 200, 0.0, 20.0, VarManager::kPt); + hm->AddHistogram(histClass, "Eta", "#eta distribution", false, 500, -5.0, 5.0, VarManager::kEta); + hm->AddHistogram(histClass, "Phi", "#varphi distribution", false, 500, -6.3, 6.3, VarManager::kPhi); + + if (subGroupStr.Contains("kine")) { + hm->AddHistogram(histClass, "Phi_Eta", "#phi vs #eta distribution", false, 200, -5.0, 5.0, VarManager::kEta, 200, -6.3, 6.3, VarManager::kPhi); + hm->AddHistogram(histClass, "Eta_Pt", "", false, 20, -1.0, 1.0, VarManager::kEta, 100, 0.0, 20.0, VarManager::kPt); + hm->AddHistogram(histClass, "Px", "p_{x} distribution", false, 200, 0.0, 20.0, VarManager::kPx); + hm->AddHistogram(histClass, "Py", "p_{y} distribution", false, 200, 0.0, 20.0, VarManager::kPy); + hm->AddHistogram(histClass, "Pz", "p_{z} distribution", false, 200, 0.0, 20.0, VarManager::kPz); + } + if (subGroupStr.Contains("its")) { + hm->AddHistogram(histClass, "ITSncls", "Number of cluster in ITS", false, 8, -0.5, 7.5, VarManager::kITSncls); + hm->AddHistogram(histClass, "ITSchi2", "ITS chi2", false, 100, 0.0, 50.0, VarManager::kITSchi2); + hm->AddHistogram(histClass, "IsITSrefit", "", false, 2, -0.5, 1.5, VarManager::kIsITSrefit); + hm->AddHistogram(histClass, "IsSPDany", "", false, 2, -0.5, 1.5, VarManager::kIsSPDany); + } + if (subGroupStr.Contains("tpc")) { + hm->AddHistogram(histClass, "TPCncls", "Number of cluster in TPC", false, 160, -0.5, 159.5, VarManager::kTPCncls); + hm->AddHistogram(histClass, "TPCncls_Run", "Number of cluster in TPC", true, VarManager::GetNRuns(), 0.5, 0.5 + VarManager::GetNRuns(), VarManager::kRunId, + 10, -0.5, 159.5, VarManager::kTPCncls, 10, 0., 1., VarManager::kNothing, VarManager::GetRunStr().Data()); + hm->AddHistogram(histClass, "IsTPCrefit", "", false, 2, -0.5, 1.5, VarManager::kIsTPCrefit); + hm->AddHistogram(histClass, "TPCchi2", "TPC chi2", false, 100, 0.0, 10.0, VarManager::kTPCchi2); + } + if (subGroupStr.Contains("tpcpid")) { + hm->AddHistogram(histClass, "TPCdedx_pIN", "TPC dE/dx vs pIN", false, 200, 0.0, 20.0, VarManager::kPin, 200, 0.0, 200., VarManager::kTPCsignal); + } + if (subGroupStr.Contains("dca")) { + hm->AddHistogram(histClass, "DCAxy", "DCAxy", false, 100, -3.0, 3.0, VarManager::kTrackDCAxy); + hm->AddHistogram(histClass, "DCAz", "DCAz", false, 100, -5.0, 5.0, VarManager::kTrackDCAz); + } + if (subGroupStr.Contains("muon")) { + hm->AddHistogram(histClass, "InvBendingMom", "", false, 100, 0.0, 1.0, VarManager::kMuonInvBendingMomentum); + hm->AddHistogram(histClass, "ThetaX", "", false, 100, -1.0, 1.0, VarManager::kMuonThetaX); + hm->AddHistogram(histClass, "ThetaY", "", false, 100, -2.0, 2.0, VarManager::kMuonThetaY); + hm->AddHistogram(histClass, "ZMu", "", false, 100, -30.0, 30.0, VarManager::kMuonZMu); + hm->AddHistogram(histClass, "BendingCoor", "", false, 100, 0.32, 0.35, VarManager::kMuonBendingCoor); + hm->AddHistogram(histClass, "NonBendingCoor", "", false, 100, 0.065, 0.07, VarManager::kMuonNonBendingCoor); + hm->AddHistogram(histClass, "Chi2", "", false, 100, 0.0, 200.0, VarManager::kMuonChi2); + hm->AddHistogram(histClass, "Chi2MatchTrigger", "", false, 100, 0.0, 20.0, VarManager::kMuonChi2MatchTrigger); + hm->AddHistogram(histClass, "RAtAbsorberEnd", "", false, 140, 10, 150, VarManager::kMuonRAtAbsorberEnd); + hm->AddHistogram(histClass, "p x dca", "", false, 700, 0.0, 700, VarManager::kMuonRAtAbsorberEnd); + } + } + + if (groupStr.Contains("pair")) { + hm->AddHistogram(histClass, "Mass", "", false, 125, 0.0, 5.0, VarManager::kMass); + hm->AddHistogram(histClass, "Mass_Pt", "", false, 125, 0.0, 5.0, VarManager::kMass, 100, 0.0, 20.0, VarManager::kPt); + hm->AddHistogram(histClass, "Eta_Pt", "", false, 125, -2.0, 2.0, VarManager::kEta, 100, 0.0, 20.0, VarManager::kPt); + hm->AddHistogram(histClass, "Mass_VtxZ", "", true, 30, -15.0, 15.0, VarManager::kVtxZ, 100, 0.0, 20.0, VarManager::kMass); + } + + if (groupStr.Contains("pair-hadron-mass")) { + hm->AddHistogram(histClass, "Mass_Pt", "", false, 40, 0.0, 20.0, VarManager::kPairMass, 40, 0.0, 20.0, VarManager::kPairPt); + } + + if (groupStr.Contains("pair-hadron-correlation")) { + hm->AddHistogram(histClass, "DeltaEta_DeltaPhi", "", false, 20, -2.0, 2.0, VarManager::kDeltaEta, 50, -8.0, 8.0, VarManager::kDeltaPhi); + hm->AddHistogram(histClass, "DeltaEta_DeltaPhiSym", "", false, 20, -2.0, 2.0, VarManager::kDeltaEta, 50, -8.0, 8.0, VarManager::kDeltaPhiSym); + } +} diff --git a/Analysis/Tasks/PWGDQ/PWGDQCoreLinkDef.h b/Analysis/Tasks/PWGDQ/PWGDQCoreLinkDef.h new file mode 100644 index 0000000000000..d2769ae13ba53 --- /dev/null +++ b/Analysis/Tasks/PWGDQ/PWGDQCoreLinkDef.h @@ -0,0 +1,13 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; diff --git a/Analysis/Tasks/PWGDQ/dileptonMuMu.cxx b/Analysis/Tasks/PWGDQ/dileptonMuMu.cxx index 5ce3dab9755ca..dc9244fbd0c8a 100644 --- a/Analysis/Tasks/PWGDQ/dileptonMuMu.cxx +++ b/Analysis/Tasks/PWGDQ/dileptonMuMu.cxx @@ -265,14 +265,14 @@ struct DileptonMuMu { for (auto& tpos : posMuons) { for (auto& tneg : negMuons) { //dileptonList(event, VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], 1); - VarManager::FillPair(tpos, tneg); + VarManager::FillPair(tpos, tneg, nullptr, VarManager::kJpsiToMuMu); if (!fDiMuonCut->IsSelected(VarManager::fgValues)) { return; } fHistMan->FillHistClass("PairsMuonULS", VarManager::fgValues); } for (auto tpos2 = tpos + 1; tpos2 != posMuons.end(); ++tpos2) { // ++ pairs - VarManager::FillPair(tpos, tpos2); + VarManager::FillPair(tpos, tpos2, nullptr, VarManager::kJpsiToMuMu); if (!fDiMuonCut->IsSelected(VarManager::fgValues)) { return; } @@ -281,7 +281,7 @@ struct DileptonMuMu { } for (auto tneg : negMuons) { // -- pairs for (auto tneg2 = tneg + 1; tneg2 != negMuons.end(); ++tneg2) { - VarManager::FillPair(tneg, tneg2); + VarManager::FillPair(tneg, tneg2, nullptr, VarManager::kJpsiToMuMu); if (!fDiMuonCut->IsSelected(VarManager::fgValues)) { return; } diff --git a/Analysis/Tasks/PWGDQ/filterPP.cxx b/Analysis/Tasks/PWGDQ/filterPP.cxx new file mode 100644 index 0000000000000..f03fde06261c3 --- /dev/null +++ b/Analysis/Tasks/PWGDQ/filterPP.cxx @@ -0,0 +1,359 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Analysis/Multiplicity.h" +#include "Analysis/EventSelection.h" +#include "Analysis/Centrality.h" +#include "Analysis/TriggerAliases.h" +#include "Analysis/ReducedInfoTables.h" +#include "Analysis/VarManager.h" +#include "Analysis/HistogramManager.h" +#include "Analysis/AnalysisCut.h" +#include "Analysis/AnalysisCompositeCut.h" +#include "CutsLibrary.h" +#include "HistogramsLibrary.h" +#include "PID/PIDResponse.h" +#include "Analysis/TrackSelectionTables.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::cout; +using std::endl; + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod; + +// Some definitions +namespace o2::aod +{ +namespace dqppfilter +{ +DECLARE_SOA_COLUMN(IsDQEventSelected, isDQEventSelected, int); +DECLARE_SOA_COLUMN(IsBarrelSelected, isBarrelSelected, uint8_t); +} // namespace dqppfilter + +DECLARE_SOA_TABLE(DQEventCuts, "AOD", "DQEVENTCUTS", dqppfilter::IsDQEventSelected); +DECLARE_SOA_TABLE(DQBarrelTrackCuts, "AOD", "DQBARRELCUTS", dqppfilter::IsBarrelSelected); +} // namespace o2::aod + +using MyEvents = soa::Join; +using MyEventsSelected = soa::Join; +using MyBarrelTracks = soa::Join; +using MyBarrelTracksSelected = soa::Join; + +constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision; +constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackCov | VarManager::ObjTypes::TrackPID; + +void DefineHistograms(HistogramManager* histMan, TString histClasses); + +struct EventSelectionTask { + Produces eventSel; + OutputObj fOutputList{"output"}; + HistogramManager* fHistMan; + AnalysisCompositeCut fEventCut{true}; + + float* fValues; + + Configurable fConfigCuts{"cfgEventCuts", "eventStandard", "Comma separated list of event cuts; multiple cuts are applied with a logical AND"}; + + void init(o2::framework::InitContext&) + { + fValues = new float[VarManager::kNVars]; + VarManager::SetDefaultVarNames(); + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + DefineHistograms(fHistMan, "Event_BeforeCuts;Event_AfterCuts;"); // define all histograms + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + + DefineCuts(); + } + + void DefineCuts() + { + // default cut is "eventStandard" (kINT7 and vtxZ selection) + TString cutNamesStr = fConfigCuts.value; + if (!cutNamesStr.IsNull()) { + std::unique_ptr objArray(cutNamesStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + fEventCut.AddCut(dqcuts::GetAnalysisCut(objArray->At(icut)->GetName())); + } + } + + // NOTE: Additional cuts to those specified via the Configurable may still be added + + VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill + } + + void process(MyEvents::iterator const& event, aod::BCs const& bcs) + { + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNEventWiseVariables, fValues); + + VarManager::FillEvent(event, fValues); + fHistMan->FillHistClass("Event_BeforeCuts", fValues); // automatically fill all the histograms in the class Event + if (fEventCut.IsSelected(fValues)) { + fHistMan->FillHistClass("Event_AfterCuts", fValues); + eventSel(1); + } else { + eventSel(0); + } + } +}; + +struct BarrelTrackSelectionTask { + Produces trackSel; + OutputObj fOutputList{"output"}; + HistogramManager* fHistMan; + std::vector fTrackCuts; + + float* fValues; // array to be used by the VarManager + + Configurable fConfigCuts{"cfgBarrelTrackCuts", "jpsiPID1", "Comma separated list of barrel track cuts"}; + + void init(o2::framework::InitContext&) + { + DefineCuts(); + + fValues = new float[VarManager::kNVars]; + VarManager::SetDefaultVarNames(); + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + TString cutNames = "TrackBarrel_BeforeCuts;"; + for (int i = 0; i < fTrackCuts.size(); i++) { + cutNames += Form("TrackBarrel_%s;", fTrackCuts[i].GetName()); + } + + DefineHistograms(fHistMan, cutNames.Data()); // define all histograms + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + } + + void DefineCuts() + { + // available cuts: jpsiKineAndQuality, jpsiPID1, jpsiPID2 + TString cutNamesStr = fConfigCuts.value; + if (!cutNamesStr.IsNull()) { + std::unique_ptr objArray(cutNamesStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + fTrackCuts.push_back(*dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); + } + } + + // NOTE: Additional cuts to those specified via the Configurable may still be added + + VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill + } + + void process(MyEvents::iterator const& event, MyBarrelTracks const& tracks, aod::BCs const& bcs) + { + uint8_t filterMap = uint8_t(0); + trackSel.reserve(tracks.size()); + + VarManager::ResetValues(0, VarManager::kNBarrelTrackVariables, fValues); + // fill event information which might be needed in histograms that combine track and event properties + VarManager::FillEvent(event, fValues); + + for (auto& track : tracks) { + filterMap = uint8_t(0); + // TODO: if a condition on the event selection is applied, the histogram output is missing + VarManager::FillTrack(track, fValues); + fHistMan->FillHistClass("TrackBarrel_BeforeCuts", fValues); + int i = 0; + for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); ++cut, ++i) { + if ((*cut).IsSelected(fValues)) { + filterMap |= (uint8_t(1) << i); + fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut).GetName()), fValues); + } + } + trackSel(filterMap); + } + } +}; + +struct FilterPPTask { + Produces eventFilter; + OutputObj fOutputList{"output"}; + OutputObj fStats{"stats"}; + HistogramManager* fHistMan; + std::vector fPairCuts; + + float* fValues; + + Partition posTracks = aod::track::signed1Pt > 0.0f && aod::dqppfilter::isBarrelSelected > uint8_t(0); + Partition negTracks = aod::track::signed1Pt < 0.0f && aod::dqppfilter::isBarrelSelected > uint8_t(0); + + Configurable fConfigTrackCuts{"cfgBarrelTrackCuts", "jpsiPID1", "Comma separated list of barrel track cuts"}; + Configurable fConfigPairCuts{"cfgPairCuts", "pairMassLow", "Comma separated list of pair cuts"}; + + int fNTrackCuts; + int fNPairCuts; + TObjArray* fTrkCutsNameArray; + + void DefineCuts() + { + // available pair cuts in CutsLibrary: pairNoCut,pairMassLow,pairJpsi,pairPsi2S,pairUpsilon,pairJpsiPtLow1, pairJpsiPtLow2 + TString pairCutNamesStr = fConfigPairCuts.value; + std::unique_ptr objArray(pairCutNamesStr.Tokenize(",")); + fNPairCuts = objArray->GetEntries(); + if (fNPairCuts) { + for (int icut = 0; icut < fNPairCuts; ++icut) { + fPairCuts.push_back(*dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); + } + } + + // NOTE: Additional cuts to those specified via the Configurable may still be added + + VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill + } + + void init(o2::framework::InitContext&) + { + DefineCuts(); + + fValues = new float[VarManager::kNVars]; + + // initialize the variable manager + VarManager::SetDefaultVarNames(); + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + // configure histograms + TString trackCutNamesStr = fConfigTrackCuts.value; + fTrkCutsNameArray = trackCutNamesStr.Tokenize(","); + fNTrackCuts = fTrkCutsNameArray->GetEntries(); + TString histNames = ""; + for (int i = 0; i < fNTrackCuts; i++) { + histNames += Form("PairsBarrelPM_%s;", fTrkCutsNameArray->At(i)->GetName()); + } + DefineHistograms(fHistMan, histNames.Data()); // define all histograms + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + + // configure the stats histogram + fStats.setObject(new TH2I("stats", "stats", fNPairCuts, -0.5, -0.5 + fNPairCuts, fNTrackCuts, -0.5, -0.5 + fNTrackCuts)); + for (int i = 0; i < fNPairCuts; ++i) { + fStats->GetXaxis()->SetBinLabel(i + 1, fPairCuts[i].GetName()); + } + for (int i = 0; i < fNTrackCuts; ++i) { + fStats->GetYaxis()->SetBinLabel(i + 1, fTrkCutsNameArray->At(i)->GetName()); + } + } + + void process(MyEventsSelected::iterator const& event, MyBarrelTracksSelected const& tracks, aod::BCs const& bcs) + { + uint64_t filter = 0; + + if (event.isDQEventSelected() == 1) { + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars, fValues); + VarManager::FillEvent(event, fValues); + + uint8_t* pairsCount = new uint8_t[fNPairCuts * fNTrackCuts]; + for (int i = 0; i < fNPairCuts * fNTrackCuts; i++) { + pairsCount[i] = 0; + } + + uint8_t cutFilter = 0; + for (auto tpos : posTracks) { + for (auto tneg : negTracks) { // +- pairs + cutFilter = tpos.isBarrelSelected() & tneg.isBarrelSelected(); + if (!cutFilter) { // the tracks must have at least one filter bit in common to continue + continue; + } + VarManager::FillPair(tpos, tneg, fValues); // compute pair quantities + for (int i = 0; i < fNTrackCuts; ++i) { + if (!(cutFilter & (uint8_t(1) << i))) { + continue; + } + fHistMan->FillHistClass(Form("PairsBarrelPM_%s", fTrkCutsNameArray->At(i)->GetName()), fValues); + int j = 0; + for (auto cut = fPairCuts.begin(); cut != fPairCuts.end(); cut++, j++) { + if ((*cut).IsSelected(fValues)) { + pairsCount[j + i * fNPairCuts] += 1; + } + } + } + } + } + + for (int i = 0; i < fNTrackCuts; i++) { + for (int j = 0; j < fNPairCuts; j++) { + if (pairsCount[j + i * fNPairCuts] > 0) { + filter |= (uint64_t(1) << (j + i * fNPairCuts)); + fStats->Fill(j, i); + } + } + } + delete[] pairsCount; + } + eventFilter(filter); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const&) +{ + return WorkflowSpec{ + adaptAnalysisTask("dq-event-selection"), + adaptAnalysisTask("dq-barrel-track-selection"), + adaptAnalysisTask("dq-ppFilter")}; +} + +void DefineHistograms(HistogramManager* histMan, TString histClasses) +{ + // + // Define here the histograms for all the classes required in analysis. + // The histogram classes are provided in the histClasses string, separated by semicolon ";" + // NOTE: Additional histograms to those predefined in the library can be added here !! + const int kNRuns = 25; + int runs[kNRuns] = { + 285009, 285011, 285012, 285013, 285014, 285015, 285064, 285065, 285066, 285106, + 285108, 285125, 285127, 285165, 285200, 285202, 285203, 285222, 285224, 285327, + 285328, 285347, 285364, 285365, 285396}; + VarManager::SetRunNumbers(kNRuns, runs); + + std::unique_ptr objArray(histClasses.Tokenize(";")); + for (Int_t iclass = 0; iclass < objArray->GetEntries(); ++iclass) { + TString classStr = objArray->At(iclass)->GetName(); + histMan->AddHistClass(classStr.Data()); + + if (classStr.Contains("Event")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "event", "trigger,vtxPbPb"); + } + + if (classStr.Contains("Track")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "track", "its,tpcpid,dca"); + } + + if (classStr.Contains("Pairs")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "pair"); + } + } +}