diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index ac4af0432b8..8c55becc413 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -4317,6 +4317,24 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("acceptance_pp13600")) { + cut->AddCut(VarManager::kMCY, -0.8, 0.8); + cut->AddCut(VarManager::kMCPt1, 1.0, 1000.0); + cut->AddCut(VarManager::kMCPt2, 1.0, 1000.0); + cut->AddCut(VarManager::kMCEta1, -0.8, 0.8); + cut->AddCut(VarManager::kMCEta2, -0.8, 0.8); + return cut; + } + + if (!nameStr.compare("acceptance_pp5360")) { + cut->AddCut(VarManager::kMCY, -0.9, 0.9); + cut->AddCut(VarManager::kMCPt1, 1.0, 1000.0); + cut->AddCut(VarManager::kMCPt2, 1.0, 1000.0); + cut->AddCut(VarManager::kMCEta1, -0.9, 0.9); + cut->AddCut(VarManager::kMCEta2, -0.9, 0.9); + return cut; + } + // --------------------------------------------------- // MC generated particle acceptance cuts diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index da047fbaed4..1e29e021068 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -659,6 +659,10 @@ class VarManager : public TObject kMCMotherPdgCode, // MC pair variables + kMCPt1, + kMCEta1, + kMCPt2, + kMCEta2, kMCCosThetaHE, kMCPhiHE, kMCPhiTildeHE, @@ -3716,6 +3720,10 @@ void VarManager::FillPairMC(T1 const& t1, T2 const& t2, float* values) values[kMCEta] = v12.Eta(); values[kMCPhi] = v12.Phi(); values[kMCY] = -v12.Rapidity(); + values[kMCPt1] = t1.pt(); + values[kMCPt2] = t2.pt(); + values[kMCEta1] = t1.eta(); + values[kMCEta2] = t2.eta(); // polarization parameters bool useHE = fgUsedVars[kMCCosThetaHE] || fgUsedVars[kMCPhiHE]; // helicity frame diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 9a6babaee92..f6eec421b7b 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -1325,6 +1325,7 @@ struct AnalysisSameEventPairing { Produces dileptonInfoList; Produces PromptNonPromptSepTable; Produces MCTruthTableEffi; + Produces dileptonPolarList; o2::base::MatLayerCylSet* fLUT = nullptr; int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. @@ -1335,7 +1336,7 @@ struct AnalysisSameEventPairing { Configurable track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; Configurable pair{"cfgPairCuts", "", "Comma separated list of pair cuts, !!! Use only if you know what you are doing, otherwise leave empty"}; - Configurable MCgenAcc{"cfgMCGenAccCut", "", "cut for MC generated particles acceptance"}; + Configurable MCgenAcc{"cfgMCGenAccCuts", "", "Comma separated list of MC generated particles acceptance cuts, !!! Use only if you know what you are doing, otherwise leave empty"}; // TODO: Add pair cuts via JSON } fConfigCuts; @@ -1354,6 +1355,7 @@ struct AnalysisSameEventPairing { Configurable useRemoteField{"cfgUseRemoteField", false, "Chose whether to fetch the magnetic field from ccdb or set it manually"}; Configurable magField{"cfgMagField", 5.0f, "Manually set magnetic field"}; Configurable flatTables{"cfgFlatTables", false, "Produce a single flat tables with all relevant information of the pairs and single tracks"}; + Configurable polarTables{"cfgPolarTables", false, "Produce tables with dilepton polarization information"}; Configurable useKFVertexing{"cfgUseKFVertexing", false, "Use KF Particle for secondary vertex reconstruction (DCAFitter is used by default)"}; Configurable useAbsDCA{"cfgUseAbsDCA", false, "Use absolute DCA minimization instead of chi^2 minimization in secondary vertexing"}; Configurable propToPCA{"cfgPropToPCA", false, "Propagate tracks to secondary vertex"}; @@ -1396,7 +1398,7 @@ struct AnalysisSameEventPairing { std::vector fGenMCSignals; std::vector fPairCuts; - AnalysisCompositeCut fMCGenAccCut; + std::vector fMCGenAccCuts; bool fUseMCGenAccCut = false; uint32_t fTrackFilterMask; // mask for the track cuts required in this task to be applied on the barrel cuts produced upstream @@ -1485,16 +1487,6 @@ struct AnalysisSameEventPairing { } } - // get the mc generated acceptance cut - TString mcGenAccCutStr = fConfigCuts.MCgenAcc.value; - if (mcGenAccCutStr != "") { - AnalysisCut* cut = dqcuts::GetAnalysisCut(mcGenAccCutStr.Data()); - if (cut != nullptr) { - fMCGenAccCut.AddCut(cut); - } - fUseMCGenAccCut = true; - } - // check that the barrel track cuts array required in this task is not empty if (!trackCutsStr.IsNull()) { // tokenize and loop over the barrel cuts produced by the barrel track selection task @@ -1663,6 +1655,19 @@ struct AnalysisSameEventPairing { } // end loop over cuts } // end if (muonCutsStr) + // get the mc generated acceptance cuts + TString mcgenCutsStr = fConfigCuts.MCgenAcc.value; + if (!mcgenCutsStr.IsNull()) { + std::unique_ptr objArray(mcgenCutsStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + AnalysisCut* cut = dqcuts::GetAnalysisCut(objArray->At(icut)->GetName()); + if (cut != nullptr) { + fMCGenAccCuts.push_back(cut); + } + } + fUseMCGenAccCut = true; + } + // Add histogram classes for each specified MCsignal at the generator level // TODO: create a std::vector of hist classes to be used at Fill time, to avoid using Form in the process function TString sigGenNamesStr = fConfigMC.genSignals.value; @@ -1695,6 +1700,12 @@ struct AnalysisSameEventPairing { histNames += Form("MCTruthGenPair_%s;", sig->GetName()); histNames += Form("MCTruthGenPairSel_%s;", sig->GetName()); fHasTwoProngGenMCsignals = true; + // for these pair level signals, also add histograms for each MCgenAcc cut if specified + if (fUseMCGenAccCut) { + for (auto& cut : fMCGenAccCuts) { + histNames += Form("MCTruthGenPairSel_%s_%s;", sig->GetName(), cut->GetName()); + } + } } } } @@ -1806,6 +1817,9 @@ struct AnalysisSameEventPairing { dileptonMiniTreeGen.reserve(1); dileptonMiniTreeRec.reserve(1); } + if (fConfigOptions.polarTables.value) { + dileptonPolarList.reserve(1); + } constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); @@ -1900,6 +1914,13 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); } + if (fConfigOptions.polarTables.value && t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) { + dileptonPolarList(VarManager::fgValues[VarManager::kCosThetaHE], VarManager::fgValues[VarManager::kPhiHE], VarManager::fgValues[VarManager::kPhiTildeHE], + VarManager::fgValues[VarManager::kCosThetaCS], VarManager::fgValues[VarManager::kPhiCS], VarManager::fgValues[VarManager::kPhiTildeCS], + VarManager::fgValues[VarManager::kCosThetaPP], VarManager::fgValues[VarManager::kPhiPP], VarManager::fgValues[VarManager::kPhiTildePP], + VarManager::fgValues[VarManager::kCosThetaRM], + VarManager::fgValues[VarManager::kCosThetaStarTPC], VarManager::fgValues[VarManager::kCosThetaStarFT0A], VarManager::fgValues[VarManager::kCosThetaStarFT0C]); + } } } } @@ -2147,12 +2168,6 @@ struct AnalysisSameEventPairing { for (auto& mctrack : mcTracks) { VarManager::FillTrackMC(mcTracks, mctrack); - // if we have a mc generated acceptance cut, apply it here - if (fUseMCGenAccCut) { - if (!fMCGenAccCut.IsSelected(VarManager::fgValues)) { - continue; - } - } // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. // TODO: Use the mcReducedFlags to select signals @@ -2176,12 +2191,6 @@ struct AnalysisSameEventPairing { continue; } VarManager::FillTrackMC(mcTracks, track); - // if we have a mc generated acceptance cut, apply it here - if (fUseMCGenAccCut) { - if (!fMCGenAccCut.IsSelected(VarManager::fgValues)) { - continue; - } - } auto track_raw = mcTracks.rawIteratorAt(track.globalIndex()); mcDecision = 0; isig = 0; @@ -2212,11 +2221,6 @@ struct AnalysisSameEventPairing { } if (sig->CheckSignal(true, t1_raw, t2_raw)) { VarManager::FillPairMC(t1, t2); - if (fUseMCGenAccCut) { - if (!fMCGenAccCut.IsSelected(VarManager::fgValues)) { - continue; - } - } fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig->GetName()), VarManager::fgValues); } } @@ -2247,12 +2251,15 @@ struct AnalysisSameEventPairing { if (sig->CheckSignal(true, t1_raw, t2_raw)) { mcDecision |= (static_cast(1) << isig); VarManager::FillPairMC(t1, t2); + fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), VarManager::fgValues); + // Fill also acceptance cut histograms if requested if (fUseMCGenAccCut) { - if (!fMCGenAccCut.IsSelected(VarManager::fgValues)) { - continue; + for (auto& cut : fMCGenAccCuts) { + if (cut->IsSelected(VarManager::fgValues)) { + fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s_%s", sig->GetName(), cut->GetName()), VarManager::fgValues); + } } } - fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), VarManager::fgValues); if (useMiniTree.fConfigMiniTree) { // WARNING! To be checked dileptonMiniTreeGen(mcDecision, -999, t1.pt(), t1.eta(), t1.phi(), t2.pt(), t2.eta(), t2.phi()); @@ -2293,10 +2300,7 @@ struct AnalysisSameEventPairing { MyBarrelTracksWithCovWithAmbiguitiesWithColl const& barrelTracks, ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) { runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); - // Feature replaced by processMCGen - /* if (fConfigMC.runMCGenPair) { - runMCGen(mcEvents, mcTracks); - }*/ + runMCGenWithGrouping(events, mcEvents, mcTracks); } void processMuonOnlySkimmed(MyEventsVtxCovSelected const& events,