diff --git a/ALICE3/TableProducer/CMakeLists.txt b/ALICE3/TableProducer/CMakeLists.txt index 53b56706f0c..70c9ac11a74 100644 --- a/ALICE3/TableProducer/CMakeLists.txt +++ b/ALICE3/TableProducer/CMakeLists.txt @@ -61,6 +61,11 @@ o2physics_add_dpl_workflow(alice3-tracking-translator PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(alice3-dq-table-maker + SOURCES alice3-dq-table-maker.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2Physics::AnalysisCCDB O2Physics::PWGDQCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(alice3strangenessfinder SOURCES alice3strangenessFinder.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/ALICE3/TableProducer/alice3-decaypreselector.cxx b/ALICE3/TableProducer/alice3-decaypreselector.cxx index 139f53a6f82..7c28a51d118 100644 --- a/ALICE3/TableProducer/alice3-decaypreselector.cxx +++ b/ALICE3/TableProducer/alice3-decaypreselector.cxx @@ -74,9 +74,6 @@ struct alice3decaypreselector { Configurable nSigmaTOF{"nSigmaTOF", 4.0f, "Nsigma for TOF PID (if enabled)"}; Configurable nSigmaRICH{"nSigmaRICH", 4.0f, "Nsigma for RICH PID (if enabled)"}; - // Define o2 fitter, 2-prong, active memory (no need to redefine per event) - o2::vertexing::DCAFitterN<2> fitter; - // for bit-packed maps std::vector selectionMap; @@ -104,7 +101,17 @@ struct alice3decaypreselector { void init(InitContext&) { - // future dev if needed + auto h = histos.add("TracksProcessed", "TracksProcessed", o2::framework::HistType::kTH1D, {{10, 0, 10}}); + h->GetXaxis()->SetBinLabel(1, "TotalTracks"); + h->GetXaxis()->SetBinLabel(2, "InnerTOFPiRejected"); + h->GetXaxis()->SetBinLabel(3, "InnerTOFKaRejected"); + h->GetXaxis()->SetBinLabel(4, "InnerTOFPrRejected"); + h->GetXaxis()->SetBinLabel(5, "OuterTOFPiRejected "); + h->GetXaxis()->SetBinLabel(6, "OuterTOFKaRejected"); + h->GetXaxis()->SetBinLabel(7, "OuterTOFPrRejected"); + h->GetXaxis()->SetBinLabel(8, "RICHPiRejected"); + h->GetXaxis()->SetBinLabel(9, "RICHKaRejected"); + h->GetXaxis()->SetBinLabel(10, "RICHPrRejected"); } // go declarative: use partitions instead of "if", then just toggle bits to allow for mask selection later @@ -129,37 +136,56 @@ struct alice3decaypreselector { /// This process function ensures that all V0s are built. It will simply tag everything as true. void processInitialize(aod::Tracks const& tracks) { + histos.fill(HIST("TracksProcessed"), 0.5, tracks.size()); initializeMasks(tracks.size()); } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void processFilterInnerTOF(tofTracks const&) { - for (auto const& track : pInnerTOFPi) + for (auto const& track : pInnerTOFPi) { bitoff(selectionMap[track.globalIndex()], kInnerTOFPion); - for (auto const& track : pInnerTOFKa) + histos.fill(HIST("TracksProcessed"), 1.5); + } + for (auto const& track : pInnerTOFKa) { bitoff(selectionMap[track.globalIndex()], kInnerTOFKaon); - for (auto const& track : pInnerTOFPr) + histos.fill(HIST("TracksProcessed"), 2.5); + } + for (auto const& track : pInnerTOFPr) { bitoff(selectionMap[track.globalIndex()], kInnerTOFProton); + histos.fill(HIST("TracksProcessed"), 3.5); + } } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void processFilterOuterTOF(tofTracks const&) { - for (auto const& track : pOuterTOFPi) + for (auto const& track : pOuterTOFPi) { bitoff(selectionMap[track.globalIndex()], kOuterTOFPion); - for (auto const& track : pOuterTOFKa) + histos.fill(HIST("TracksProcessed"), 4.5); + } + for (auto const& track : pOuterTOFKa) { bitoff(selectionMap[track.globalIndex()], kOuterTOFKaon); - for (auto const& track : pOuterTOFPr) + histos.fill(HIST("TracksProcessed"), 5.5); + } + for (auto const& track : pOuterTOFPr) { bitoff(selectionMap[track.globalIndex()], kOuterTOFProton); + histos.fill(HIST("TracksProcessed"), 6.5); + } } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void processFilterRICH(richTracks const&) { - for (auto const& track : pRICHPi) + for (auto const& track : pRICHPi) { bitoff(selectionMap[track.globalIndex()], kRICHPion); - for (auto const& track : pRICHKa) + histos.fill(HIST("TracksProcessed"), 7.5); + } + for (auto const& track : pRICHKa) { bitoff(selectionMap[track.globalIndex()], kRICHKaon); - for (auto const& track : pRICHPr) + histos.fill(HIST("TracksProcessed"), 8.5); + } + for (auto const& track : pRICHPr) { bitoff(selectionMap[track.globalIndex()], kRICHProton); + histos.fill(HIST("TracksProcessed"), 9.5); + } } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void processFilterOnMonteCarloTruth(labeledTracks const& tracks, aod::McParticles const&) diff --git a/ALICE3/TableProducer/alice3-dq-table-maker.cxx b/ALICE3/TableProducer/alice3-dq-table-maker.cxx new file mode 100644 index 00000000000..0e990ff754a --- /dev/null +++ b/ALICE3/TableProducer/alice3-dq-table-maker.cxx @@ -0,0 +1,744 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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: Ionut Cristian Arsene iarsene@cern.ch, i.c.arsene@fys.uio.no +// Alexander Tiekoetter (alexander.tiekoetter@cern.ch) +/// \file alice3-dq-table-maker.cxx +/// \brief DQ table maker for ALICE 3 + +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/MCSignal.h" +#include "PWGDQ/Core/MCSignalLibrary.h" +#include "PWGDQ/Core/MuonMatchingMlResponse.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "PWGDQ/DataModel/ReducedTablesAlice3.h" + +#include "ALICE3/DataModel/OTFPIDTrk.h" +#include "ALICE3/DataModel/OTFRICH.h" +#include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/collisionAlice3.h" +#include "ALICE3/DataModel/tracksAlice3.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/McCollisionExtra.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonDataFormat/InteractionRecord.h" +#include "DataFormatsGlobalTracking/RecoContainer.h" +#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexerParams.h" +#include "DetectorsVertexing/VertexTrackMatcher.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" +#include "MathUtils/Primitive2D.h" +#include "ReconstructionDataFormats/PrimaryVertex.h" +#include "ReconstructionDataFormats/VtxTrackIndex.h" +#include "ReconstructionDataFormats/VtxTrackRef.h" + +#include "THashList.h" +#include "TList.h" + +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod; + +using MyBarrelTracks = soa::Join; + +using MyEvents = soa::Join; +using MyEventsMC = aod::McCollisions; + +constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::Collision; +constexpr static uint32_t gkEventMcFillMap = VarManager::ObjTypes::CollisionMC; + +constexpr static uint32_t gkTrackFillMapWithCov = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackCov | VarManager::ObjTypes::TrackPID; + +struct Alice3DQTableMaker { + + Produces eventMC; + Produces trackMC; + + Produces event; + Produces eventVtxCov; + Produces eventInfo; + Produces eventMClabels; + + Produces trackBarrelInfo; + Produces trackBasic; + Produces trackBarrel; + Produces trackBarrelCov; + Produces trackBarrelAssoc; + Produces trackBarrelLabels; + + Produces trackPIDTOF; + Produces trackPIDRich; + Produces trackPIDRichSig; + Produces trackPIDOT; + + OutputObj fOutputList{"output"}; + OutputObj fStatsList{"Statistics"}; //! skimming statistics + + HistogramManager* fHistMan; + + // Event and track AnalysisCut configurables + struct : ConfigurableGroup { + Configurable fConfigEventCuts{"cfgEventCuts", "", "Event selection"}; + Configurable fConfigTrackCuts{"cfgBarrelTrackCuts", "", "barrel track cut"}; + Configurable fConfigEventCutsJSON{"cfgEventCutsJSON", "", "Additional event selection in JSON format"}; + Configurable fConfigTrackCutsJSON{"cfgBarrelTrackCutsJSON", "", "Additional list of barrel track cuts in JSON format"}; + } fConfigCuts; + + // MC signals to be skimmed + Configurable fConfigMCSignals{"cfgMCsignals", "", "Comma separated list of MC signals"}; + Configurable fConfigMCSignalsJSON{"cfgMCsignalsJSON", "", "Additional list of MC signals via JSON"}; + + // Steer QA output + struct : ConfigurableGroup { + Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigDetailedQA{"cfgDetailedQA", false, "If true, include more QA histograms (BeforeCuts classes)"}; + Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddMuonHistogram{"cfgAddMuonHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddMCTruthHistogram{"cfgAddMCTruthHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; + } fConfigHistOutput; + + AnalysisCompositeCut* fEventCut; //! Event selection cut + std::vector fTrackCuts; //! Barrel track cuts + std::vector fMuonCuts; //! Muon track cuts + + bool fDoDetailedQA = false; + + std::vector fMCSignals; + std::map fLabelsMap; + std::map fLabelsMapReversed; + std::map fMCFlags; + std::map fCollIndexMap; // key: old collision index, value: skimmed collision index + std::map fTrackIndexMap; // key: old track global index, value: new track global index + + void init(InitContext& context) + { + bool isProcessSkimmingEnabled = context.mOptions.get("processSkimming"); + + if (!isProcessSkimmingEnabled) + LOG(fatal) << "No process function was enabled ALICE 3 TableMaker"; + + VarManager::SetDefaultVarNames(); // Important that this is called before DefineCuts() !!! + + DefineCuts(); + + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + if (fConfigHistOutput.fConfigQA && fConfigHistOutput.fConfigDetailedQA) { + fDoDetailedQA = true; + } + + TString histClasses = ""; + + if (fDoDetailedQA) { + histClasses += "Event_BeforeCuts;"; + } + + if (fConfigHistOutput.fConfigQA) { + histClasses += "Event_AfterCuts;"; + histClasses += "Event_MCTruth;"; + } + + if (isProcessSkimmingEnabled) { + if (fDoDetailedQA) { + histClasses += "TrackBarrel_BeforeCuts;"; + } + + if (fConfigHistOutput.fConfigQA) { + for (auto& cut : fTrackCuts) { + histClasses += Form("TrackBarrel_%s;", cut->GetName()); + } + } + } + + TString configNamesStr = fConfigMCSignals.value; + std::unique_ptr objArray(configNamesStr.Tokenize(",")); + + if (objArray->GetEntries() > 0) { + for (int isig = 0; isig < objArray->GetEntries(); ++isig) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objArray->At(isig)->GetName()); + if (sig) { + fMCSignals.push_back(sig); + } + } + } + + TString addMCSignalsStr = fConfigMCSignalsJSON.value; + + if (addMCSignalsStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); + + for (auto& mcIt : addMCSignals) { + if (mcIt) { + fMCSignals.push_back(mcIt); + } + } + } + + for (auto& mcIt : fMCSignals) { + if (fConfigHistOutput.fConfigQA) { + histClasses += Form("MCTruth_%s;", mcIt->GetName()); + } + if (fDoDetailedQA) { + if (isProcessSkimmingEnabled) { + for (auto& cut : fTrackCuts) { + histClasses += Form("TrackBarrel_%s_%s;", cut->GetName(), mcIt->GetName()); + } + } + } + } + + DefineHistograms(histClasses); + + TString addHistsStr = fConfigHistOutput.fConfigAddJSONHistograms.value; + if (fConfigHistOutput.fConfigQA && addHistsStr != "") { + dqhistograms::AddHistogramsFromJSON(fHistMan, addHistsStr.Data()); + } + + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + } + + void DefineCuts() + { + fEventCut = new AnalysisCompositeCut(true); + TString eventCutStr = fConfigCuts.fConfigEventCuts.value; + fEventCut->AddCut(dqcuts::GetAnalysisCut(eventCutStr.Data())); + + TString addEvCutsStr = fConfigCuts.fConfigEventCutsJSON.value; + if (addEvCutsStr != "") { + std::vector addEvCuts = dqcuts::GetCutsFromJSON(addEvCutsStr.Data()); + for (auto& cutIt : addEvCuts) { + fEventCut->AddCut(cutIt); + } + } + + // Barrel track cuts + TString cutNamesStr = fConfigCuts.fConfigTrackCuts.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())); + } + } + // Additional Barrel track cuts via JSON + TString addTrackCutsStr = fConfigCuts.fConfigTrackCutsJSON.value; + if (addTrackCutsStr != "") { + std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); + for (auto& t : addTrackCuts) { + fTrackCuts.push_back(reinterpret_cast(t)); + } + } + + VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill + } + + void DefineHistograms(TString histClasses) + { + std::unique_ptr objArray(histClasses.Tokenize(";")); + for (int iclass = 0; iclass < objArray->GetEntries(); ++iclass) { + TString classStr = objArray->At(iclass)->GetName(); + if (fConfigHistOutput.fConfigQA) { + fHistMan->AddHistClass(classStr.Data()); + } + + TString histEventName = fConfigHistOutput.fConfigAddEventHistogram.value; + if (classStr.Contains("Event")) { + if (fConfigHistOutput.fConfigQA && !classStr.Contains("MCTruth")) { + dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "event", histEventName); + } else { + dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "event", "generator"); + } + } + + TString histTrackName = fConfigHistOutput.fConfigAddTrackHistogram.value; + if (classStr.Contains("Track")) { + if (fConfigHistOutput.fConfigQA) { + dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", histTrackName); + } + } + + TString histMCTruthName = fConfigHistOutput.fConfigAddMCTruthHistogram.value; + if (classStr.Contains("MCTruth") && !classStr.Contains("Event")) { + if (fConfigHistOutput.fConfigQA) { + dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "mctruth_track", histMCTruthName); + } + } + } + + // create statistics histograms (event, tracks, muons, MCsignals) + fStatsList.setObject(new TList()); + fStatsList->SetOwner(kTRUE); + std::vector eventLabels{"Collisions before filtering", "Before cuts", "After cuts"}; + TH2I* histEvents = new TH2I("EventStats", "Event statistics", eventLabels.size(), -0.5, eventLabels.size() - 0.5, o2::aod::evsel::kNsel + 1, -0.5, (float)o2::aod::evsel::kNsel + 0.5); + int ib = 1; + for (auto label = eventLabels.begin(); label != eventLabels.end(); label++, ib++) { + histEvents->GetXaxis()->SetBinLabel(ib, (*label).Data()); + } + for (int ib = 1; ib <= o2::aod::evsel::kNsel; ib++) { + histEvents->GetYaxis()->SetBinLabel(ib, o2::aod::evsel::selectionLabels[ib - 1]); + } + histEvents->GetYaxis()->SetBinLabel(o2::aod::evsel::kNsel + 1, "Total"); + fStatsList->Add(histEvents); + + // Track statistics: one bin for each track selection and 5 bins for V0 tags (gamma, K0s, Lambda, anti-Lambda, Omega) + TH1I* histTracks = new TH1I("TrackStats", "Track statistics", fTrackCuts.size() + 5.0, -0.5, fTrackCuts.size() - 0.5 + 5.0); + ib = 1; + for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, ib++) { + histTracks->GetXaxis()->SetBinLabel(ib, (*cut)->GetName()); + } + const char* v0TagNames[5] = {"Photon conversion", "K^{0}_{s}", "#Lambda", "#bar{#Lambda}", "#Omega"}; + for (int ib = 0; ib < 5; ib++) { + histTracks->GetXaxis()->SetBinLabel(fTrackCuts.size() + 1 + ib, v0TagNames[ib]); + } + fStatsList->Add(histTracks); + + TH1I* histMCsignals = new TH1I("MCsignals", "MC signals", fMCSignals.size() + 1, -0.5, fMCSignals.size() - 0.5 + 1.0); + ib = 1; + for (auto signal = fMCSignals.begin(); signal != fMCSignals.end(); signal++, ib++) { + histMCsignals->GetXaxis()->SetBinLabel(ib, (*signal)->GetName()); + } + histMCsignals->GetXaxis()->SetBinLabel(fMCSignals.size() + 1, "Others (matched to reco tracks)"); + fStatsList->Add(histMCsignals); + } + + Preslice trackIndicesPerCollision = aod::track_association::collisionId; + + void skimMCCollisions(MyEventsMC const& mcCollisions) + { + // skim MC collisions + // NOTE: So far, all MC collisions are skimmed. In case there will be filtering based on MC collisions, + // one has to do a mapping of the old vs new indices so that the skimmed labels are properly updated. + VarManager::ResetValues(0, VarManager::kNVars); + + for (auto& mcCollision : mcCollisions) { + VarManager::FillEventAlice3(mcCollision); + + fHistMan->FillHistClass("Event_MCTruth", VarManager::fgValues); + + eventMC(mcCollision.generatorsID(), mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), + mcCollision.t(), mcCollision.weight(), mcCollision.impactParameter()); // TODO: Determine and fill multiplicity values + } + } + + void skimMCParticles(aod::McParticles const& mcTracks, MyEventsMC const&) + { + // Select MC particles which fulfill at least one of the user specified MC signals + // In this function we just fill a map with the labels of selected particles, not creating the tables themselves. + // The reason is that in the skims we will additionally add any MC label connected to selected reconstructed tracks + // which were not selected already via the MC signals + + fLabelsMap.clear(); + fLabelsMapReversed.clear(); + fMCFlags.clear(); + + uint16_t mcflags = static_cast(0); // flags which will hold the decisions for each MC signal + int trackCounter = 0; + + for (auto& mctrack : mcTracks) { + // check all the requested MC signals and fill the decision bit map + mcflags = 0; + int i = 0; + for (auto& sig : fMCSignals) { + bool checked = false; + if constexpr (soa::is_soa_filtered_v) { + auto mctrack_raw = mcTracks.rawIteratorAt(mctrack.globalIndex()); + checked = sig->CheckSignal(true, mctrack_raw); + } else { + checked = sig->CheckSignal(true, mctrack); + } + if (checked) { + mcflags |= (static_cast(1) << i); + } + i++; + } + + // if no MC signals were matched, continue + if (mcflags == 0) { + continue; + } + + // If this MC track was not already added to the map, add it now + if (fLabelsMap.find(mctrack.globalIndex()) == fLabelsMap.end()) { + fLabelsMap[mctrack.globalIndex()] = trackCounter; + fLabelsMapReversed[trackCounter] = mctrack.globalIndex(); + fMCFlags[mctrack.globalIndex()] = mcflags; + trackCounter++; + + // fill histograms for each of the signals, if found + if (fConfigHistOutput.fConfigQA) { + VarManager::FillTrackMC(mcTracks, mctrack); + auto mcCollision = mctrack.template mcCollision_as(); + VarManager::FillEvent(mcCollision); + int j = 0; + for (auto signal = fMCSignals.begin(); signal != fMCSignals.end(); signal++, j++) { + if (mcflags & (static_cast(1) << j)) { + fHistMan->FillHistClass(Form("MCTruth_%s", (*signal)->GetName()), VarManager::fgValues); + } + } + } + } + } + } + + void skimCollisions(MyEvents const& collisions) + { + // Skim reconstructed collisions which are selected by the user specified cuts + // Create a collision index map to relate between the "old" AO2D indices and the skimmed ones + fCollIndexMap.clear(); + + // Loop over collisions + for (const auto& collision : collisions) { + + (reinterpret_cast(fStatsList->At(0)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); + + VarManager::ResetValues(0, VarManager::kNEventWiseVariables); + VarManager::FillEventAlice3(collision); // extract event information and place it in the fValues array + + if (collision.has_mcCollision()) { + auto mcCollision = collision.template mcCollision_as(); + VarManager::FillEventAlice3(mcCollision); + } + + if (fDoDetailedQA) { + fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); + } + + // Apply the user specified event selection + if (!fEventCut->IsSelected(VarManager::fgValues)) { + continue; + } + + (reinterpret_cast(fStatsList->At(0)))->Fill(3.0, static_cast(o2::aod::evsel::kNsel)); + + // Fill historams after event cuts + fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); + + event(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), + collision.collisionTime(), collision.collisionTimeRes(), collision.multDensity()); + + eventVtxCov(collision.covXX(), collision.covXY(), collision.covXZ(), collision.covYY(), collision.covYZ(), collision.covZZ(), collision.chi2()); + eventMClabels(collision.mcCollisionId(), collision.mcMask()); + eventInfo(collision.globalIndex()); + + // add an element for this collision into the map + fCollIndexMap[collision.globalIndex()] = event.lastIndex(); + } + } + + void skimTracks(MyEvents::iterator const& collision, MyBarrelTracks const& /*tracks*/, TrackAssoc const& assocs, aod::McParticles const& mcTracks) + { + // Skim the barrel track associations + // Apply track cuts for each collision association and if it passes the cuts, we skim it. + // NOTE: If selection cuts include conditions on quantities dependent on the associated collision (e.g. DCA), + // one track may pass for some association and fail for others. + // Tracks are written only once in the skims, even if they contribute to more than one association + // so in case of multiple associations, the variables depending on the collision association (e.g. DCA, secondary vertexing, etc) + // have to be recomputed at analysis time for each association. + + uint64_t trackFilteringTag = static_cast(0); + uint32_t trackTempFilterMap = static_cast(0); + uint16_t mcflags = static_cast(0); + int trackCounter = fLabelsMap.size(); + + for (const auto& assoc : assocs) { + + auto track = assoc.template track_as(); + + if (fCollIndexMap.find(track.collisionId()) == fCollIndexMap.end()) { + continue; + } + + trackFilteringTag = static_cast(0); + trackTempFilterMap = static_cast(0); + + // Compute track quantities and fill histograms + VarManager::FillTrackAlice3(track); + + if (fDoDetailedQA) { + fHistMan->FillHistClass("TrackBarrel_BeforeCuts", VarManager::fgValues); + } + + int i = 0; + for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, i++) { + if ((*cut)->IsSelected(VarManager::fgValues)) { + trackTempFilterMap |= (static_cast(1) << i); + if (fConfigHistOutput.fConfigQA) { + fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut)->GetName()), VarManager::fgValues); + } + (reinterpret_cast(fStatsList->At(1)))->Fill(static_cast(i)); + } + } + if (!trackTempFilterMap) { + continue; + } + + // If this track is already present in the index map, it means it was already skimmed, + // so we just store the association and we skip the track + if (fTrackIndexMap.find(track.globalIndex()) != fTrackIndexMap.end()) { + trackBarrelAssoc(fCollIndexMap[collision.globalIndex()], fTrackIndexMap[track.globalIndex()]); + continue; + } + + trackFilteringTag |= (static_cast(trackTempFilterMap) << VarManager::kBarrelUserCutsBits); // BIT13-...: user track filters + + // NOTE: The collision ID that is written in the table is the one originally assigned in the AOD. + // However, in data analysis one should loop over associations, so this one should not be used. + // In the case of Run2-like analysis, there will be no associations, so this ID will be the one originally assigned in the AO2Ds (updated for the skims) + uint32_t reducedEventIdx = fCollIndexMap[track.collisionId()]; + + // NOTE: trackBarrelInfo stores the index of the collision as in AO2D (for use in some cases where the analysis on skims is done + // in workflows where the original AO2Ds are also present) + // trackBarrelInfo(track.collisionId(), collision.posX(), collision.posY(), collision.posZ(), track.globalIndex()); + trackBasic(reducedEventIdx, trackFilteringTag, track.pt(), track.eta(), track.phi(), track.sign(), 0); + + trackBarrel(track.x(), track.alpha(), track.y(), track.z(), track.snp(), track.tgl(), track.signed1Pt(), + track.flags(), track.itsClusterMap(), track.itsChi2NCl(), + track.isReconstructed(), track.nSiliconHits(), track.nTPCHits(), track.length(), track.dcaXY(), + track.dcaZ()); + + if constexpr (static_cast(gkTrackFillMapWithCov & VarManager::ObjTypes::TrackCov)) { + trackBarrelCov(track.cYY(), track.cZY(), track.cZZ(), track.cSnpY(), track.cSnpZ(), + track.cSnpSnp(), track.cTglY(), track.cTglZ(), track.cTglSnp(), track.cTglTgl(), + track.c1PtY(), track.c1PtZ(), track.c1PtSnp(), track.c1PtTgl(), track.c1Pt21Pt2()); + } + + if constexpr (static_cast(gkTrackFillMapWithCov & VarManager::ObjTypes::TrackPID)) { + + trackPIDTOF(track.tofEventTime(), track.tofEventTimeErr(), + track.nSigmaElectronInnerTOF(), track.nSigmaMuonInnerTOF(), track.nSigmaPionInnerTOF(), + track.nSigmaKaonInnerTOF(), track.nSigmaProtonInnerTOF(), track.nSigmaDeuteronInnerTOF(), + track.nSigmaTritonInnerTOF(), track.nSigmaHelium3InnerTOF(), track.nSigmaAlphaInnerTOF(), + track.innerTOFTrackTimeReco(), track.innerTOFTrackLengthReco(), + track.nSigmaElectronOuterTOF(), track.nSigmaMuonOuterTOF(), track.nSigmaPionOuterTOF(), + track.nSigmaKaonOuterTOF(), track.nSigmaProtonOuterTOF(), track.nSigmaDeuteronOuterTOF(), + track.nSigmaTritonOuterTOF(), track.nSigmaHelium3OuterTOF(), track.nSigmaAlphaOuterTOF(), + track.outerTOFTrackTimeReco(), track.outerTOFTrackLengthReco()); + + trackPIDRich(track.nSigmaElectronRich(), track.nSigmaMuonRich(), track.nSigmaPionRich(), + track.nSigmaKaonRich(), track.nSigmaProtonRich(), track.nSigmaDeuteronRich(), + track.nSigmaTritonRich(), track.nSigmaHelium3Rich(), track.nSigmaAlphaRich()); + + trackPIDRichSig(track.hasSig(), track.hasSigInGas(), + track.hasSigEl(), track.hasSigMu(), track.hasSigPi(), + track.hasSigKa(), track.hasSigPr(), track.hasSigDe(), + track.hasSigTr(), track.hasSigHe3(), track.hasSigAl()); + + trackPIDOT(track.timeOverThresholdBarrel(), + track.nSigmaTrkEl(), track.nSigmaTrkMu(), track.nSigmaTrkPi(), + track.nSigmaTrkKa(), track.nSigmaTrkPr(), track.nSigmaTrkDe(), + track.nSigmaTrkTr(), track.nSigmaTrkHe(), track.nSigmaTrkAl()); + } + + fTrackIndexMap[track.globalIndex()] = trackBasic.lastIndex(); + + // Check whether the MCParticle corresponding to this reconstructed track was already selected for skimming + // If not, add it to the skimming map + if (!track.has_mcParticle()) { + trackBarrelLabels(-1, 0, 0); // this is the case when there is no matched MCParticle + } else { + auto mctrack = track.template mcParticle_as(); + VarManager::FillTrackMC(mcTracks, mctrack); + + mcflags = 0; + int i = 0; // runs over the MC signals + int j = 0; // runs over the track cuts + // check all the specified signals and fill histograms for MC truth matched tracks + for (auto& sig : fMCSignals) { + if (sig->CheckSignal(true, mctrack)) { + mcflags |= (static_cast(1) << i); + // If detailed QA is on, fill histograms for each MC signal and track cut combination + if (fDoDetailedQA) { + j = 0; + for (auto& cut : fTrackCuts) { + if (trackTempFilterMap & (uint8_t(1) << j)) { + fHistMan->FillHistClass(Form("TrackBarrel_%s_%s", cut->GetName(), sig->GetName()), VarManager::fgValues); // fill the reconstructed truth + } + j++; + } + } + } + i++; + } + + // if the MC truth particle corresponding to this reconstructed track is not already written, + // add it to the skimmed stack + if (!(fLabelsMap.find(mctrack.globalIndex()) != fLabelsMap.end())) { + fLabelsMap[mctrack.globalIndex()] = trackCounter; + fLabelsMapReversed[trackCounter] = mctrack.globalIndex(); + fMCFlags[mctrack.globalIndex()] = mcflags; + trackCounter++; + } + + trackBarrelLabels(fLabelsMap.find(mctrack.globalIndex())->second, track.mcMask(), mcflags); + } + + trackBarrelAssoc(fCollIndexMap[collision.globalIndex()], fTrackIndexMap[track.globalIndex()]); + } // end loop over associations + } // end skimTracks + + Preslice perMcCollision = aod::mcparticle::mcCollisionId; + Preslice perCollisionTracks = aod::track::collisionId; + + void fullSkimming(MyEvents const& collisions, + MyBarrelTracks const& tracksBarrel, aod::TrackAssoc const& trackAssocs, + MyEventsMC const& mcCollisions, aod::McParticles const& mcParticles) + { + eventMC.reserve(mcCollisions.size()); + skimMCCollisions(mcCollisions); + + // skim collisions + event.reserve(collisions.size()); + eventVtxCov.reserve(collisions.size()); + eventMClabels.reserve(collisions.size()); + eventInfo.reserve(collisions.size()); + + skimCollisions(collisions); + + if (fCollIndexMap.size() == 0) + return; + + skimMCParticles(mcParticles, mcCollisions); + + if constexpr (static_cast(gkTrackFillMapWithCov)) { + fTrackIndexMap.clear(); + trackBasic.reserve(tracksBarrel.size()); + trackBarrel.reserve(tracksBarrel.size()); + trackBarrelCov.reserve(tracksBarrel.size()); + trackPIDTOF.reserve(tracksBarrel.size()); + trackPIDRich.reserve(tracksBarrel.size()); + trackPIDRichSig.reserve(tracksBarrel.size()); + trackPIDOT.reserve(tracksBarrel.size()); + trackBarrelAssoc.reserve(tracksBarrel.size()); + trackBarrelLabels.reserve(tracksBarrel.size()); + } + + if (fCollIndexMap.size() > 0) { + + for (auto const& [origIdx, skimIdx] : fCollIndexMap) { + auto collision = collisions.rawIteratorAt(origIdx); + + if constexpr (static_cast(gkTrackFillMapWithCov)) { + auto groupedTrackIndices = trackAssocs.sliceBy(trackIndicesPerCollision, origIdx); + + skimTracks(collision, tracksBarrel, groupedTrackIndices, mcParticles); + } + } + } + + // Loop over the label map, create the mother/daughter relationships if these exist and write the skimmed MC stack + for (const auto& [newLabel, oldLabel] : fLabelsMapReversed) { + auto mctrack = mcParticles.iteratorAt(oldLabel); + uint16_t mcflags = fMCFlags.find(oldLabel)->second; + + std::vector mothers; + if (mctrack.has_mothers()) { + for (auto& m : mctrack.mothersIds()) { + if (m < mcParticles.size()) { // protect against bad mother indices + if (fLabelsMap.find(m) != fLabelsMap.end()) { + mothers.push_back(fLabelsMap.find(m)->second); + } + } else { + LOG(warn) << "Mother label (" << m << ") exceeds the McParticles size (" << mcParticles.size() << ")"; + LOG(warn) << " Check the MC generator"; + } + } + } + + // TODO: Check that the daughter slice in the skimmed table works as expected + // Note that not all daughters from the original table are preserved in the skimmed MC stack + std::vector daughters; + if (mctrack.has_daughters()) { + for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { + // TODO: remove this check as soon as issues with MC production are fixed + if (d < mcParticles.size()) { // protect against bad daughter indices + if (fLabelsMap.find(d) != fLabelsMap.end()) { + daughters.push_back(fLabelsMap.find(d)->second); + } + } else { + LOG(warn) << "Daughter label (" << d << ") exceeds the McParticles size (" << mcParticles.size() << ")"; + LOG(warn) << " Check the MC generator"; + } + } + } + int daughterRange[2] = {-1, -1}; + if (daughters.size() > 0) { + daughterRange[0] = daughters[0]; + daughterRange[1] = daughters[daughters.size() - 1]; + } + + // NOTE: Here we assume that MC collisions are not filtered, so there is no new vs old index map for translation + auto mcCollision = mctrack.template mcCollision_as(); + trackMC(mcCollision.globalIndex(), mctrack.pdgCode(), mctrack.statusCode(), mctrack.flags(), + mothers, daughterRange, + mctrack.weight(), mctrack.pt(), mctrack.eta(), mctrack.phi(), mctrack.e(), + mctrack.vx(), mctrack.vy(), mctrack.vz(), mctrack.vt(), mcflags); + + for (unsigned int isig = 0; isig < fMCSignals.size(); isig++) { + if (mcflags & (static_cast(1) << isig)) { + (reinterpret_cast(fStatsList->At(2)))->Fill(static_cast(isig)); + } + } + if (mcflags == 0) { + (reinterpret_cast(fStatsList->At(2)))->Fill(static_cast(fMCSignals.size())); + } + } + } + + void processSkimming(MyEvents const& collisions, + MyBarrelTracks const& tracksBarrel, aod::TrackAssoc const& trackAssocs, + MyEventsMC const& mcCollisions, aod::McParticles const& mcParticles) + { + fullSkimming(collisions, tracksBarrel, trackAssocs, mcCollisions, mcParticles); + } + + PROCESS_SWITCH(Alice3DQTableMaker, processSkimming, "Build DQ skimmed data model for ALICE3", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/ALICE3/TableProducer/alice3TrackingTranslator.cxx b/ALICE3/TableProducer/alice3TrackingTranslator.cxx index 94e5f0ef5d1..da8cc107329 100644 --- a/ALICE3/TableProducer/alice3TrackingTranslator.cxx +++ b/ALICE3/TableProducer/alice3TrackingTranslator.cxx @@ -16,6 +16,7 @@ /// \author Nicolò Jacazio, Universita del Piemonte Orientale (IT) /// +#include "ALICE3/DataModel/OTFTracks.h" #include "ALICE3/DataModel/collisionAlice3.h" #include "ALICE3/DataModel/tracksAlice3.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -67,6 +68,9 @@ struct Alice3TrackingTranslator { o2::framework::Produces tableTrackSelectionExtension; o2::framework::Produces tableStoredMcParticles; o2::framework::Produces tableMcCollisions; + o2::framework::Produces tableOTFLUTConfigId; + + o2::framework::Configurable maxCollisions{"maxCollisions", 1000, "Nsigma for TOF PID (if enabled)"}; void init(o2::framework::InitContext&) { @@ -80,6 +84,7 @@ struct Alice3TrackingTranslator { if (mTree->SetBranchAddress(branchname, &branchvar)) { \ LOG(fatal) << "Could not set branch address for " << branchname; \ } + struct FileStruct { FileStruct(std::string filename, std::string treename) : mFile(filename.c_str(), "READ") { @@ -252,6 +257,10 @@ struct Alice3TrackingTranslator { const Long64_t kEvents = fileParticles.getEntries(); for (Long64_t iEvent = 0; iEvent < kEvents; ++iEvent) { + if (iEvent > 0 && iEvent % maxCollisions) { + LOG(info) << "Processing event " << iEvent << "/" << kEvents; + break; + } fileParticles.setEventEntry(iEvent); // fileVertices.setEventEntry(iEvent); fileTracksummary.setEventEntry(iEvent); @@ -265,6 +274,7 @@ struct Alice3TrackingTranslator { float collisionY = 0.0f; float collisionZ = 0.0f; + tableOTFLUTConfigId(0); // dummy for the moment tableCollisions(0, // bcId collisionX, // posX collisionY, // posY @@ -326,6 +336,7 @@ struct Alice3TrackingTranslator { fileTracksummary.m_t_vx->at(iParticle), fileTracksummary.m_t_vy->at(iParticle), fileTracksummary.m_t_vz->at(iParticle)}); + tableStoredMcParticles(tableMcCollisions.lastIndex(), // mcCollisionId fileTracksummary.m_majorityParticlePDG->at(iParticle), // pdgCode 0, // statusCode diff --git a/ALICE3/Tasks/CMakeLists.txt b/ALICE3/Tasks/CMakeLists.txt index 8ae02abe6c7..0a62aafca3f 100644 --- a/ALICE3/Tasks/CMakeLists.txt +++ b/ALICE3/Tasks/CMakeLists.txt @@ -89,6 +89,11 @@ o2physics_add_dpl_workflow(alice3strangeness PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(alice3-dq-efficiency + SOURCES alice3-dq-efficiency.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGDQCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(alice3-decayer-qa SOURCES alice3DecayerQA.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/ALICE3/Tasks/alice3-dq-efficiency.cxx b/ALICE3/Tasks/alice3-dq-efficiency.cxx new file mode 100644 index 00000000000..70ae14c493a --- /dev/null +++ b/ALICE3/Tasks/alice3-dq-efficiency.cxx @@ -0,0 +1,2592 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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 +// alexander.tiekoetter@cern.ch +// Configurable workflow for running several DQ or other PWG analyses + +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/MCSignal.h" +#include "PWGDQ/Core/MCSignalLibrary.h" +#include "PWGDQ/Core/MixingHandler.h" +#include "PWGDQ/Core/MixingLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "PWGDQ/DataModel/ReducedTablesAlice3.h" + +#include "ALICE3/DataModel/OTFPIDTrk.h" +#include "ALICE3/DataModel/OTFRICH.h" +#include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/collisionAlice3.h" +#include "ALICE3/DataModel/tracksAlice3.h" +#include "Common/Core/TableHelper.h" + +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using std::string; + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod; + +// Some definitions +namespace o2::aod +{ +namespace dqanalysisflags +{ +DECLARE_SOA_COLUMN(MixingHash, mixingHash, int); //! Hash used in event mixing //need to understand +DECLARE_SOA_BITMAP_COLUMN(IsEventSelected, isEventSelected, 32); //! Event decision +DECLARE_SOA_BITMAP_COLUMN(IsBarrelSelected, isBarrelSelected, 32); //! Barrel track decisions +DECLARE_SOA_COLUMN(BarrelAmbiguityInBunch, barrelAmbiguityInBunch, int8_t); //! Barrel track in-bunch ambiguity +DECLARE_SOA_COLUMN(BarrelAmbiguityOutOfBunch, barrelAmbiguityOutOfBunch, int8_t); //! Barrel track out of bunch ambiguity +DECLARE_SOA_BITMAP_COLUMN(IsBarrelSelectedPrefilter, isBarrelSelectedPrefilter, 32); //! Barrel prefilter decisions (joinable to ReducedA3TracksAssoc) + +DECLARE_SOA_COLUMN(Massee, massee, float); +DECLARE_SOA_COLUMN(Etaee, etaee, float); +DECLARE_SOA_COLUMN(Rapee, rapee, float); +DECLARE_SOA_COLUMN(Phiee, phiee, float); +DECLARE_SOA_COLUMN(Ptee, ptee, float); +DECLARE_SOA_COLUMN(Lxyee, lxyee, float); +DECLARE_SOA_COLUMN(LxyeePoleMass, lxyeepolemass, float); +DECLARE_SOA_COLUMN(Lzee, lzee, float); +DECLARE_SOA_COLUMN(MultiplicityFT0A, multiplicityFT0AJPsi2ee, float); +DECLARE_SOA_COLUMN(MultiplicityFT0C, multiplicityFT0CJPsi2ee, float); +DECLARE_SOA_COLUMN(PercentileFT0M, percentileFT0MJPsi2ee, float); +DECLARE_SOA_COLUMN(MultiplicityNContrib, multiplicityNContribJPsi2ee, float); +DECLARE_SOA_COLUMN(AmbiguousInBunchPairs, AmbiguousJpsiPairsInBunch, bool); +DECLARE_SOA_COLUMN(AmbiguousOutOfBunchPairs, AmbiguousJpsiPairsOutOfBunch, bool); +DECLARE_SOA_COLUMN(Corrassoc, corrassoc, bool); +DECLARE_SOA_COLUMN(DeltaEta, deltaEta, float); +DECLARE_SOA_COLUMN(DeltaPhi, deltaPhi, float); +// Candidate columns efficiency calculation for prompt-non-prompt JPsi separation +DECLARE_SOA_COLUMN(OniaPt, oniaPt, float); +DECLARE_SOA_COLUMN(OniaY, oniaY, float); +DECLARE_SOA_COLUMN(OniaEta, oniaEta, float); +DECLARE_SOA_COLUMN(OniaPhi, oniaPhi, float); +DECLARE_SOA_COLUMN(OniaVz, oniaVz, float); +DECLARE_SOA_COLUMN(OniaVtxZ, oniaVtxZ, float); +} // namespace dqanalysisflags + +DECLARE_SOA_TABLE(EventCuts, "AOD", "DQANAEVCUTS", dqanalysisflags::IsEventSelected); //! joinable to ReducedEvents +DECLARE_SOA_TABLE(MixingHashes, "AOD", "DQANAMIXHASHA", dqanalysisflags::MixingHash); //! joinable to ReducedEvents +DECLARE_SOA_TABLE(BarrelTrackCuts, "AOD", "DQANATRKCUTS", dqanalysisflags::IsBarrelSelected); //! joinable to ReducedA3TracksAssoc +DECLARE_SOA_TABLE(BarrelAmbiguities, "AOD", "DQBARRELAMB", dqanalysisflags::BarrelAmbiguityInBunch, dqanalysisflags::BarrelAmbiguityOutOfBunch); //! joinable to ReducedBarrelTracks +DECLARE_SOA_TABLE(Prefilter, "AOD", "DQPREFILTER", dqanalysisflags::IsBarrelSelectedPrefilter); //! joinable to ReducedA3TracksAssoc + +DECLARE_SOA_TABLE(JPsieeCandidates, "AOD", "DQPSEUDOPROPER", dqanalysisflags::Massee, dqanalysisflags::Ptee, dqanalysisflags::Etaee, dqanalysisflags::Rapee, dqanalysisflags::Phiee, dqanalysisflags::Lxyee, dqanalysisflags::LxyeePoleMass, dqanalysisflags::Lzee, dqanalysisflags::AmbiguousInBunchPairs, dqanalysisflags::AmbiguousOutOfBunchPairs, dqanalysisflags::Corrassoc, dqanalysisflags::MultiplicityFT0A, dqanalysisflags::MultiplicityFT0C, dqanalysisflags::PercentileFT0M, dqanalysisflags::MultiplicityNContrib); +DECLARE_SOA_TABLE(OniaMCTruth, "AOD", "MCTRUTHONIA", dqanalysisflags::OniaPt, dqanalysisflags::OniaEta, dqanalysisflags::OniaY, dqanalysisflags::OniaPhi, dqanalysisflags::OniaVz, dqanalysisflags::OniaVtxZ, dqanalysisflags::MultiplicityFT0A, dqanalysisflags::MultiplicityFT0C, dqanalysisflags::PercentileFT0M, dqanalysisflags::MultiplicityNContrib); + +} // namespace o2::aod + +// TODO: USE PROPER TABLES + +using MyEvents = soa::Join; +using MyEventsSelected = soa::Join; +using MyEventsVtxCov = soa::Join; +using MyEventsVtxCovSelected = soa::Join; + +using MyBarrelAssocs = soa::Join; +using MyBarrelAssocsPrefilter = soa::Join; + +using MyBarrelTracks = soa::Join; + +using MyBarrelTracksWithCov = soa::Join; + +using MyBarrelTracksWithCovWithAmbiguities = soa::Join; + +constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::ReducedEvent; +constexpr static uint32_t gkEventFillMapWithCov = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventVtxCov; + +constexpr static uint32_t gkTrackFillMapWithCov = VarManager::ObjTypes::ReducedTrack | VarManager::ObjTypes::ReducedTrackBarrel | VarManager::ObjTypes::ReducedTrackBarrelCov | VarManager::ObjTypes::ReducedTrackBarrelPID; +constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::ReducedTrack | VarManager::ObjTypes::ReducedTrackBarrel | VarManager::ObjTypes::ReducedTrackBarrelPID; + +// Global function used to define needed histogram classes +void DefineHistograms(HistogramManager* histMan, TString histClasses, const char* histGroups); // defines histograms for all tasks + +// Analysis task that produces event decisions and the Hash table used in event mixing +struct AnalysisEventSelection { + Produces eventSel; + Produces hash; + OutputObj fOutputList{"output"}; + Configurable fConfigMixingVariables{"cfgMixingVars", "", "Mixing configs separated by a comma, default no mixing"}; + Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; + Configurable fConfigEventCutsJSON{"cfgEventCutsJSON", "", "Additional event cuts specified in JSON format"}; + Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddEventMCHistogram{"cfgAddEventMCHistogram", "generator", "Comma separated list of histograms"}; + Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Add event histograms defined via JSON formatting (see HistogramsLibrary)"}; + + HistogramManager* fHistMan = nullptr; + MixingHandler* fMixHandler = nullptr; + + AnalysisCompositeCut* fEventCut; + + std::map fSelMap; // key: reduced event global index, value: event selection decision + + void init(o2::framework::InitContext& context) + { + if (context.mOptions.get("processDummy")) { + return; + } + VarManager::SetDefaultVarNames(); + + fEventCut = new AnalysisCompositeCut(true); + TString eventCutStr = fConfigEventCuts.value; + if (eventCutStr != "") { + AnalysisCut* cut = dqcuts::GetAnalysisCut(eventCutStr.Data()); + if (cut != nullptr) { + fEventCut->AddCut(cut); + } + } + // Additional cuts via JSON + TString eventCutJSONStr = fConfigEventCutsJSON.value; + if (eventCutJSONStr != "") { + std::vector jsonCuts = dqcuts::GetCutsFromJSON(eventCutJSONStr.Data()); + for (auto& cutIt : jsonCuts) { + fEventCut->AddCut(cutIt); + } + } + + VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill + + if (fConfigQA) { + fHistMan = new HistogramManager("analysisHistos", "", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + DefineHistograms(fHistMan, "Event_BeforeCuts;Event_AfterCuts;", fConfigAddEventHistogram.value.data()); + DefineHistograms(fHistMan, "EventsMC", fConfigAddEventMCHistogram.value.data()); + dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // aditional histograms via JSON + VarManager::SetUseVars(fHistMan->GetUsedVars()); + fOutputList.setObject(fHistMan->GetMainHistogramList()); + } + + TString mixVarsString = fConfigMixingVariables.value; + std::unique_ptr objArray(mixVarsString.Tokenize(",")); + if (objArray->GetEntries() > 0) { + fMixHandler = new MixingHandler("mixingHandler", "mixing handler"); + fMixHandler->Init(); + for (int iVar = 0; iVar < objArray->GetEntries(); ++iVar) { + dqmixing::SetUpMixing(fMixHandler, objArray->At(iVar)->GetName()); + } + } + } + + void runEventSelection(MyEventsVtxCov const& events, ReducedA3MCEvents const& mcEvents) + { + fSelMap.clear(); + + for (auto& event : events) { + // Reset the fValues array and fill event observables + VarManager::ResetValues(0, VarManager::kNEventWiseVariables); + VarManager::FillEventAlice3(event); + if (event.has_reducedA3MCEvent()) { + VarManager::FillEventAlice3(event.reducedA3MCEvent()); + } + + bool decision = false; + // if QA is requested fill histograms before event selections + if (fConfigQA) { + fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); // automatically fill all the histograms in the class Event + } + if (fEventCut->IsSelected(VarManager::fgValues)) { + if (fConfigQA) { + fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); + } + decision = true; + } + fSelMap[event.globalIndex()] = decision; + if (fMixHandler != nullptr) { + int hh = fMixHandler->FindEventCategory(VarManager::fgValues); + hash(hh); + } + } + + for (auto& event : mcEvents) { + // Reset the fValues array and fill event observables + VarManager::ResetValues(0, VarManager::kNEventWiseVariables); + VarManager::FillEventAlice3(event); + if (fConfigQA) { + fHistMan->FillHistClass("EventsMC", VarManager::fgValues); + } + } + } + + void publishSelections(MyEventsVtxCov const& events) + { + // publish the table + uint32_t evSel = static_cast(0); + for (auto& event : events) { + evSel = 0; + if (fSelMap[event.globalIndex()]) { // event passed the user cuts + evSel |= (static_cast(1) << 0); + } + eventSel(evSel); + } + } + + void processSkimmed(MyEventsVtxCov const& events, aod::ReducedA3MCEvents const& mcEvents) + { + runEventSelection(events, mcEvents); + publishSelections(events); + } + + void processDummy(MyEventsVtxCov const&) + { + // do nothing + } + + PROCESS_SWITCH(AnalysisEventSelection, processSkimmed, "Run event selection on DQ skimmed events", false); + PROCESS_SWITCH(AnalysisEventSelection, processDummy, "Dummy function", true); +}; + +// Produces a table with barrel track decisions (joinable to the ReducedA3TracksAssociations) +// Here one should add all the track cuts needed through the workflow (e.g. cuts for same-even pairing, electron prefiltering, track for dilepton-track correlations) +struct AnalysisTrackSelection { + Produces trackSel; + Produces trackAmbiguities; + OutputObj fOutputList{"output"}; + + Configurable fConfigCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigCutsJSON{"cfgBarrelTrackCutsJSON", "", "Additional list of barrel track cuts in JSON format"}; + Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; + Configurable fConfigPublishAmbiguity{"cfgPublishAmbiguity", true, "If true, publish ambiguity table and fill QA histograms"}; + + Configurable fConfigMCSignals{"cfgTrackMCSignals", "", "Comma separated list of MC signals"}; + Configurable fConfigMCSignalsJSON{"cfgTrackMCsignalsJSON", "", "Additional list of MC signals via JSON"}; + + HistogramManager* fHistMan; + std::vector fTrackCuts; + std::vector fMCSignals; // list of signals to be checked + std::vector fHistNamesReco; + std::vector fHistNamesMCMatched; + + std::map> fNAssocsInBunch; // key: track global index, value: vector of global index for events associated in-bunch (events that have in-bunch pileup or splitting) + std::map> fNAssocsOutOfBunch; // key: track global index, value: vector of global index for events associated out-of-bunch (events that have no in-bunch pileup) + + void init(o2::framework::InitContext& context) + { + if (context.mOptions.get("processDummy")) { + return; + } + VarManager::SetDefaultVarNames(); + + 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())); + } + } + // add extra cuts from JSON + TString addTrackCutsStr = fConfigCutsJSON.value; + if (addTrackCutsStr != "") { + std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); + for (auto& t : addTrackCuts) { + fTrackCuts.push_back(reinterpret_cast(t)); + } + } + VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill + + TString configSigNamesStr = fConfigMCSignals.value; + std::unique_ptr sigNamesArray(configSigNamesStr.Tokenize(",")); + // Setting the MC signals + for (int isig = 0; isig < sigNamesArray->GetEntries(); ++isig) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(sigNamesArray->At(isig)->GetName()); + if (sig) { + if (sig->GetNProngs() != 1) { // NOTE: only 1 prong signals + continue; + } + fMCSignals.push_back(sig); + } + } + // Add the MCSignals from the JSON config + TString addMCSignalsStr = fConfigMCSignalsJSON.value; + if (addMCSignalsStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); + for (auto& mcIt : addMCSignals) { + if (mcIt->GetNProngs() != 1) { // NOTE: only 1 prong signals + continue; + } + fMCSignals.push_back(mcIt); + } + } + + if (fConfigQA) { + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + // Configure histogram classes for each track cut; + // Add histogram classes for each track cut and for each requested MC signal (reconstructed tracks with MC truth) + TString histClasses = "AssocsBarrel_BeforeCuts;"; + for (auto& cut : fTrackCuts) { + TString nameStr = Form("AssocsBarrel_%s", cut->GetName()); + fHistNamesReco.push_back(nameStr); + histClasses += Form("%s;", nameStr.Data()); + for (auto& sig : fMCSignals) { + TString nameStr2 = Form("AssocsCorrectBarrel_%s_%s", cut->GetName(), sig->GetName()); + fHistNamesMCMatched.push_back(nameStr2); + histClasses += Form("%s;", nameStr2.Data()); + nameStr2 = Form("AssocsIncorrectBarrel_%s_%s", cut->GetName(), sig->GetName()); + fHistNamesMCMatched.push_back(nameStr2); + histClasses += Form("%s;", nameStr2.Data()); + } + } + + DefineHistograms(fHistMan, histClasses.Data(), fConfigAddTrackHistogram.value.data()); + if (fConfigPublishAmbiguity) { + DefineHistograms(fHistMan, "TrackBarrel_AmbiguityInBunch;TrackBarrel_AmbiguityOutOfBunch;", "ambiguity"); + } + dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + } + } + + void runTrackSelection(ReducedA3TracksAssoc const& assocs, MyEventsVtxCovSelected const& /*events*/, MyBarrelTracksWithCov const& tracks, ReducedA3MCEvents const& /*eventsMC*/, ReducedA3MCTracks const& tracksMC) + { + fNAssocsInBunch.clear(); + fNAssocsOutOfBunch.clear(); + + trackSel.reserve(assocs.size()); + trackAmbiguities.reserve(tracks.size()); + + // Loop over associations + for (auto& assoc : assocs) { + auto event = assoc.template reducedA3event_as(); + if (!event.isEventSelected_bit(0)) { + trackSel(0); + continue; + } + + VarManager::ResetValues(0, VarManager::kNBarrelTrackVariables); + // fill event information which might be needed in histograms/cuts that combine track and event properties + VarManager::FillEventAlice3(event); + if (event.has_reducedA3MCEvent()) { + VarManager::FillEventAlice3(event.reducedA3MCEvent()); + } + + auto track = assoc.template reducedA3track_as(); + VarManager::FillTrackAlice3(track); + // compute quantities which depend on the associated collision, such as DCA + VarManager::FillTrackCollision(track, event); + + bool isCorrectAssoc = false; + if (track.has_reducedA3MCTrack()) { + auto trackMC = track.reducedA3MCTrack(); + auto eventMCfromTrack = trackMC.reducedA3MCEvent(); + if (event.has_reducedA3MCEvent()) { + isCorrectAssoc = (eventMCfromTrack.globalIndex() == event.reducedA3MCEvent().globalIndex()); + } + VarManager::FillTrackMC(tracksMC, trackMC); + } + + if (fConfigQA) { + fHistMan->FillHistClass("AssocsBarrel_BeforeCuts", VarManager::fgValues); + } + + int iCut = 0; + uint32_t filterMap = static_cast(0); + for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, iCut++) { + if ((*cut)->IsSelected(VarManager::fgValues)) { + filterMap |= (static_cast(1) << iCut); + if (fConfigQA) { + fHistMan->FillHistClass(fHistNamesReco[iCut], VarManager::fgValues); + } + } + } // end loop over cuts + trackSel(filterMap); + + // compute MC matching decisions and fill histograms for matched associations + int isig = 0; + if (filterMap > 0 && track.has_reducedA3MCTrack()) { + // loop over all MC signals + for (auto sig = fMCSignals.begin(); sig != fMCSignals.end(); sig++, isig++) { + // check if this MC signal is matched + if ((*sig)->CheckSignal(true, track.reducedA3MCTrack())) { + // mcDecision |= (static_cast(1) << isig); + // loop over cuts and fill histograms for the cuts that are fulfilled + for (unsigned int icut = 0; icut < fTrackCuts.size(); icut++) { + if (filterMap & (static_cast(1) << icut)) { + if (isCorrectAssoc) { + fHistMan->FillHistClass(fHistNamesMCMatched[icut * 2 * fMCSignals.size() + 2 * isig].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(fHistNamesMCMatched[icut * 2 * fMCSignals.size() + 2 * isig + 1].Data(), VarManager::fgValues); + } + } + } // end loop over cuts + } + } + } // end if (filterMap > 0) + + // count the number of associations per track + if (fConfigPublishAmbiguity && filterMap > 0) { + if (event.isEventSelected_bit(1)) { + // for this track, count the number of associated collisions with in-bunch pileup and out of bunch associations + if (fNAssocsInBunch.find(track.globalIndex()) == fNAssocsInBunch.end()) { + std::vector evVector = {event.globalIndex()}; + fNAssocsInBunch[track.globalIndex()] = evVector; + } else { + auto& evVector = fNAssocsInBunch[track.globalIndex()]; + evVector.push_back(event.globalIndex()); + } + } else { + if (fNAssocsOutOfBunch.find(track.globalIndex()) == fNAssocsOutOfBunch.end()) { + std::vector evVector = {event.globalIndex()}; + fNAssocsOutOfBunch[track.globalIndex()] = evVector; + } else { + auto& evVector = fNAssocsOutOfBunch[track.globalIndex()]; + evVector.push_back(event.globalIndex()); + } + } + } + } // end loop over associations + + // QA the collision-track associations + // TODO: some tracks can be associated to both collisions that have in bunch pileup and collisions from different bunches + // So one could QA these tracks separately + if (fConfigPublishAmbiguity) { + if (fConfigQA) { + for (auto& [trackIdx, evIndices] : fNAssocsInBunch) { + if (evIndices.size() == 1) { + continue; + } + auto track = tracks.rawIteratorAt(trackIdx); + VarManager::ResetValues(0, VarManager::kNBarrelTrackVariables); + VarManager::FillTrackAlice3(track); + VarManager::fgValues[VarManager::kBarrelNAssocsInBunch] = static_cast(evIndices.size()); + fHistMan->FillHistClass("TrackBarrel_AmbiguityInBunch", VarManager::fgValues); + } // end loop over in-bunch ambiguous tracks + + for (auto& [trackIdx, evIndices] : fNAssocsOutOfBunch) { + if (evIndices.size() == 1) { + continue; + } + auto track = tracks.rawIteratorAt(trackIdx); + VarManager::ResetValues(0, VarManager::kNBarrelTrackVariables); + VarManager::FillTrackAlice3(track); + VarManager::fgValues[VarManager::kBarrelNAssocsOutOfBunch] = static_cast(evIndices.size()); + fHistMan->FillHistClass("TrackBarrel_AmbiguityOutOfBunch", VarManager::fgValues); + } // end loop over out-of-bunch ambiguous tracks + } + + // publish the ambiguity table + for (auto& track : tracks) { + int8_t nInBunch = 0; + if (fNAssocsInBunch.find(track.globalIndex()) != fNAssocsInBunch.end()) { + nInBunch = fNAssocsInBunch[track.globalIndex()].size(); + } + int8_t nOutOfBunch = 0; + if (fNAssocsOutOfBunch.find(track.globalIndex()) != fNAssocsOutOfBunch.end()) { + nOutOfBunch = fNAssocsOutOfBunch[track.globalIndex()].size(); + } + trackAmbiguities(nInBunch, nOutOfBunch); + } + } + } // end runTrackSelection() + + void processSkimmedWithCov(ReducedA3TracksAssoc const& assocs, MyEventsVtxCovSelected const& events, MyBarrelTracksWithCov const& tracks, ReducedA3MCEvents const& eventsMC, ReducedA3MCTracks const& tracksMC) + { + runTrackSelection(assocs, events, tracks, eventsMC, tracksMC); + } + + void processDummy(MyEvents const&) + { + // do nothing + } + + PROCESS_SWITCH(AnalysisTrackSelection, processSkimmedWithCov, "Run barrel track selection on DQ skimmed tracks w/ cov matrix associations", false); + PROCESS_SWITCH(AnalysisTrackSelection, processDummy, "Dummy function", true); +}; + +struct AnalysisPrefilterSelection { + Produces prefilter; // joinable with ReducedA3TracksAssoc + + // Configurables + Configurable fConfigPrefilterTrackCut{"cfgPrefilterTrackCut", "", "Prefilter track cut"}; + Configurable fConfigPrefilterPairCut{"cfgPrefilterPairCut", "", "Prefilter pair cut"}; + Configurable fConfigTrackCuts{"cfgTrackCuts", "", "Track cuts for which to run the prefilter"}; + // Track related options + Configurable fPropTrack{"cfgPropTrack", false, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; + + std::map fPrefilterMap; + AnalysisCompositeCut* fPairCut; + uint32_t fPrefilterMask; + int fPrefilterCutBit; + + PresliceUnsorted trackAssocsPerCollision = aod::reducedA3track_association::reducedA3eventId; + + void init(o2::framework::InitContext& context) + { + if (context.mOptions.get("processDummy")) { + return; + } + + bool runPrefilter = true; + // get the list of track cuts to be prefiltered + TString trackCutsStr = fConfigTrackCuts.value; + TObjArray* objArrayTrackCuts = nullptr; + if (!trackCutsStr.IsNull()) { + objArrayTrackCuts = trackCutsStr.Tokenize(","); + if (objArrayTrackCuts == nullptr) { + runPrefilter = false; + } + } else { + LOG(warn) << " No track cuts to prefilter! Prefilter will not be run"; + runPrefilter = false; + } + // get the cut to be used as loose selection + TString prefilterTrackCutStr = fConfigPrefilterTrackCut.value; + if (prefilterTrackCutStr.IsNull()) { + LOG(warn) << " No prefilter loose selection specified! Prefilter will not be run"; + runPrefilter = false; + } + + fPrefilterMask = 0; + fPrefilterCutBit = -1; + if (runPrefilter) { + // get the list of cuts that were computed in the barrel track-selection task and create a bit mask + // to mark just the ones we want to apply a prefilter on + string trackCuts; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", trackCuts, false); + TString allTrackCutsStr = trackCuts; + // check also the cuts added via JSON and add them to the string of cuts + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", trackCuts, false); + TString addTrackCutsStr = trackCuts; + if (addTrackCutsStr != "") { + std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); + for (auto& t : addTrackCuts) { + allTrackCutsStr += Form(",%s", t->GetName()); + } + } + + std::unique_ptr objArray(allTrackCutsStr.Tokenize(",")); + if (objArray == nullptr) { + LOG(fatal) << " Not getting any track cuts from the barrel-track-selection "; + } + if (objArray->FindObject(prefilterTrackCutStr.Data()) == nullptr) { + LOG(fatal) << " Prefilter track cut not among the cuts calculated by the track-selection task! "; + } + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + TString tempStr = objArray->At(icut)->GetName(); + if (objArrayTrackCuts->FindObject(tempStr.Data()) != nullptr) { + fPrefilterMask |= (static_cast(1) << icut); + } + if (tempStr.CompareTo(fConfigPrefilterTrackCut.value) == 0) { + fPrefilterCutBit = icut; + } + } + // setup the prefilter pair cut + fPairCut = new AnalysisCompositeCut(true); + TString pairCutStr = fConfigPrefilterPairCut.value; + if (!pairCutStr.IsNull()) { + fPairCut = dqcuts::GetCompositeCut(pairCutStr.Data()); + } + } + if (fPrefilterMask == static_cast(0) || fPrefilterCutBit < 0) { + LOG(warn) << "No specified loose cut or track cuts for prefiltering. This task will do nothing."; + } + + VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetDefaultVarNames(); + + VarManager::SetupTwoProngDCAFitter(5.0f, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, true); // TODO: get these parameters from Configurables + VarManager::SetupTwoProngFwdDCAFitter(5.0f, true, 200.0f, 1.0e-3f, 0.9f, true); + } + + void runPrefilter(MyEvents::iterator const& event, MyBarrelAssocs const& assocs, MyBarrelTracks const& /*tracks*/) + { + if (fPrefilterCutBit < 0 || fPrefilterMask == 0) { + return; + } + + for (auto& [assoc1, assoc2] : o2::soa::combinations(assocs, assocs)) { + auto track1 = assoc1.template reducedA3track_as(); + auto track2 = assoc2.template reducedA3track_as(); + + // NOTE: here we restrict to just pairs of opposite sign (conversions), but in principle this can be made + // a configurable and check also same-sign pairs (track splitting) + if (track1.sign() * track2.sign() > 0) { + continue; + } + + // here we check the cuts fulfilled by both tracks, for both the tight and loose selections + uint32_t track1Candidate = (assoc1.isBarrelSelected_raw() & fPrefilterMask); + uint32_t track2Candidate = (assoc2.isBarrelSelected_raw() & fPrefilterMask); + bool track1Loose = assoc1.isBarrelSelected_bit(fPrefilterCutBit); + bool track2Loose = assoc2.isBarrelSelected_bit(fPrefilterCutBit); + + if (!((track1Candidate > 0 && track2Loose) || (track2Candidate > 0 && track1Loose))) { + continue; + } + + // compute pair quantities + VarManager::FillPairAlice3(track1, track2); + if (fPropTrack) { + VarManager::FillPairCollision(event, track1, track2); + } + // if the pair fullfils the criteria, add an entry into the prefilter map for the two tracks + if (fPairCut->IsSelected(VarManager::fgValues)) { + if (fPrefilterMap.find(track1.globalIndex()) == fPrefilterMap.end() && track1Candidate > 0) { + fPrefilterMap[track1.globalIndex()] = track1Candidate; + } + if (fPrefilterMap.find(track2.globalIndex()) == fPrefilterMap.end() && track2Candidate > 0) { + fPrefilterMap[track2.globalIndex()] = track2Candidate; + } + } + } // end loop over combinations + } + + void processBarrelSkimmed(MyEvents const& events, MyBarrelAssocs const& assocs, MyBarrelTracks const& tracks) + { + + fPrefilterMap.clear(); + + for (auto& event : events) { + auto groupedAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); + if (groupedAssocs.size() > 1) { + runPrefilter(event, groupedAssocs, tracks); + } + } + + uint32_t mymap = -1; + // If cuts were not configured, then produce a map with all 1's and publish it for all associations + if (fPrefilterCutBit < 0 || fPrefilterMask == 0) { + for (int i = 0; i < assocs.size(); ++i) { + prefilter(mymap); + } + } else { + for (auto& assoc : assocs) { + // TODO: just use the index from the assoc (no need to cast the whole track) + auto track = assoc.template reducedA3track_as(); + mymap = -1; + if (fPrefilterMap.find(track.globalIndex()) != fPrefilterMap.end()) { + // NOTE: publish the bitwise negated bits (~), so there will be zeroes for cuts that failed the prefiltering and 1 everywhere else + mymap = ~fPrefilterMap[track.globalIndex()]; + prefilter(mymap); + } else { + prefilter(mymap); // track did not pass the prefilter selections, so publish just 1's + } + } + } + } + + void processDummy(MyEvents const&) + { + // do nothing + } + + PROCESS_SWITCH(AnalysisPrefilterSelection, processBarrelSkimmed, "Run Prefilter selection on reduced tracks", false); + PROCESS_SWITCH(AnalysisPrefilterSelection, processDummy, "Do nothing", true); +}; + +// Run the same-event pairing +// This task assumes that both legs of the resonance fulfill the same cuts (symmetric decay channel) +// Runs combinatorics for barrel-barrel combinations +// The task implements also process functions for running event mixing +struct AnalysisSameEventPairing { + + Produces dielectronList; + Produces dielectronsExtraList; + Produces dielectronAllList; + Produces dileptonMiniTreeGen; + Produces dileptonMiniTreeRec; + Produces PromptNonPromptSepTable; + Produces MCTruthTableEffi; + + o2::base::MatLayerCylSet* fLUT = nullptr; + OutputObj fOutputList{"output"}; + + struct : ConfigurableGroup { + Configurable track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track 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"}; + // TODO: Add pair cuts via JSON + } fConfigCuts; + + Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigAddSEPHistogram{"cfgAddSEPHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; + + struct : ConfigurableGroup { + 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 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"}; + Configurable corrFullGeo{"cfgCorrFullGeo", false, "Use full geometry to correct for MCS effects in track propagation"}; + Configurable noCorr{"cfgNoCorrFwdProp", false, "Do not correct for MCS effects in track propagation"}; + Configurable collisionSystem{"syst", "pp", "Collision system, pp or PbPb"}; + Configurable centerMassEnergy{"energy", 13600, "Center of mass energy in GeV"}; + } fConfigOptions; + + struct : ConfigurableGroup { + Configurable genSignals{"cfgBarrelMCGenSignals", "", "Comma separated list of MC signals (generated)"}; + Configurable genSignalsJSON{"cfgMCGenSignalsJSON", "", "Additional list of MC signals (generated) via JSON"}; + Configurable recSignals{"cfgBarrelMCRecSignals", "", "Comma separated list of MC signals (reconstructed)"}; + Configurable recSignalsJSON{"cfgMCRecSignalsJSON", "", "Comma separated list of MC signals (reconstructed) via JSON"}; + Configurable skimSignalOnly{"cfgSkimSignalOnly", false, "Configurable to select only matched candidates"}; + } fConfigMC; + + struct : ConfigurableGroup { + Configurable fConfigMiniTree{"useMiniTree.cfgMiniTree", false, "Produce a single flat table with minimal information for analysis"}; + Configurable fConfigMiniTreeMinMass{"useMiniTree.cfgMiniTreeMinMass", 2, "Min. mass cut for minitree"}; + Configurable fConfigMiniTreeMaxMass{"useMiniTree.cfgMiniTreeMaxMass", 5, "Max. mass cut for minitree"}; + } useMiniTree; + + // Track related options + Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; + + // Filter filterEventSelected = aod::dqanalysisflags::isEventSelected & uint32_t(1); + Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); + + HistogramManager* fHistMan; + + // keep histogram class names in maps, so we don't have to buld their names in the pair loops + std::map> fTrackHistNames; + std::map> fBarrelHistNamesMCmatched; + std::vector fRecMCSignals; + std::vector fGenMCSignals; + + std::vector fPairCuts; + AnalysisCompositeCut fMCGenAccCut; + bool fUseMCGenAccCut = false; + + uint32_t fTrackFilterMask; // mask for the track cuts required in this task to be applied on the barrel cuts produced upstream + int fNCutsBarrel; + int fNPairCuts; + bool fHasTwoProngGenMCsignals = false; + + bool fEnableBarrelHistos; + + PresliceUnsorted trackAssocsPerCollision = aod::reducedA3track_association::reducedA3eventId; + + void init(o2::framework::InitContext& context) + { + if (context.mOptions.get("processDummy")) { + return; + } + bool isMCGen = context.mOptions.get("processMCGen") || context.mOptions.get("processMCGenWithGrouping") || context.mOptions.get("processBarrelOnlySkimmed"); + VarManager::SetDefaultVarNames(); + + fEnableBarrelHistos = context.mOptions.get("processBarrelOnlySkimmed"); + + // Keep track of all the histogram class names to avoid composing strings in the pairing loop + TString histNames = ""; + TString cutNamesStr = fConfigCuts.pair.value; + if (!cutNamesStr.IsNull()) { + std::unique_ptr objArray(cutNamesStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + fPairCuts.push_back(*dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); + } + } + + // get the list of cuts for tracks, check that they were played by the barrel selection tasks + // and make a mask for active cuts (barrel selection tasks may run more cuts, needed for other analyses) + TString trackCutsStr = fConfigCuts.track.value; + TObjArray* objArrayTrackCuts = nullptr; + if (!trackCutsStr.IsNull()) { + objArrayTrackCuts = trackCutsStr.Tokenize(","); + } + + // Setting the MC rec signal names + TString sigNamesStr = fConfigMC.recSignals.value; + std::unique_ptr objRecSigArray(sigNamesStr.Tokenize(",")); + for (int isig = 0; isig < objRecSigArray->GetEntries(); ++isig) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objRecSigArray->At(isig)->GetName()); + if (sig) { + if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required + continue; + } + fRecMCSignals.push_back(sig); + } + } + + // Add the MCSignals from the JSON config + TString addMCSignalsStr = fConfigMC.recSignalsJSON.value; + if (addMCSignalsStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); + for (auto& mcIt : addMCSignals) { + if (mcIt->GetNProngs() != 2) { // NOTE: only 2 prong signals + continue; + } + fRecMCSignals.push_back(mcIt); + } + } + + // get the barrel track selection cuts + string tempCuts; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); + TString tempCutsStr = tempCuts; + // check also the cuts added via JSON and add them to the string of cuts + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempCuts, false); + TString addTrackCutsStr = tempCuts; + if (addTrackCutsStr != "") { + std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); + for (auto& t : addTrackCuts) { + tempCutsStr += Form(",%s", t->GetName()); + } + } + + // 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 + std::unique_ptr objArray(tempCutsStr.Tokenize(",")); + fNCutsBarrel = objArray->GetEntries(); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + TString tempStr = objArray->At(icut)->GetName(); + // if the current barrel selection cut is required in this task, then switch on the corresponding bit in the mask + // and assign histogram directories + if (objArrayTrackCuts->FindObject(tempStr.Data()) != nullptr) { + fTrackFilterMask |= (static_cast(1) << icut); + + if (fEnableBarrelHistos) { + // assign the pair hist directories for the current cut + std::vector names = { + Form("PairsBarrelSEPM_%s", objArray->At(icut)->GetName()), + Form("PairsBarrelSEPP_%s", objArray->At(icut)->GetName()), + Form("PairsBarrelSEMM_%s", objArray->At(icut)->GetName())}; + if (fConfigQA) { + // assign separate hist directories for ambiguous tracks + names.push_back(Form("PairsBarrelSEPM_ambiguousInBunch_%s", objArray->At(icut)->GetName())); + names.push_back(Form("PairsBarrelSEPP_ambiguousInBunch_%s", objArray->At(icut)->GetName())); + names.push_back(Form("PairsBarrelSEMM_ambiguousInBunch_%s", objArray->At(icut)->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunch_%s", objArray->At(icut)->GetName())); + names.push_back(Form("PairsBarrelSEPP_ambiguousOutOfBunch_%s", objArray->At(icut)->GetName())); + names.push_back(Form("PairsBarrelSEMM_ambiguousOutOfBunch_%s", objArray->At(icut)->GetName())); + } + for (auto& n : names) { + histNames += Form("%s;", n.Data()); + } + fTrackHistNames[icut] = names; + + // if there are pair cuts specified, assign hist directories for each barrel cut - pair cut combination + // NOTE: This could possibly lead to large histogram outputs. It is strongly advised to use pair cuts only + // if you know what you are doing. + TString cutNamesStr = fConfigCuts.pair.value; + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + fNPairCuts = objArrayPair->GetEntries(); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + names = { + Form("PairsBarrelSEPM_%s_%s", objArray->At(icut)->GetName(), objArrayPair->At(iPairCut)->GetName()), + Form("PairsBarrelSEPP_%s_%s", objArray->At(icut)->GetName(), objArrayPair->At(iPairCut)->GetName()), + Form("PairsBarrelSEMM_%s_%s", objArray->At(icut)->GetName(), objArrayPair->At(iPairCut)->GetName())}; + histNames += Form("%s;%s;%s;", names[0].Data(), names[1].Data(), names[2].Data()); + // NOTE: In the numbering scheme for the map key, we use the number of barrel cuts in the barrel-track selection task + fTrackHistNames[fNCutsBarrel + icut * fNPairCuts + iPairCut] = names; + } // end loop (pair cuts) + } // end if (pair cuts) + + // assign hist directories for the MC matched pairs for each (track cut,MCsignal) combination + if (!sigNamesStr.IsNull()) { + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { + auto sig = fRecMCSignals.at(isig); + names = { + Form("PairsBarrelSEPM_%s_%s", objArray->At(icut)->GetName(), sig->GetName()), + Form("PairsBarrelSEPP_%s_%s", objArray->At(icut)->GetName(), sig->GetName()), + Form("PairsBarrelSEMM_%s_%s", objArray->At(icut)->GetName(), sig->GetName())}; + if (fConfigQA) { + names.push_back(Form("PairsBarrelSEPMCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPMIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousInBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousInBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousInBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunch_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); + } + for (auto& n : names) { + histNames += Form("%s;", n.Data()); + } + fBarrelHistNamesMCmatched.try_emplace(icut * fRecMCSignals.size() + isig, names); + } // end loop over MC signals + } + } // end if enableBarrelHistos + } + } + } + + // 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; + std::unique_ptr objGenSigArray(sigGenNamesStr.Tokenize(",")); + for (int isig = 0; isig < objGenSigArray->GetEntries(); isig++) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objGenSigArray->At(isig)->GetName()); + if (sig) { + fGenMCSignals.push_back(sig); + } + } + + // Add the MCSignals from the JSON config + TString addMCSignalsGenStr = fConfigMC.genSignalsJSON.value; + if (addMCSignalsGenStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsGenStr.Data()); + for (auto& mcIt : addMCSignals) { + if (mcIt->GetNProngs() > 2) { // NOTE: only 2 prong signals + continue; + } + fGenMCSignals.push_back(mcIt); + } + } + + if (isMCGen) { + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() == 1) { + histNames += Form("MCTruthGen_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function + histNames += Form("MCTruthGenSel_%s;", sig->GetName()); + } else if (sig->GetNProngs() == 2) { + histNames += Form("MCTruthGenPair_%s;", sig->GetName()); + histNames += Form("MCTruthGenPairSel_%s;", sig->GetName()); + fHasTwoProngGenMCsignals = true; + } + } + } + + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + VarManager::SetCollisionSystem((TString)fConfigOptions.collisionSystem, fConfigOptions.centerMassEnergy); // set collision system and center of mass energy + + DefineHistograms(fHistMan, histNames.Data(), fConfigAddSEPHistogram.value.data()); // define all histograms + dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + } + + // Template function to run same event pairing (barrel-barrel) + void runSameEventPairing(MyEventsVtxCovSelected const& events, PresliceUnsorted& preslice, MyBarrelAssocsPrefilter const& assocs, MyBarrelTracksWithCovWithAmbiguities const& /*tracks*/, ReducedA3MCEvents const& /*mcEvents*/, ReducedA3MCTracks const& /*mcTracks*/) + { + if (events.size() == 0) { + LOG(warning) << "No events in this TF, going to the next one ..."; + return; + } + + TString cutNames = fConfigCuts.track.value; + std::map> histNames = fTrackHistNames; + std::map> histNamesMC = fBarrelHistNamesMCmatched; + int ncuts = fNCutsBarrel; + + uint32_t twoTrackFilter = static_cast(0); + int sign1 = 0; + int sign2 = 0; + uint32_t mcDecision = static_cast(0); + bool isCorrectAssoc_leg1 = false; + bool isCorrectAssoc_leg2 = false; + dielectronList.reserve(1); + dielectronsExtraList.reserve(1); + + if (fConfigOptions.flatTables.value) { + dielectronAllList.reserve(1); + } + + if (useMiniTree.fConfigMiniTree) { + dileptonMiniTreeGen.reserve(1); + dileptonMiniTreeRec.reserve(1); + } + + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEventAlice3(event, VarManager::fgValues); + VarManager::FillEventAlice3(event.reducedA3MCEvent(), VarManager::fgValues); + + auto groupedAssocs = assocs.sliceBy(preslice, event.globalIndex()); + if (groupedAssocs.size() == 0) { + continue; + } + + for (auto& [a1, a2] : o2::soa::combinations(groupedAssocs, groupedAssocs)) { + + twoTrackFilter = a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & a2.isBarrelSelectedPrefilter_raw() & fTrackFilterMask; + + if (!twoTrackFilter) { // the tracks must have at least one filter bit in common to continue + continue; + } + + auto t1 = a1.template reducedA3track_as(); + auto t2 = a2.template reducedA3track_as(); + sign1 = t1.sign(); + sign2 = t2.sign(); + // store the ambiguity number of the two dilepton legs in the last 4 digits of the two-track filter + if (t1.barrelAmbiguityInBunch() > 1) { + twoTrackFilter |= (static_cast(1) << 28); + } + if (t2.barrelAmbiguityInBunch() > 1) { + twoTrackFilter |= (static_cast(1) << 29); + } + if (t1.barrelAmbiguityOutOfBunch() > 1) { + twoTrackFilter |= (static_cast(1) << 30); + } + if (t2.barrelAmbiguityOutOfBunch() > 1) { + twoTrackFilter |= (static_cast(1) << 31); + } + + // run MC matching for this pair + int isig = 0; + mcDecision = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if (t1.has_reducedA3MCTrack() && t2.has_reducedA3MCTrack()) { + if ((*sig)->CheckSignal(true, t1.reducedA3MCTrack(), t2.reducedA3MCTrack())) { + mcDecision |= (static_cast(1) << isig); + } + } + } // end loop over MC signals + if (t1.has_reducedA3MCTrack() && t2.has_reducedA3MCTrack()) { + isCorrectAssoc_leg1 = (t1.reducedA3MCTrack().reducedA3MCEvent() == event.reducedA3MCEvent()); + isCorrectAssoc_leg2 = (t2.reducedA3MCTrack().reducedA3MCEvent() == event.reducedA3MCEvent()); + } + + VarManager::FillPairAlice3(t1, t2); + if (fPropTrack) { + VarManager::FillPairCollision(event, t1, t2); + } + /* TODO: Reimplement Pair vertexing when secondary vertexing is available + if constexpr (TTwoProngFitter) { + // VarManager::FillPairVertexing(event, t1, t2, fConfigOptions.propToPCA); + }*/ + if (!fConfigMC.skimSignalOnly || (fConfigMC.skimSignalOnly && mcDecision > 0)) { + dielectronList(event.globalIndex(), VarManager::fgValues[VarManager::kMass], + VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], + t1.sign() + t2.sign(), twoTrackFilter, mcDecision); + } + + // Fill histograms + bool isAmbiInBunch = false; + bool isAmbiOutOfBunch = false; + bool isCorrect_pair = false; + if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) + isCorrect_pair = true; + + for (int icut = 0; icut < ncuts; icut++) { + if (twoTrackFilter & (static_cast(1) << icut)) { + isAmbiInBunch = (twoTrackFilter & (static_cast(1) << 28)) || (twoTrackFilter & (static_cast(1) << 29)); + isAmbiOutOfBunch = (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31)); + if (sign1 * sign2 < 0) { // +- pairs + fHistMan->FillHistClass(histNames[icut][0].Data(), VarManager::fgValues); // reconstructed, unmatched + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + PromptNonPromptSepTable(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kRap], VarManager::fgValues[VarManager::kPhi], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjectedPoleJPsiMass], VarManager::fgValues[VarManager::kVertexingTauzProjected], isAmbiInBunch, isAmbiOutOfBunch, isCorrect_pair, VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][0].Data(), VarManager::fgValues); // matched signal + if (fConfigQA) { + if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { // correct track-collision association + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][3].Data(), VarManager::fgValues); + } else { // incorrect track-collision association + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][4].Data(), VarManager::fgValues); + } + if (isAmbiInBunch) { // ambiguous in bunch + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][5].Data(), VarManager::fgValues); + if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][6].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][7].Data(), VarManager::fgValues); + } + } + if (isAmbiOutOfBunch) { // ambiguous out of bunch + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][8].Data(), VarManager::fgValues); + if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][9].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][10].Data(), VarManager::fgValues); + } + } + } + } + if (fConfigQA) { + if (isAmbiInBunch) { + fHistMan->FillHistClass(histNames[icut][3].Data(), VarManager::fgValues); + } + if (isAmbiOutOfBunch) { + fHistMan->FillHistClass(histNames[icut][3 + 3].Data(), VarManager::fgValues); + } + } + } + } else { + if (sign1 > 0) { // ++ pairs + fHistMan->FillHistClass(histNames[icut][1].Data(), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][1].Data(), VarManager::fgValues); + } + } + if (fConfigQA) { + if (isAmbiInBunch) { + fHistMan->FillHistClass(histNames[icut][4].Data(), VarManager::fgValues); + } + if (isAmbiOutOfBunch) { + fHistMan->FillHistClass(histNames[icut][4 + 3].Data(), VarManager::fgValues); + } + } + } else { // -- pairs + fHistMan->FillHistClass(histNames[icut][2].Data(), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][2].Data(), VarManager::fgValues); + } + } + if (fConfigQA) { + if (isAmbiInBunch) { + fHistMan->FillHistClass(histNames[icut][5].Data(), VarManager::fgValues); + } + if (isAmbiOutOfBunch) { + fHistMan->FillHistClass(histNames[icut][5 + 3].Data(), VarManager::fgValues); + } + } + } + } + for (unsigned int iPairCut = 0; iPairCut < fPairCuts.size(); iPairCut++) { + AnalysisCompositeCut cut = fPairCuts.at(iPairCut); + if (!(cut.IsSelected(VarManager::fgValues))) // apply pair cuts + continue; + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][0].Data(), VarManager::fgValues); + } else { + if (sign1 > 0) { + fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][1].Data(), VarManager::fgValues); + } else { + fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][2].Data(), VarManager::fgValues); + } + } + } // end loop (pair cuts) + } + } // end loop (cuts) + } // end loop over pairs of track associations + } // end loop over events + } + + PresliceUnsorted perReducedMcEvent = aod::reducedA3trackMC::reducedA3MCEventId; + + void runMCGenWithGrouping(MyEventsVtxCovSelected const& events, ReducedA3MCEvents const& mcEvents, ReducedA3MCTracks const& mcTracks) + { + uint32_t mcDecision = 0; + int isig = 0; + + 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 + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, mctrack)) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + } + } + } + // Fill Generated histograms taking into account selected collisions + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedA3MCEvent()) { + continue; + } + + for (auto& track : mcTracks) { + if (track.reducedA3MCEventId() != event.reducedA3MCEventId()) { + 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; + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, track_raw)) { + mcDecision |= (static_cast(1) << isig); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + MCTruthTableEffi(VarManager::fgValues[VarManager::kMCPt], VarManager::fgValues[VarManager::kMCEta], VarManager::fgValues[VarManager::kMCY], VarManager::fgValues[VarManager::kMCPhi], VarManager::fgValues[VarManager::kMCVz], VarManager::fgValues[VarManager::kMCVtxZ], VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); + + if (useMiniTree.fConfigMiniTree) { + auto mcEvent = mcEvents.rawIteratorAt(track_raw.reducedA3MCEventId()); + dileptonMiniTreeGen(mcDecision, mcEvent.impactParameter(), track_raw.pt(), track_raw.eta(), track_raw.phi(), -999, -999, -999); + } + } + isig++; + } + } + } // end loop over reconstructed events + + if (fHasTwoProngGenMCsignals) { + for (auto& [t1, t2] : combinations(mcTracks, mcTracks)) { + auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); + auto t2_raw = mcTracks.rawIteratorAt(t2.globalIndex()); + if (t1_raw.reducedA3MCEventId() == t2_raw.reducedA3MCEventId()) { + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here + continue; + } + 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); + } + } + } + } + } + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedA3MCEvent()) { + continue; + } + // CURRENTLY ONLY FOR 1-GENERATION 2-PRONG SIGNALS + if (fHasTwoProngGenMCsignals) { + auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedA3MCEventId()); + groupedMCTracks.bindInternalIndicesTo(&mcTracks); + for (auto& [t1, t2] : combinations(groupedMCTracks, groupedMCTracks)) { + auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); + auto t2_raw = mcTracks.rawIteratorAt(t2.globalIndex()); + if (t1_raw.reducedA3MCEventId() == t2_raw.reducedA3MCEventId()) { + mcDecision = 0; + isig = 0; + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here + continue; + } + if (sig->CheckSignal(true, t1_raw, t2_raw)) { + mcDecision |= (static_cast(1) << isig); + VarManager::FillPairMC(t1, t2); + if (fUseMCGenAccCut) { + if (!fMCGenAccCut.IsSelected(VarManager::fgValues)) { + continue; + } + } + 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()); + } + } + isig++; + } + } + } + } // end loop over reconstructed events + } + } + + void processBarrelOnlySkimmed(MyEventsVtxCovSelected const& events, + MyBarrelAssocsPrefilter const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, ReducedA3MCEvents const& mcEvents, ReducedA3MCTracks const& mcTracks) + { + runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); + runMCGenWithGrouping(events, mcEvents, mcTracks); + } + + PresliceUnsorted perReducedMcGenEvent = aod::reducedA3trackMC::reducedA3MCEventId; + + void processMCGen(soa::Filtered const& events, ReducedA3MCEvents const& mcEvents, ReducedA3MCTracks const& mcTracks) + { + // Fill Generated histograms taking into account all generated tracks + uint32_t mcDecision = 0; + int isig = 0; + + for (auto& mctrack : mcTracks) { + VarManager::FillTrackMC(mcTracks, mctrack); + // 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 + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, mctrack)) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + } + } + } + + // Fill Generated histograms taking into account selected collisions + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedA3MCEvent()) { + continue; + } + VarManager::FillEventAlice3(event, VarManager::fgValues); + VarManager::FillEventAlice3(event.reducedA3MCEvent(), VarManager::fgValues); + // auto groupedMCTracks = mcTracks.sliceBy(perReducedMcGenEvent, event.reducedA3MCEventId()); + // groupedMCTracks.bindInternalIndicesTo(&mcTracks); + // for (auto& track : groupedMCTracks) { + for (auto& track : mcTracks) { + if (track.reducedA3MCEventId() != event.reducedA3MCEventId()) { + continue; + } + VarManager::FillTrackMC(mcTracks, track); + auto track_raw = mcTracks.rawIteratorAt(track.globalIndex()); + // auto track_raw = groupedMCTracks.rawIteratorAt(track.globalIndex()); + mcDecision = 0; + isig = 0; + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, track_raw)) { + mcDecision |= (static_cast(1) << isig); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + MCTruthTableEffi(VarManager::fgValues[VarManager::kMCPt], VarManager::fgValues[VarManager::kMCEta], VarManager::fgValues[VarManager::kMCY], VarManager::fgValues[VarManager::kMCPhi], VarManager::fgValues[VarManager::kMCVz], VarManager::fgValues[VarManager::kMCVtxZ], VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); + + if (useMiniTree.fConfigMiniTree) { + auto mcEvent = mcEvents.rawIteratorAt(track_raw.reducedA3MCEventId()); + dileptonMiniTreeGen(mcDecision, mcEvent.impactParameter(), track_raw.pt(), track_raw.eta(), track_raw.phi(), -999, -999, -999); + } + } + isig++; + } + } + } // end loop over reconstructed events + if (fHasTwoProngGenMCsignals) { + for (auto& [t1, t2] : combinations(mcTracks, mcTracks)) { + auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); + auto t2_raw = mcTracks.rawIteratorAt(t2.globalIndex()); + if (t1_raw.reducedA3MCEventId() == t2_raw.reducedA3MCEventId()) { + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here + continue; + } + if (sig->CheckSignal(true, t1_raw, t2_raw)) { + fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig->GetName()), VarManager::fgValues); + } + } + } + } + } + // Fill Generated PAIR histograms taking into account selected collisions + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedA3MCEvent()) { + continue; + } + + if (fHasTwoProngGenMCsignals) { + for (auto& [t1, t2] : combinations(mcTracks, mcTracks)) { + if (t1.reducedA3MCEventId() != event.reducedA3MCEventId()) { + continue; + } + if (t2.reducedA3MCEventId() != event.reducedA3MCEventId()) { + continue; + } + auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); + auto t2_raw = mcTracks.rawIteratorAt(t2.globalIndex()); + if (t1_raw.reducedA3MCEventId() == t2_raw.reducedA3MCEventId()) { + mcDecision = 0; + isig = 0; + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here + continue; + } + if (sig->CheckSignal(true, t1_raw, t2_raw)) { + mcDecision |= (static_cast(1) << isig); + 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()); + } + } + isig++; + } + } + } + } + } // end loop over reconstructed events + } + + void processMCGenWithGrouping(soa::Filtered const& events, ReducedA3MCEvents const& mcEvents, ReducedA3MCTracks const& mcTracks) + { + uint32_t mcDecision = 0; + int isig = 0; + + for (auto& mctrack : mcTracks) { + VarManager::FillTrackMC(mcTracks, mctrack); + // 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 + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, mctrack)) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + } + } + } + // Fill Generated histograms taking into account selected collisions + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedA3MCEvent()) { + continue; + } + + for (auto& track : mcTracks) { + if (track.reducedA3MCEventId() != event.reducedA3MCEventId()) { + continue; + } + VarManager::FillTrackMC(mcTracks, track); + auto track_raw = mcTracks.rawIteratorAt(track.globalIndex()); + mcDecision = 0; + isig = 0; + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, track_raw)) { + mcDecision |= (static_cast(1) << isig); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + MCTruthTableEffi(VarManager::fgValues[VarManager::kMCPt], VarManager::fgValues[VarManager::kMCEta], VarManager::fgValues[VarManager::kMCY], VarManager::fgValues[VarManager::kMCPhi], VarManager::fgValues[VarManager::kMCVz], VarManager::fgValues[VarManager::kMCVtxZ], VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); + + if (useMiniTree.fConfigMiniTree) { + auto mcEvent = mcEvents.rawIteratorAt(track_raw.reducedA3MCEventId()); + dileptonMiniTreeGen(mcDecision, mcEvent.impactParameter(), track_raw.pt(), track_raw.eta(), track_raw.phi(), -999, -999, -999); + } + } + isig++; + } + } + } // end loop over reconstructed events + if (fHasTwoProngGenMCsignals) { + for (auto& [t1, t2] : combinations(mcTracks, mcTracks)) { + auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); + auto t2_raw = mcTracks.rawIteratorAt(t2.globalIndex()); + if (t1_raw.reducedA3MCEventId() == t2_raw.reducedA3MCEventId()) { + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here + continue; + } + if (sig->CheckSignal(true, t1_raw, t2_raw)) { + fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig->GetName()), VarManager::fgValues); + } + } + } + } + } + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedA3MCEvent()) { + continue; + } + // CURRENTLY ONLY FOR 1-GENERATION 2-PRONG SIGNALS + if (fHasTwoProngGenMCsignals) { + auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedA3MCEventId()); + groupedMCTracks.bindInternalIndicesTo(&mcTracks); + for (auto& [t1, t2] : combinations(groupedMCTracks, groupedMCTracks)) { + auto t1_raw = groupedMCTracks.rawIteratorAt(t1.globalIndex()); + auto t2_raw = groupedMCTracks.rawIteratorAt(t2.globalIndex()); + if (t1_raw.reducedA3MCEventId() == t2_raw.reducedA3MCEventId()) { + mcDecision = 0; + isig = 0; + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here + continue; + } + if (sig->CheckSignal(true, t1_raw, t2_raw)) { + mcDecision |= (static_cast(1) << isig); + 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()); + } + } + isig++; + } + } + } + } // end loop over reconstructed events + } + } + + void processDummy(MyEvents const&) + { + // do nothing + } + + PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmed, "Run barrel only pairing, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processMCGen, "Loop over MC particle stack and fill generator level histograms", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processMCGenWithGrouping, "Loop over MC particle stack (grouped MCTracks) and fill generator level histograms", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", true); +}; + +struct AnalysisAsymmetricPairing { + + Produces ditrackList; + Produces ditrackExtraList; + + // Output objects + OutputObj fOutputList{"output"}; + + // Configurables + Configurable fConfigLegCuts{"cfgLegCuts", "", ":[:],[:[:],...]"}; + Configurable fConfigLegAFilterMask{"cfgLegAFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; + Configurable fConfigLegBFilterMask{"cfgLegBFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; + Configurable fConfigLegCFilterMask{"cfgLegCFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; + Configurable fConfigCommonTrackCuts{"cfgCommonTrackCuts", "", "Comma separated list of cuts to be applied to all legs"}; + Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; + Configurable fConfigPairCutsJSON{"cfgPairCutsJSON", "", "Additional list of pair cuts in JSON format"}; + Configurable fConfigSkipAmbiguousIdCombinations{"cfgSkipAmbiguousIdCombinations", true, "Choose whether to skip pairs/triples which pass a stricter combination of cuts, e.g. KKPi triplets for D+ -> KPiPi"}; + + Configurable fConfigHistogramSubgroups{"cfgAsymmetricPairingHistogramsSubgroups", "barrel,vertexing", "Comma separated list of asymmetric-pairing histogram subgroups"}; + Configurable fConfigSameSignHistograms{"cfgSameSignHistograms", false, "Include same sign pair histograms for 2-prong decays"}; + Configurable fConfigReflectedHistograms{"cfgReflectedHistograms", false, "Include separate histograms for pairs which are reflections of previously counted pairs"}; + Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; + + Configurable fConfigMCGenSignals{"cfgBarrelMCGenSignals", "", "Comma separated list of MC signals (generated)"}; + Configurable fConfigMCRecSignals{"cfgBarrelMCRecSignals", "", "Comma separated list of MC signals (reconstructed)"}; + Configurable fConfigMCRecSignalsJSON{"cfgMCRecSignalsJSON", "", "Additional list of MC signals (reconstructed) via JSON"}; + Configurable fConfigMCGenSignalsJSON{"cfgMCGenSignalsJSON", "", "Comma separated list of MC signals (generated) via JSON"}; + + HistogramManager* fHistMan; + + std::vector fPairCuts; + int fNPairHistPrefixes; + + std::vector fRecMCSignals; + std::vector fGenMCSignals; + + // Filter masks to find legs in BarrelTrackCuts table + uint32_t fLegAFilterMask; + uint32_t fLegBFilterMask; + uint32_t fLegCFilterMask; + // Maps tracking which combination of leg cuts the track cuts participate in + std::map fConstructedLegAFilterMasksMap; + std::map fConstructedLegBFilterMasksMap; + std::map fConstructedLegCFilterMasksMap; + // Filter map for common track cuts + uint32_t fCommonTrackCutMask; + // Map tracking which common track cut the track cuts correspond to + std::map fCommonTrackCutFilterMasks; + + int fNLegCuts; + int fNPairCuts = 0; + int fNCommonTrackCuts; + // vectors for cut names and signal names, for easy access when calling FillHistogramList() + std::vector fLegCutNames; + std::vector fPairCutNames; + std::vector fCommonCutNames; + std::vector fRecMCSignalNames; + + Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); + + PresliceUnsorted trackAssocsPerCollision = aod::reducedA3track_association::reducedA3eventId; + // PresliceUnsorted trackAssocsPerCollision = aod::reducedA3track_association::reducedA3eventId; + + // Partitions for triplets and asymmetric pairs + Partition legACandidateAssocs = (o2::aod::dqanalysisflags::isBarrelSelected & fConfigLegAFilterMask) > static_cast(0); + Partition legBCandidateAssocs = (o2::aod::dqanalysisflags::isBarrelSelected & fConfigLegBFilterMask) > static_cast(0); + Partition legCCandidateAssocs = (o2::aod::dqanalysisflags::isBarrelSelected & fConfigLegCFilterMask) > static_cast(0); + + // Map to track how many times a pair of tracks has been encountered + std::map, int8_t> fPairCount; + + void init(o2::framework::InitContext& context) + { + bool isMCGen = context.mOptions.get("processMCGen") || context.mOptions.get("processMCGenWithEventSelection"); + if (context.mOptions.get("processDummy")) { + return; + } + + VarManager::SetDefaultVarNames(); + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + // Get the leg cut filter masks + fLegAFilterMask = fConfigLegAFilterMask.value; + fLegBFilterMask = fConfigLegBFilterMask.value; + fLegCFilterMask = fConfigLegCFilterMask.value; + + // Get the pair cuts + TString cutNamesStr = fConfigPairCuts.value; + if (!cutNamesStr.IsNull()) { + std::unique_ptr objArray(cutNamesStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + fPairCuts.push_back(dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); + } + } + // Extra pair cuts via JSON + TString addPairCutsStr = fConfigPairCutsJSON.value; + if (addPairCutsStr != "") { + std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); + for (auto& t : addPairCuts) { + fPairCuts.push_back(reinterpret_cast(t)); + cutNamesStr += Form(",%s", t->GetName()); + } + } + std::unique_ptr objArrayPairCuts(cutNamesStr.Tokenize(",")); + fNPairCuts = objArrayPairCuts->GetEntries(); + for (int j = 0; j < fNPairCuts; j++) { + fPairCutNames.push_back(objArrayPairCuts->At(j)->GetName()); + } + + // Setting the MC rec signal names + TString sigNamesStr = fConfigMCRecSignals.value; + std::unique_ptr objRecSigArray(sigNamesStr.Tokenize(",")); + for (int isig = 0; isig < objRecSigArray->GetEntries(); ++isig) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objRecSigArray->At(isig)->GetName()); + if (sig) { + fRecMCSignals.push_back(sig); + } + } + // Add the reco MCSignals from the JSON config + TString addMCSignalsStr = fConfigMCRecSignalsJSON.value; + if (addMCSignalsStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); + for (auto& mcIt : addMCSignals) { + if (mcIt->GetNProngs() != 2 && mcIt->GetNProngs() != 3) { + LOG(fatal) << "Signal at reconstructed level requested (" << mcIt->GetName() << ") " << "does not have 2 or 3 prongs! Fix it"; + } + fRecMCSignals.push_back(mcIt); + sigNamesStr += Form(",%s", mcIt->GetName()); + } + } + // Put all the reco MCSignal names in the vector for histogram naming + std::unique_ptr objArrayRecMCSignals(sigNamesStr.Tokenize(",")); + for (int i = 0; i < objArrayRecMCSignals->GetEntries(); i++) { + fRecMCSignalNames.push_back(objArrayRecMCSignals->At(i)->GetName()); + } + + // Get the barrel track selection cuts + string tempCuts; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); + TString tempCutsStr = tempCuts; + // check also the cuts added via JSON and add them to the string of cuts + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempCuts, false); + TString addTrackCutsStr = tempCuts; + if (addTrackCutsStr != "") { + std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); + for (auto& t : addTrackCuts) { + tempCutsStr += Form(",%s", t->GetName()); + } + } + std::unique_ptr objArray(tempCutsStr.Tokenize(",")); + // Get the common leg cuts + int commonCutIdx; + TString commonNamesStr = fConfigCommonTrackCuts.value; + if (!commonNamesStr.IsNull()) { // if common track cuts + std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); + fNCommonTrackCuts = objArrayCommon->GetEntries(); + for (int icut = 0; icut < fNCommonTrackCuts; ++icut) { + commonCutIdx = objArray->IndexOf(objArrayCommon->At(icut)); + if (commonCutIdx >= 0) { + fCommonTrackCutMask |= static_cast(1) << objArray->IndexOf(objArrayCommon->At(icut)); + fCommonTrackCutFilterMasks[icut] = static_cast(1) << objArray->IndexOf(objArrayCommon->At(icut)); + fCommonCutNames.push_back(objArrayCommon->At(icut)->GetName()); + } else { + LOGF(fatal, "Common track cut %s was not calculated upstream. Check the config!", objArrayCommon->At(icut)->GetName()); + } + } + } + // Check that the leg cut masks make sense + if (static_cast(std::floor(TMath::Log2(fLegAFilterMask))) + 1 > objArray->GetEntries()) { + LOGF(fatal, "fConfigLegAFilterMask has highest bit at position %d, but track-selection only has %d cuts!", static_cast(std::floor(TMath::Log2(fLegAFilterMask))) + 1, objArray->GetEntries()); + } + if (static_cast(std::floor(TMath::Log2(fLegBFilterMask))) + 1 > objArray->GetEntries()) { + LOGF(fatal, "fConfigLegBFilterMask has highest bit at position %d, but track-selection only has %d cuts!", static_cast(std::floor(TMath::Log2(fLegBFilterMask))) + 1, objArray->GetEntries()); + } + if (static_cast(std::floor(TMath::Log2(fLegCFilterMask))) + 1 > objArray->GetEntries()) { + LOGF(fatal, "fConfigLegCFilterMask has highest bit at position %d, but track-selection only has %d cuts!", static_cast(std::floor(TMath::Log2(fLegCFilterMask))) + 1, objArray->GetEntries()); + } + + // Get the cuts defining the legs + uint32_t fConstructedLegAFilterMask = 0; + uint32_t fConstructedLegBFilterMask = 0; + uint32_t fConstructedLegCFilterMask = 0; + TString legCutsStr = fConfigLegCuts.value; + std::unique_ptr objArrayLegs(legCutsStr.Tokenize(",")); + if (objArrayLegs->GetEntries() == 0 && !isMCGen) { + LOG(fatal) << "No cuts defining legs. Check the config!"; + } + fNLegCuts = objArrayLegs->GetEntries(); + std::vector isThreeProng; + int legAIdx; + int legBIdx; + int legCIdx; + // Loop over leg defining cuts + for (int icut = 0; icut < fNLegCuts; ++icut) { + TString legsStr = objArrayLegs->At(icut)->GetName(); + std::unique_ptr legs(legsStr.Tokenize(":")); + if (legs->GetEntries() == 3) { + isThreeProng.push_back(true); + } else if (legs->GetEntries() == 2) { + isThreeProng.push_back(false); + } else { + LOGF(fatal, "Leg cuts %s has the wrong format and could not be parsed!", legsStr.Data()); + continue; + } + // Find leg cuts in the track selection cuts + legAIdx = objArray->IndexOf(legs->At(0)); + if (legAIdx >= 0) { + fConstructedLegAFilterMask |= static_cast(1) << legAIdx; + fConstructedLegAFilterMasksMap[icut] |= static_cast(1) << legAIdx; + } else { + LOGF(fatal, "Leg A cut %s was not calculated upstream. Check the config!", legs->At(0)->GetName()); + continue; + } + legBIdx = objArray->IndexOf(legs->At(1)); + if (legBIdx >= 0) { + fConstructedLegBFilterMask |= static_cast(1) << legBIdx; + fConstructedLegBFilterMasksMap[icut] |= static_cast(1) << legBIdx; + } else { + LOGF(fatal, "Leg B cut %s was not calculated upstream. Check the config!", legs->At(1)->GetName()); + continue; + } + if (isThreeProng[icut]) { + legCIdx = objArray->IndexOf(legs->At(2)); + if (legCIdx >= 0) { + fConstructedLegCFilterMask |= static_cast(1) << legCIdx; + fConstructedLegCFilterMasksMap[icut] |= static_cast(1) << legCIdx; + } else { + LOGF(fatal, "Leg C cut %s was not calculated upstream. Check the config!", legs->At(2)->GetName()); + continue; + } + } + // Leg cut config is fine, store the leg cut name in a vector + fLegCutNames.push_back(legsStr); + + // Define histogram and histogram directory names + if (isThreeProng[icut]) { + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s", legsStr.Data()), fConfigHistogramSubgroups.value.data()); + if (fConfigQA) { + DefineHistograms(fHistMan, Form("TripletsBarrelSE_ambiguous_%s", legsStr.Data()), fConfigHistogramSubgroups.value.data()); + } + + std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName()), fConfigHistogramSubgroups.value.data()); + } + + TString cutNamesStr = fConfigPairCuts.value; + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + fNPairCuts = objArrayPair->GetEntries(); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s", legsStr.Data(), objArrayPair->At(iPairCut)->GetName()), fConfigHistogramSubgroups.value.data()); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName()), fConfigHistogramSubgroups.value.data()); + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + + // TODO: assign hist directories for the MC matched triplets for each (leg cut combo,MCsignal) combination + if (!sigNamesStr.IsNull()) { + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { + auto sig = fRecMCSignals.at(isig); + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s", legsStr.Data(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + } + + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + } // end loop over MC signals + } // end if (MC signals) + } else { + std::vector pairHistPrefixes = {"PairsBarrelSEPM"}; + if (fConfigSameSignHistograms.value) { + pairHistPrefixes.push_back("PairsBarrelSEPP"); + pairHistPrefixes.push_back("PairsBarrelSEMM"); + } + fNPairHistPrefixes = pairHistPrefixes.size(); + + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data()), fConfigHistogramSubgroups.value.data()); + } + if (fConfigQA) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_ambiguous_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data()), fConfigHistogramSubgroups.value.data()); + } + } + if (fConfigReflectedHistograms.value) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_reflected_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data()), fConfigHistogramSubgroups.value.data()); + } + } + + std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName()), fConfigHistogramSubgroups.value.data()); + } + } + + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + fNPairCuts = objArrayPair->GetEntries(); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayPair->At(iPairCut)->GetName()), fConfigHistogramSubgroups.value.data()); + } + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName()), fConfigHistogramSubgroups.value.data()); + } + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + + // assign hist directories for the MC matched triplets for each (leg cut combo,MCsignal) combination + if (!sigNamesStr.IsNull()) { + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { + auto sig = fRecMCSignals.at(isig); + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + } + if (fConfigReflectedHistograms.value) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_reflected_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + } + } + + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + } + } + + if (!cutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + } + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { + DefineHistograms(fHistMan, Form("%s_%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig->GetName()), fConfigHistogramSubgroups.value.data()); + } + } // end loop (common cuts) + } // end loop (pair cuts) + } // end if (pair cuts) + } // end loop over MC signals + } // end if (MC signals) + } + } + + // 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 = fConfigMCGenSignals.value; + std::unique_ptr objGenSigArray(sigGenNamesStr.Tokenize(",")); + for (int isig = 0; isig < objGenSigArray->GetEntries(); isig++) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objGenSigArray->At(isig)->GetName()); + if (sig) { + if (sig->GetNProngs() == 1) { // NOTE: 1-prong signals required + fGenMCSignals.push_back(sig); + DefineHistograms(fHistMan, Form("MCTruthGen_%s;", sig->GetName()), fConfigHistogramSubgroups.value.data()); // TODO: Add these names to a std::vector to avoid using Form in the process function + DefineHistograms(fHistMan, Form("MCTruthGenSel_%s;", sig->GetName()), fConfigHistogramSubgroups.value.data()); // TODO: Add these names to a std::vector to avoid using Form in the process function + } + } + } + + // Add the gen MCSignals from the JSON config + addMCSignalsStr = fConfigMCGenSignalsJSON.value; + if (addMCSignalsStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); + for (auto& mcIt : addMCSignals) { + if (mcIt->GetNProngs() == 1) { + fGenMCSignals.push_back(mcIt); + DefineHistograms(fHistMan, Form("MCTruthGen_%s;", mcIt->GetName()), fConfigHistogramSubgroups.value.data()); // TODO: Add these names to a std::vector to avoid using Form in the process function + DefineHistograms(fHistMan, Form("MCTruthGenSel_%s;", mcIt->GetName()), fConfigHistogramSubgroups.value.data()); // TODO: Add these names to a std::vector to avoid using Form in the process function + } + } + } + + // Make sure the leg cuts are covered by the configured filter masks + if (fLegAFilterMask != fConstructedLegAFilterMask) { + LOGF(fatal, "cfgLegAFilterMask (%d) is not equal to the mask constructed by the cuts specified in cfgLegCuts (%d)!", fLegAFilterMask, fConstructedLegAFilterMask); + } + if (fLegBFilterMask != fConstructedLegBFilterMask) { + LOGF(fatal, "cfgLegBFilterMask (%d) is not equal to the mask constructed by the cuts specified in cfgLegCuts (%d)!", fLegBFilterMask, fConstructedLegBFilterMask); + } + if (fLegCFilterMask != fConstructedLegCFilterMask) { + LOGF(fatal, "cfgLegCFilterMask (%d) is not equal to the mask constructed by the cuts specified in cfgLegCuts (%d)!", fLegCFilterMask, fConstructedLegCFilterMask); + } + // Make sure only pairs or only triplets of leg cuts were given + int tripletCheckSum = std::count(isThreeProng.begin(), isThreeProng.end(), true); + if (tripletCheckSum != 0 && tripletCheckSum != fNLegCuts) { + LOGF(fatal, "A mix of pairs and triplets was given as leg cuts. Check your config!"); + } + + dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + } + + // Function to run same event pairing with asymmetric pairs (e.g. kaon-pion) + void runAsymmetricPairing(MyEventsVtxCovSelected const& events, PresliceUnsorted& preslice, MyBarrelAssocs const& /*assocs*/, MyBarrelTracksWithCovWithAmbiguities const& /*tracks*/, ReducedA3MCEvents const& /*mcEvents*/, ReducedA3MCTracks const& /*mcTracks*/) + { + fPairCount.clear(); + + int sign1 = 0; + int sign2 = 0; + uint32_t mcDecision = 0; + ditrackList.reserve(1); + ditrackExtraList.reserve(1); + + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEventAlice3(event, VarManager::fgValues); + + auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegAAssocs.size() == 0) { + continue; + } + auto groupedLegBAssocs = legBCandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegBAssocs.size() == 0) { + continue; + } + + for (auto& [a1, a2] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs))) { + + uint32_t twoTrackFilter = 0; + uint32_t twoTrackCommonFilter = 0; + uint32_t pairFilter = 0; + bool isPairIdWrong = false; + for (int icut = 0; icut < fNLegCuts; ++icut) { + // Find leg pair definitions both candidates participate in + if ((a1.isBarrelSelected_raw() & fConstructedLegAFilterMasksMap[icut]) && (a2.isBarrelSelected_raw() & fConstructedLegBFilterMasksMap[icut])) { + twoTrackFilter |= static_cast(1) << icut; + // If the supposed pion passes a kaon cut, this is a K+K-. Skip it. + if (fConfigSkipAmbiguousIdCombinations.value) { + if (a2.isBarrelSelected_raw() & fLegAFilterMask) { + isPairIdWrong = true; + } + } + } + } + + if (!twoTrackFilter || isPairIdWrong) { + continue; + } + + // Find common track cuts both candidates pass + twoTrackCommonFilter |= a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & fCommonTrackCutMask; + + auto t1 = a1.template reducedA3track_as(); + auto t2 = a2.template reducedA3track_as(); + + // Avoid self-pairs + if (t1.globalIndex() == t2.globalIndex()) { + continue; + } + + bool isReflected = false; + std::pair trackIds(t1.globalIndex(), t2.globalIndex()); + if (fPairCount.find(trackIds) != fPairCount.end()) { + // Double counting is possible due to track-collision ambiguity. Skip pairs which were counted before + fPairCount[trackIds] += 1; + continue; + } + if (fPairCount.find(std::pair(trackIds.second, trackIds.first)) != fPairCount.end()) { + isReflected = true; + } + fPairCount[trackIds] += 1; + + sign1 = t1.sign(); + sign2 = t2.sign(); + // store the ambiguity number of the two dilepton legs in the last 4 digits of the two-track filter + if (t1.barrelAmbiguityInBunch() > 1 || t1.barrelAmbiguityOutOfBunch() > 1) { + twoTrackFilter |= static_cast(1) << 30; + } + if (t2.barrelAmbiguityInBunch() > 1 || t2.barrelAmbiguityOutOfBunch() > 1) { + twoTrackFilter |= static_cast(1) << 31; + } + + // run MC matching for this pair + int isig = 0; + mcDecision = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if (t1.has_reducedA3MCTrack() && t2.has_reducedA3MCTrack()) { + VarManager::FillPairMC(t1.reducedA3MCTrack(), t2.reducedA3MCTrack()); + if ((*sig)->CheckSignal(true, t1.reducedA3MCTrack(), t2.reducedA3MCTrack())) { + mcDecision |= static_cast(1) << isig; + } + } + } // end loop over MC signals + + VarManager::FillPairAlice3(t1, t2); + /*TODO: Reimplement when secondary vertexing is available + if constexpr (TTwoProngFitter) { + VarManager::FillPairVertexing(event, t1, t2, fConfigPropToPCA); + }*/ + + // Fill histograms + bool isAmbi = false; + for (int icut = 0; icut < fNLegCuts; icut++) { + if (twoTrackFilter & (static_cast(1) << icut)) { + isAmbi = (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31)); + if (sign1 * sign2 < 0) { // +- pairs + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s", fLegCutNames[icut].Data()), VarManager::fgValues); // reconstructed, unmatched + if (isAmbi && fConfigQA) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + } + if (isReflected && fConfigReflectedHistograms.value) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + } + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { // ++ pairs + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + if (isAmbi && fConfigQA) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + } + if (isReflected && fConfigReflectedHistograms.value) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + } + } else { // -- pairs + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + if (isAmbi && fConfigQA) { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + } + if (isReflected && fConfigReflectedHistograms) { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + } + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + if (isReflected && fConfigReflectedHistograms.value) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + if (isReflected && fConfigReflectedHistograms.value) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } + } else { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + if (isReflected && fConfigReflectedHistograms.value) { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } + } + } + } + } + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + } else { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } else { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } + } + } + } + } + } // end loop (common cuts) + int iPairCut = 0; + for (auto cut = fPairCuts.begin(); cut != fPairCuts.end(); cut++, iPairCut++) { + if (!((*cut)->IsSelected(VarManager::fgValues))) // apply pair cuts + continue; + pairFilter |= (static_cast(1) << iPairCut); + // Histograms with pair cuts + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + } else { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } else { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } + } + } + } + // Histograms with pair cuts and common track cuts + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + } else { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + } + } + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + if (sign1 * sign2 < 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } else if (fConfigSameSignHistograms.value) { + if (sign1 > 0) { + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } else { + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + } + } + } + } + } + } + } // end loop (pair cuts) + } + } // end loop (cuts) + ditrackList(event.globalIndex(), VarManager::fgValues[VarManager::kMass], + VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], + t1.sign() + t2.sign(), twoTrackFilter, pairFilter, twoTrackCommonFilter); + } // end inner assoc loop (leg A) + } // end event loop + } + + // Function to run same event triplets (e.g. D+->K-pi+pi+) + void runThreeProng(MyEventsVtxCovSelected const& events, PresliceUnsorted& preslice, MyBarrelAssocs const& /*assocs*/, MyBarrelTracksWithCovWithAmbiguities const& tracks, ReducedA3MCEvents const& /*mcEvents*/, ReducedA3MCTracks const& /*mcTracks*/, VarManager::PairCandidateType tripletType) + { + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEventAlice3(event, VarManager::fgValues); + + auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegAAssocs.size() == 0) { + continue; + } + auto groupedLegBAssocs = legBCandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegBAssocs.size() == 0) { + continue; + } + auto groupedLegCAssocs = legCCandidateAssocs.sliceBy(preslice, event.globalIndex()); + if (groupedLegCAssocs.size() == 0) { + continue; + } + + // Based on triplet type, make suitable combinations of the partitions + if (tripletType == VarManager::kTripleCandidateToPKPi) { + for (auto& [a1, a2, a3] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs, groupedLegCAssocs))) { + readTriplet(a1, a2, a3, tracks, event, tripletType); + } + } else if (tripletType == VarManager::kTripleCandidateToKPiPi) { + for (auto& a1 : groupedLegAAssocs) { + for (auto& [a2, a3] : combinations(groupedLegBAssocs, groupedLegCAssocs)) { + readTriplet(a1, a2, a3, tracks, event, tripletType); + } + } + } else { + LOG(fatal) << "Given tripletType not recognized. Don't know how to make combinations!\n"; + } + } // end event loop + } + + // Helper function to process triplet + void readTriplet(MyBarrelAssocs::iterator const& a1, MyBarrelAssocs::iterator const& a2, MyBarrelAssocs::iterator const& a3, MyBarrelTracksWithCovWithAmbiguities const& /*tracks*/, MyEventsVtxCovSelected::iterator const& /*event*/, VarManager::PairCandidateType tripletType) + { + uint32_t mcDecision = 0; + + uint32_t threeTrackFilter = 0; + uint32_t threeTrackCommonFilter = 0; + for (int icut = 0; icut < fNLegCuts; ++icut) { + // Find out which leg cut combinations the triplet passes + if ((a1.isBarrelSelected_raw() & fConstructedLegAFilterMasksMap[icut]) && (a2.isBarrelSelected_raw() & fConstructedLegBFilterMasksMap[icut]) && (a3.isBarrelSelected_raw() & fConstructedLegCFilterMasksMap[icut])) { + threeTrackFilter |= (static_cast(1) << icut); + if (tripletType == VarManager::kTripleCandidateToPKPi && fConfigSkipAmbiguousIdCombinations.value) { + // Check if the supposed pion passes as a proton or kaon, if so, skip this triplet. It is pKp or pKK. + if ((a3.isBarrelSelected_raw() & fLegAFilterMask) || (a3.isBarrelSelected_raw() & fLegBFilterMask)) { + return; + } + // Check if the supposed kaon passes as a proton, if so, skip this triplet. It is ppPi. + if (a2.isBarrelSelected_raw() & fLegAFilterMask) { + return; + } + } + if (tripletType == VarManager::kTripleCandidateToKPiPi && fConfigSkipAmbiguousIdCombinations.value) { + // Check if one of the supposed pions pass as a kaon, if so, skip this triplet. It is KKPi. + if ((a2.isBarrelSelected_raw() & fLegAFilterMask) || (a3.isBarrelSelected_raw() & fLegAFilterMask)) { + return; + } + } + } + } + if (!threeTrackFilter) { + return; + } + + // Find common track cuts all candidates pass + threeTrackCommonFilter |= a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & a3.isBarrelSelected_raw() & fCommonTrackCutMask; + + auto t1 = a1.template reducedA3track_as(); + auto t2 = a2.template reducedA3track_as(); + auto t3 = a3.template reducedA3track_as(); + + // Avoid self-pairs + if (t1 == t2 || t1 == t3 || t2 == t3) { + return; + } + // Check charge + if (tripletType == VarManager::kTripleCandidateToKPiPi) { + if (!((t1.sign() == -1 && t2.sign() == 1 && t3.sign() == 1) || (t1.sign() == 1 && t2.sign() == -1 && t3.sign() == -1))) { + return; + } + } + if (tripletType == VarManager::kTripleCandidateToPKPi) { + if (!((t1.sign() == 1 && t2.sign() == -1 && t3.sign() == 1) || (t1.sign() == -1 && t2.sign() == 1 && t3.sign() == -1))) { + return; + } + } + + // store the ambiguity of the three legs in the last 3 digits of the two-track filter + if (t1.barrelAmbiguityInBunch() > 1 || t1.barrelAmbiguityOutOfBunch() > 1) { + threeTrackFilter |= (static_cast(1) << 29); + } + if (t2.barrelAmbiguityInBunch() > 1 || t2.barrelAmbiguityOutOfBunch() > 1) { + threeTrackFilter |= (static_cast(1) << 30); + } + if (t3.barrelAmbiguityInBunch() > 1 || t3.barrelAmbiguityOutOfBunch() > 1) { + threeTrackFilter |= (static_cast(1) << 31); + } + + // run MC matching for this triplet + int isig = 0; + mcDecision = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if (t1.has_reducedA3MCTrack() && t2.has_reducedA3MCTrack() && t3.has_reducedA3MCTrack()) { + if ((*sig)->CheckSignal(true, t1.reducedA3MCTrack(), t2.reducedA3MCTrack(), t3.reducedA3MCTrack())) { + mcDecision |= (static_cast(1) << isig); + } + } + } // end loop over MC signals + + VarManager::FillTriple(t1, t2, t3, VarManager::fgValues, tripletType); + /* TODO: Reimplement when secondary vertexing is available + if constexpr (TThreeProngFitter) { + VarManager::FillTripletVertexing(event, t1, t2, t3, tripletType); + }*/ + + // Fill histograms + bool isAmbi = false; + for (int icut = 0; icut < fNLegCuts; icut++) { + isAmbi = (threeTrackFilter & (static_cast(1) << 29)) || (threeTrackFilter & (static_cast(1) << 30)) || (threeTrackFilter & (static_cast(1) << 31)); + if (threeTrackFilter & (static_cast(1) << icut)) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + if (fConfigQA && isAmbi) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + } + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { + if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + } + } // end loop (common cuts) + int iPairCut = 0; + for (auto cut = fPairCuts.begin(); cut != fPairCuts.end(); cut++, iPairCut++) { + if (!((*cut)->IsSelected(VarManager::fgValues))) // apply pair cuts + continue; + // Histograms with pair cuts + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + // Histograms with pair cuts and common track cuts + for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { + if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals + if (mcDecision & (static_cast(1) << isig)) { + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + } + } // end loop (MC signals) + } + } + } // end loop (pair cuts) + } + } // end loop (cuts) + } + + void processKaonPionSkimmed(MyEventsVtxCovSelected const& events, + MyBarrelAssocs const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + ReducedA3MCEvents const& mcEvents, ReducedA3MCTracks const& mcTracks) + { + runAsymmetricPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); + } + + void processKaonPionPionSkimmed(MyEventsVtxCovSelected const& events, + MyBarrelAssocs const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + ReducedA3MCEvents const& mcEvents, ReducedA3MCTracks const& mcTracks) + { + runThreeProng(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks, VarManager::kTripleCandidateToKPiPi); + } + + void processMCGen(ReducedA3MCTracks const& mcTracks) + { + // loop over mc stack and fill histograms for pure MC truth signals + // group all the MC tracks which belong to the MC event corresponding to the current reconstructed event + // auto groupedMCTracks = tracksMC.sliceBy(aod::reducedA3trackMC::reducedA3MCEventId, event.reducedMCevent().globalIndex()); + for (auto& mctrack : mcTracks) { + + VarManager::FillTrackMC(mcTracks, mctrack); + // 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 + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, mctrack)) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + } + } + } + } + + PresliceUnsorted perReducedMcEvent = aod::reducedA3trackMC::reducedA3MCEventId; + + void processMCGenWithEventSelection(soa::Filtered const& events, + ReducedA3MCEvents const& /*mcEvents*/, ReducedA3MCTracks const& mcTracks) + { + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedA3MCEvent()) { + continue; + } + + auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedA3MCEventId()); + groupedMCTracks.bindInternalIndicesTo(&mcTracks); + for (auto& track : groupedMCTracks) { + + VarManager::FillTrackMC(mcTracks, track); + + auto track_raw = groupedMCTracks.rawIteratorAt(track.globalIndex()); + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, track_raw)) { + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + } + } + } + } // end loop over reconstructed events + } + + void processDummy(MyEvents&) + { + // do nothing + } + + PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionSkimmed, "Run kaon pion pairing, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionPionSkimmed, "Run kaon pion pion triplets, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processMCGen, "Loop over MC particle stack and fill generator level histograms", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processMCGenWithEventSelection, "Loop over MC particle stack and fill generator level histograms", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} + +void DefineHistograms(HistogramManager* histMan, TString histClasses, const char* histGroups) +{ + // + // Define here the histograms for all the classes required in analysis. + // The histogram classes are provided in the histClasses string, separated by semicolon ";" + // The histogram classes and their components histograms are defined below depending on the name of the histogram class + // + 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()); + + TString histName = histGroups; + // NOTE: The level of detail for histogramming can be controlled via configurables + if (classStr.Contains("Event")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "event", histName); + } + + if (classStr.Contains("SameBunchCorrelations") || classStr.Contains("OutOfBunchCorrelations")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "two-collisions", histName); + } + + // TODO: CHANGE TO PROPER PID + + if ((classStr.Contains("Track") || classStr.Contains("Assoc")) && !classStr.Contains("Pairs")) { + if (classStr.Contains("Barrel")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "track", histName); + if (classStr.Contains("PIDCalibElectron")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "track", "postcalib_electron"); + } + if (classStr.Contains("PIDCalibPion")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "track", "postcalib_pion"); + } + if (classStr.Contains("PIDCalibProton")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "track", "postcalib_proton"); + } + if (classStr.Contains("Ambiguity")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "track", "ambiguity"); + } + } + } + + if (classStr.Contains("Pairs")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "pair", histName); + } + + if (classStr.Contains("Triplets")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "pair", histName); + } + + if (classStr.Contains("MCTruthGenPair")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "mctruth_pair", histName); + } + + if (classStr.Contains("MCTruthGenSelBR")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "mctruth_triple"); + } else if (classStr.Contains("MCTruthGen")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "mctruth_track"); + } + + // if (classStr.Contains("MCTruthGen")) { + // dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "mctruth_track"); + // } + + if (classStr.Contains("DileptonsSelected")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "pair", "barrel,vertexing"); + } + + if (classStr.Contains("DileptonTrack") && !classStr.Contains("ME")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "dilepton-track", histName); + } + + if (classStr.Contains("DileptonTrackME")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "dilepton-track", "mixedevent"); + } + + if (classStr.Contains("HadronsSelected")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "track", histName); + } + + if (classStr.Contains("DileptonHadronInvMass")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "dilepton-hadron-mass"); + } + + if (classStr.Contains("DileptonHadronCorrelation")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "dilepton-hadron-correlation"); + } + + if (classStr.Contains("MCTruthEenergyCorrelators")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "energy-correlator-gen"); + } + + } // end loop over histogram classes +} diff --git a/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx b/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx index 650f8c92b97..cda831fc5bf 100644 --- a/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx @@ -43,6 +43,7 @@ #include "TH1F.h" #include "TH2F.h" #include "TH3F.h" +#include "THnSparse.h" #include "TMath.h" #include "TProfile.h" #include "TProfile2D.h" @@ -83,6 +84,9 @@ struct RadialFlowDecorr { static constexpr float KCentTestMaxHi = 70.f; static constexpr float KCentCovCut = 1.0f; static constexpr float KBinOffset = 0.5f; + static constexpr int KNchPbMax = 3600; + static constexpr int KNchOMax = 600; + static constexpr float KHalf = 0.5f; static constexpr float KPhiMin = 0.f; @@ -101,7 +105,7 @@ struct RadialFlowDecorr { static constexpr int KNbinsPhi = 64; static constexpr float KEtaAxisMin = -0.8f; static constexpr float KEtaAxisMax = 0.8f; - static constexpr int KNbinsPhiFine = 30; + static constexpr int KNbinsPhiFine = 16; static constexpr int KNbinsPtRes = 50; static constexpr float KPtResMax = 1.f; static constexpr int KNbinsEtaRes = 100; @@ -129,7 +133,7 @@ struct RadialFlowDecorr { kCentFT0M = 3, kCentFV0A = 4 }; - enum SystemCounter { + enum SystemType { kPbPb = 1, kOO = 2, kpPb = 3, @@ -173,7 +177,6 @@ struct RadialFlowDecorr { Configurable cfgnSigmaCutTOF{"cfgnSigmaCutTOF", 2.0f, "PID nSigma cut for TOF"}; Configurable cfgnSigmaCutCombTPCTOF{"cfgnSigmaCutCombTPCTOF", 2.0f, "PID nSigma combined cut for TPC and TOF"}; Configurable cfgCutPtLower{"cfgCutPtLower", 0.2f, "Lower pT cut"}; - Configurable cfgCutPtLowerProt{"cfgCutPtLowerProt", 0.2f, "Lower pT cut"}; Configurable cfgCutPtUpper{"cfgCutPtUpper", 10.0f, "Higher pT cut for inclusive hadron analysis"}; Configurable cfgCutPtUpperPID{"cfgCutPtUpperPID", 6.0f, "Higher pT cut for identified particle analysis"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "absolute Eta cut"}; @@ -185,16 +188,40 @@ struct RadialFlowDecorr { Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time interval with dead ITS zone"}; Configurable cfgEvSelkNoITSROFrameBorder{"cfgEvSelkNoITSROFrameBorder", true, "ITSROFrame border event selection cut"}; Configurable cfgEvSelkNoTimeFrameBorder{"cfgEvSelkNoTimeFrameBorder", true, "TimeFrame border event selection cut"}; - Configurable cfgSys{"cfgSys", 2, "Efficiency to be used for which wystem? 1-->PbPb, 2-->OO, 3-->pPb, 4-->pp"}; + Configurable cfgSys{"cfgSys", 2, "Efficiency to be used for which system? 1-->PbPb, 2-->OO, 3-->pPb, 4-->pp"}; Configurable cfgFlat{"cfgFlat", true, "Whether to use flattening weights or not"}; + Configurable cfgCCDBurl{"cfgCCDBurl", "https://alice-ccdb.cern.ch", "ccdb url"}; + Configurable cfgCCDBUserPath{"cfgCCDBUserPath", "/Users/s/somadutt", "Base CCDB path"}; + + ConfigurableAxis cfgAxisCent{"cfgAxisCent", {0.0, 1.0, 3.0, 5.0, 10, 20, 30, 40, 50, 60, 70, 80, 100}, "centrality axis (percentile)"}; + const AxisSpec centAxis{cfgAxisCent, "Centrality (%)"}; + + AxisSpec nChAxis{1, 0., 1., "Nch", "Nch"}; + AxisSpec nChAxis2{1, 0., 1., "Nch", "Nch"}; + + const AxisSpec vzAxis{5, -12.5, 12.5, + "Vz" + "Vz"}; + const AxisSpec chgAxis{3, -1.5, 1.5}; + ConfigurableAxis cfgpTAxis{"cfgpTAxis", {0.0, 0.2, 0.5, 1, 3, 5, 7.5, 10}, "pT axis for flattening"}; + const AxisSpec pTAxis{cfgpTAxis, "pT"}; + + Configurable cfgRunGetEff{"cfgRunGetEff", false, "Run MC pass to build efficiency/fake maps"}; + Configurable cfgRunGetMCFlat{"cfgRunGetMCFlat", false, "Run MC to Get Flattening Weights"}; + Configurable cfgRunMCMean{"cfgRunMCMean", false, "Run MC mean(pT) & mean(Et)"}; + Configurable cfgRunMCFluc{"cfgRunMCFluc", false, "Run MC fluctuations (C2, subevent)"}; + Configurable cfgRunGetDataFlat{"cfgRunGetDataFlat", false, "Run Data Get Flattening Weights"}; + Configurable cfgRunDataMean{"cfgRunDataMean", false, "Run DATA mean(pT) & mean(Et)"}; + Configurable cfgRunDataFluc{"cfgRunDataFluc", false, "Run DATA fluctuations (C2, subevent)"}; + Service ccdb; Service pdg; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; std::array hEff{}; std::array hFake{}; - std::array hWeightMap3D{}; + std::array hFlatWeight{}; TProfile3D* pmeanTruNchEtabinPtbinStep2 = nullptr; TProfile3D* pmeanRecoNchEtabinPtbinStep2 = nullptr; @@ -211,6 +238,17 @@ struct RadialFlowDecorr { TProfile3D* pmeanNchEtabinPtbinStep2 = nullptr; TProfile3D* pmeanEtNchEtabinPtbinStep2 = nullptr; + // Helper to calculate all three combined PID sigmas at once + template + static std::tuple getAllCombinedNSigmas(const T& candidate) + { + return { + std::hypot(candidate.tpcNSigmaPr(), candidate.tofNSigmaPr()), // Proton + std::hypot(candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()), // Pion + std::hypot(candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()) // Kaon + }; + } + template bool isEventSelected(const T& col) { @@ -282,10 +320,7 @@ struct RadialFlowDecorr { } } if (candidate.hasTOF() && candidate.pt() > cfgCutPtUpperTPC && candidate.pt() < cfgCutPtUpperPID) { - float combNSigmaPr = std::sqrt(std::pow(candidate.tpcNSigmaPr(), 2.0) + std::pow(candidate.tofNSigmaPr(), 2.0)); - float combNSigmaPi = std::sqrt(std::pow(candidate.tpcNSigmaPi(), 2.0) + std::pow(candidate.tofNSigmaPi(), 2.0)); - float combNSigmaKa = std::sqrt(std::pow(candidate.tpcNSigmaKa(), 2.0) + std::pow(candidate.tofNSigmaKa(), 2.0)); - + auto [combNSigmaPr, combNSigmaPi, combNSigmaKa] = getAllCombinedNSigmas(candidate); int flag2 = 0; if (combNSigmaPr < cfgnSigmaOtherParticles) flag2 += 1; @@ -321,10 +356,7 @@ struct RadialFlowDecorr { } } if (candidate.hasTOF() && candidate.pt() > cfgCutPtUpperTPC && candidate.pt() < cfgCutPtUpperPID) { - float combNSigmaPr = std::sqrt(std::pow(candidate.tpcNSigmaPr(), 2.0) + std::pow(candidate.tofNSigmaPr(), 2.0)); - float combNSigmaPi = std::sqrt(std::pow(candidate.tpcNSigmaPi(), 2.0) + std::pow(candidate.tofNSigmaPi(), 2.0)); - float combNSigmaKa = std::sqrt(std::pow(candidate.tpcNSigmaKa(), 2.0) + std::pow(candidate.tofNSigmaKa(), 2.0)); - + auto [combNSigmaPr, combNSigmaPi, combNSigmaKa] = getAllCombinedNSigmas(candidate); int flag2 = 0; if (combNSigmaPr < cfgnSigmaOtherParticles) flag2 += 1; @@ -360,10 +392,7 @@ struct RadialFlowDecorr { } } if (candidate.hasTOF() && candidate.pt() > cfgCutPtUpperTPC && candidate.pt() < cfgCutPtUpperPID) { - float combNSigmaPr = std::sqrt(std::pow(candidate.tpcNSigmaPr(), 2.0) + std::pow(candidate.tofNSigmaPr(), 2.0)); - float combNSigmaPi = std::sqrt(std::pow(candidate.tpcNSigmaPi(), 2.0) + std::pow(candidate.tofNSigmaPi(), 2.0)); - float combNSigmaKa = std::sqrt(std::pow(candidate.tpcNSigmaKa(), 2.0) + std::pow(candidate.tofNSigmaKa(), 2.0)); - + auto [combNSigmaPr, combNSigmaPi, combNSigmaKa] = getAllCombinedNSigmas(candidate); int flag2 = 0; if (combNSigmaPr < cfgnSigmaOtherParticles) flag2 += 1; @@ -413,15 +442,22 @@ struct RadialFlowDecorr { return val; } - float getFlatteningWeight(float cent, float eta, float phi, PID pidType) const + float getFlatteningWeight(float vz, float chg, float pt, float eta, float phi, PID pidType, bool cfgflat) const { - TH3F* h = hWeightMap3D[pidType]; + if (!cfgflat) + return 1.0; + THnSparseF* h = hFlatWeight[pidType]; + if (!h) - return -1; - const int ibx = h->GetXaxis()->FindBin(cent); - const int iby = h->GetYaxis()->FindBin(eta); - const int ibz = h->GetZaxis()->FindBin(phi); - float val = h->GetBinContent(ibx, iby, ibz); + return 0.0; + int bins[5]; + bins[0] = h->GetAxis(0)->FindBin(vz); + bins[1] = h->GetAxis(1)->FindBin(chg); + bins[2] = h->GetAxis(2)->FindBin(pt); + bins[3] = h->GetAxis(3)->FindBin(eta); + bins[4] = h->GetAxis(4)->FindBin(phi); + float val = h->GetBinContent(bins); + return val; } @@ -464,21 +500,6 @@ struct RadialFlowDecorr { return {calculatedMeanPt, twopcorr}; } - ConfigurableAxis cfgAxisCent{"cfgAxisCent", {0.0, 1.0, 3.0, 5.0, 10, 20, 30, 40, 50, 60, 70, 80, 100}, "centrality axis (percentile)"}; // FT0*/FV0A style - const AxisSpec centAxis{cfgAxisCent, "Centrality (%)"}; - static constexpr int KNbinsNch = 5000; - static constexpr float KNchMax = 5000.5f; - static constexpr int KNbinsNchCoarse = 500; - ConfigurableAxis nChAxis{"nChAxis", {KNbinsNch, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - ConfigurableAxis nChAxis2{"nChAxis2", {KNbinsNchCoarse, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - - Configurable cfgRunGetEff{"cfgRunGetEff", false, "Run MC pass to build efficiency/fake maps"}; - Configurable cfgRunMCMean{"cfgRunMCMean", false, "Run MC mean(pT) & mean(Et)"}; - Configurable cfgRunMCFluc{"cfgRunMCFluc", false, "Run MC fluctuations (C2, subevent)"}; - Configurable cfgRunGetFlat{"cfgRunGetFlat", false, "Run Data Get Flattening Weights"}; - Configurable cfgRunDataMean{"cfgRunDataMean", false, "Run DATA mean(pT) & mean(Et)"}; - Configurable cfgRunDataFluc{"cfgRunDataFluc", false, "Run DATA fluctuations (C2, subevent)"}; - using GeneralCollisions = soa::Join< aod::Collisions, aod::EvSels, @@ -532,24 +553,8 @@ struct RadialFlowDecorr { histos.add("hEta", ";#eta", kTH1F, {{KNbinsEta, KEtaMin, KEtaMax}}); histos.add("hPhi", ";#phi", kTH1F, {{KNbinsPhi, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhi", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent1EtaPhi", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent7EtaPhi", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiWtd", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent1EtaPhiWtd", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent7EtaPhiWtd", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - - histos.add("hCentEtaPhiWtd_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent1EtaPhiWtd_PID", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent7EtaPhiWtd_PID", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - - histos.add("hCentEtaPhiTrue", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiReco", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiRecoMatched", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - - histos.add("hCentEtaPhiTrue_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiReco_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiRecoMatched_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiReco", "hEtaPhiReco", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1) / 2, KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiReco_PID", "hEtaPhiReco_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1) / 2, KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); } void declareMCCommonHists() { @@ -578,6 +583,7 @@ struct RadialFlowDecorr { histos.add("h_RecoMatchedToPrimary", ";p_{T}", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); histos.add("h_RecoUnMatchedToPrimary", ";p_{T}", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); histos.add("h_AllReco", ";p_{T}", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); + histos.add("h_AllRecoEffCorr", ";p_{T}", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); histos.add("hReco_ParticleWeight", ";cent;p_{T};#eta", kTH3F, {{centAxis}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsPtRes, -KEtaFineMax, KEtaFineMax}}); histos.add("hTruth_ParticleWeight", ";cent;p_{T};#eta", kTH3F, {{centAxis}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsPtRes, -KEtaFineMax, KEtaFineMax}}); @@ -586,6 +592,10 @@ struct RadialFlowDecorr { histos.add("hDCAz_Unmatched", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); histos.add("hDCAxy_NotPrimary", ";DCA_{xy} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); histos.add("hDCAz_NotPrimary", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAxy_RecoMatched", ";DCA_{xy} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAz_RecoMatched", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAxy_Reco", ";DCA_{xy} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAz_Reco", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); } void declareMCMeanHists() @@ -620,6 +630,11 @@ struct RadialFlowDecorr { histos.add("pmeanEtRecoEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); histos.add("pmeanEtRecoMatchedEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("hEtaPhiRecoWtd", "hEtaPhiRecoWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd", "hEtaPhiRecoEffWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoWtd_PID", "hEtaPhiRecoWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd_PID", "hEtaPhiRecoEffWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.addClone("MCGen/", "MCReco/"); histos.addClone("MCGen/", "MCRecoMatched/"); histos.addClone("MCGen/", "MCRecoEffCorr/"); @@ -627,15 +642,10 @@ struct RadialFlowDecorr { } void declareMCFlucHists() { - static constexpr int KNbinsNchFluc = 1000; - - ConfigurableAxis nChAxis{"nChAxis", {KNbinsNch, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - ConfigurableAxis nChAxis2{"nChAxis2", {KNbinsNchCoarse, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - // pT cumulants histos.add("MCGen/Prof_C2_Cent", ";cent;C_{2}", kTProfile, {centAxis}); histos.add("MCGen/Prof_C2_Mult", ";N_{PV};C_{2}", kTProfile, {nChAxis}); - histos.add("MCGen/Prof_C2Sub_Mult_etabin_ptbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{KNbinsNchFluc, KBinOffset, KNchMax}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("MCGen/Prof_C2Sub_Mult_etabin_ptbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis2}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); histos.add("MCGen/Prof_ipt0_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); histos.add("MCGen/Prof_ipt1_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); histos.add("MCGen/Prof_ipt2_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); @@ -647,7 +657,7 @@ struct RadialFlowDecorr { histos.add("MCGen/Prof_ipt2_Cov_Eta", ";#eta;cov", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); histos.add("MCGen/Prof_C2Et_Cent", ";cent;C_{2}^{E_{T}}", kTProfile, {centAxis}); histos.add("MCGen/Prof_C2Et_Mult", ";N_{PV};C_{2}^{E_{T}}", kTProfile, {nChAxis}); - histos.add("MCGen/Prof_C2EtSub_Mult_etabin_ptbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{KNbinsNchFluc, KBinOffset, KNchMax}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("MCGen/Prof_C2EtSub_Mult_etabin_ptbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis2}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); histos.add("MCGen/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); histos.add("MCGen/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); histos.add("MCGen/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); @@ -675,9 +685,19 @@ struct RadialFlowDecorr { histos.add("pmeanEtRecoMatchedNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); histos.add("pmeanEtRecoEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); histos.add("pmeanEtRecoMatchedEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + histos.add("hEtaPhiRecoWtd", "hEtaPhiRecoWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd", "hEtaPhiRecoEffWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoWtd_PID", "hEtaPhiRecoWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd_PID", "hEtaPhiRecoEffWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); } void declareDataMeanHists() { + histos.add("hEtaPhiRecoWtd", "hEtaPhiRecoWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd", "hEtaPhiRecoEffWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoWtd_PID", "hEtaPhiRecoWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd_PID", "hEtaPhiRecoEffWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("Prof_cent_Nchrec", ";cent;#LT N_{PV}#GT", kTProfile, {centAxis}); histos.add("Prof_MeanpT_Cent", ";cent;#LT p_{T}#GT", kTProfile, {centAxis}); histos.add("pmean_nch_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); @@ -688,11 +708,26 @@ struct RadialFlowDecorr { void declareDataGetFlatHists() { - histos.add("hCentEtaPhi_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, 0, TwoPI}}); + histos.add("hEtaPhiRecoWtd", "hEtaPhiRecoWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd", "hEtaPhiRecoEffWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoWtd_PID", "hEtaPhiRecoWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd_PID", "hEtaPhiRecoEffWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + } + void declareMCGetFlatHists() + { + histos.add("hEtaPhiRecoWtd", "hEtaPhiRecoWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd", "hEtaPhiRecoEffWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoWtd_PID", "hEtaPhiRecoWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd_PID", "hEtaPhiRecoEffWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); } void declareDataFlucHists() { + histos.add("hEtaPhiRecoWtd", "hEtaPhiRecoWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd", "hEtaPhiRecoEffWtd", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoWtd_PID", "hEtaPhiRecoWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("hEtaPhiRecoEffWtd_PID", "hEtaPhiRecoEffWtd_PID", kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add("pmean_nch_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); histos.add("Prof_MeanEt_Cent", ";cent;#LT E_{T}#GT", kTProfile, {centAxis}); histos.add("pmeanEt_nch_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); @@ -728,36 +763,51 @@ struct RadialFlowDecorr { histos.add("Prof_ipt2_C2SubEt2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); } - TH3F* buildWeightMapFromRaw(TH3F* hRaw, const char* mapName) + THnSparseF* buildWeightMapFromRaw(THnSparseF* hRaw, const char* mapName) { if (!hRaw) { LOGF(error, "Raw eta-phi map for '%s' is null; no flattening will be applied.", mapName); return nullptr; } - auto hWeightMap = reinterpret_cast(hRaw->Clone(mapName)); - hWeightMap->SetTitle(Form("Flattening Weight Map %s (w_{#phi} = / N_{#phi})", mapName)); - hWeightMap->SetDirectory(nullptr); - hWeightMap->Reset(); - auto axC = hRaw->GetXaxis(); - auto axE = hRaw->GetYaxis(); - auto axP = hRaw->GetZaxis(); - for (int ic = 1; ic <= axC->GetNbins(); ++ic) { - for (int ie = 1; ie <= axE->GetNbins(); ++ie) { - // average over phi at fixed (cent,eta) - double sum = 0.0; - int nphi = axP->GetNbins(); - for (int ip = 1; ip <= nphi; ++ip) - sum += hRaw->GetBinContent(ic, ie, ip); - const double avg = (nphi > 0 ? sum / nphi : 0.0); - for (int ip = 1; ip <= nphi; ++ip) { - const double raw = hRaw->GetBinContent(ic, ie, ip); - const double w = (avg > 0.0 && raw > 0.0) ? (avg / raw) : 1.0; - hWeightMap->SetBinContent(ic, ie, ip, w); + auto hWMap = reinterpret_cast(hRaw->Clone(mapName)); + hWMap->SetTitle(Form("Flattening Weight Map %s (w_{#phi} = / N_{#phi})", mapName)); + // hWMap->SetDirectory(nullptr); + hWMap->Reset(); + auto axV = hRaw->GetAxis(0); // Vz + auto axChg = hRaw->GetAxis(1); // Charge + auto axPt = hRaw->GetAxis(2); // Charge + auto axE = hRaw->GetAxis(3); // Eta + auto axP = hRaw->GetAxis(4); // Phi + + int bins[5]; + for (int iv = 1; iv <= axV->GetNbins(); ++iv) { + bins[0] = iv; + for (int ichg = 1; ichg <= axChg->GetNbins(); ++ichg) { + bins[1] = ichg; + for (int ipt = 1; ipt <= axPt->GetNbins(); ++ipt) { + bins[2] = ipt; + for (int ie = 1; ie <= axE->GetNbins(); ++ie) { + bins[3] = ie; + double sum = 0.0; + int nphi = axP->GetNbins(); + for (int ip = 1; ip <= nphi; ++ip) { + bins[4] = ip; + sum += hRaw->GetBinContent(bins); + } + const double avg = (nphi > 0 ? sum / nphi : 0.0); + for (int ip = 1; ip <= nphi; ++ip) { + bins[4] = ip; + const double raw = hRaw->GetBinContent(bins); + const double w = (avg > 0.0 && raw > 0.0) ? (avg / raw) : 1.0; + hWMap->SetBinContent(bins, w); + } + } } } } + LOGF(info, "Flattening weight map '%s' built.", mapName); - return hWeightMap; + return hWMap; } inline void loadTProfile3D(TDirectory* dir, const char* name, TProfile3D*& target) @@ -766,19 +816,16 @@ struct RadialFlowDecorr { LOGF(error, "loadTProfile3D: directory is null for object %s", name); return; } - auto* obj = dir->Get(name); if (!obj) { LOGF(error, "loadTProfile3D: object '%s' not found in directory %s", name, dir->GetName()); return; } - auto* prof = dynamic_cast(obj); if (!prof) { LOGF(error, "loadTProfile3D: object '%s' is not a TProfile3D (it is %s)", name, obj->ClassName()); return; } - target = reinterpret_cast(prof->Clone(Form("%s_clone", name))); target->SetDirectory(nullptr); LOGF(info, "Loaded TProfile3D '%s' with entries = %.0f", name, target->GetEntries()); @@ -786,16 +833,45 @@ struct RadialFlowDecorr { void init(InitContext&) { - ccdb->setURL("https://alice-ccdb.cern.ch"); + if (cfgSys == 1) { + nChAxis = {KNchPbMax / 3, KBinOffset, KNchPbMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + nChAxis2 = {KNchPbMax / 10, KBinOffset, KNchPbMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + } else { + nChAxis = {KNchOMax, KBinOffset, KNchOMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + nChAxis2 = {KNchOMax / 6, KBinOffset, KNchOMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + } + + ccdb->setURL(cfgCCDBurl.value); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - int64_t now = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); + int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); - declareCommonQA(); + std::string sysDir = ""; + switch (cfgSys) { + case kPbPb: + sysDir = "PbPbTest"; + break; + case kOO: + sysDir = "OOTest"; + break; + case kpPb: + sysDir = "pPbTest"; + break; + case kpp: + sysDir = "ppTest"; + break; + default: + LOGF(fatal, "Invalid cfgSys value: %d", cfgSys.value); + } + + std::string pathEff = cfgCCDBUserPath.value + "/" + sysDir + "/Job1_EffMaps"; + std::string pathMCFlat = cfgCCDBUserPath.value + "/" + sysDir + "/Job1_MCFlatMaps"; + std::string pathMCMean = cfgCCDBUserPath.value + "/" + sysDir + "/Job2_MCMean"; + std::string pathDataFlat = cfgCCDBUserPath.value + "/" + sysDir + "/Job1_DataFlatMaps"; + std::string pathDataMean = cfgCCDBUserPath.value + "/" + sysDir + "/Job2_DataMean"; + declareCommonQA(); std::string userCcdbPath; if (cfgSys == kPbPb) { userCcdbPath = "/Users/s/somadutt/PbPbTest/"; @@ -818,15 +894,17 @@ struct RadialFlowDecorr { } if (cfgRunMCFluc) { declareMCFlucHists(); - histos.addClone("MCGen/", "MCReco/"); histos.addClone("MCGen/", "MCRecoMatched/"); histos.addClone("MCGen/", "MCRecoEffCorr/"); histos.addClone("MCGen/", "MCRecoMatchedEffCorr/"); } - if (cfgRunGetFlat) { + if (cfgRunGetDataFlat) { declareDataGetFlatHists(); } + if (cfgRunGetMCFlat) { + declareMCGetFlatHists(); + } if (cfgRunDataMean) { declareDataMeanHists(); } @@ -834,10 +912,14 @@ struct RadialFlowDecorr { declareDataFlucHists(); } - const bool needEffMaps = cfgRunMCMean || cfgRunMCFluc || cfgRunDataMean || cfgRunDataFluc; - if (needEffMaps && !cfgRunGetEff) { + if (!cfgRunGetEff) { + TList* lst = ccdb->getForTimeStamp(pathEff, now); - LOGF(info, "Loading Eff/Fake maps from CCDB path: %s", userCcdbPath.c_str()); + if (!lst) { + LOGF(fatal, "Efficiency maps required but CCDB list is null at %s!", pathEff.c_str()); + } + + LOGF(info, "Loading Eff/Fake maps from TList..."); auto loadEffFakeForPID = [&](PID pidType) { std::string suffix = pidSuffix[pidType]; @@ -847,108 +929,132 @@ struct RadialFlowDecorr { std::string hFakeNumFakName = "h3_RecoUnMatchedToPrimary_Fake" + suffix; std::string hFakeDenName = "h3_AllReco" + suffix; - // --- Efficiency --- - auto* hNum = ccdb->get(userCcdbPath + hEffNumName); - auto* hDen = ccdb->get(userCcdbPath + hEffDenName); + auto* hNum = reinterpret_cast(lst->FindObject(hEffNumName.c_str())); + auto* hDen = reinterpret_cast(lst->FindObject(hEffDenName.c_str())); + if (hNum && hDen) { hEff[pidType] = reinterpret_cast(hNum->Clone(Form("hEff%s", suffix.c_str()))); hEff[pidType]->SetDirectory(nullptr); hEff[pidType]->Divide(hDen); } else { - LOGF(error, "Missing CCDB objects for efficiency. Checked:\n%s\n%s", - (userCcdbPath + hEffNumName).c_str(), - (userCcdbPath + hEffDenName).c_str()); + LOGF(error, "Missing CCDB objects for efficiency. Checked in list: %s, %s", hEffNumName.c_str(), hEffDenName.c_str()); } - // --- Fakes --- - auto* hNumS = ccdb->get(userCcdbPath + hFakeNumSecName); - auto* hNumF = ccdb->get(userCcdbPath + hFakeNumFakName); - auto* hDenF = ccdb->get(userCcdbPath + hFakeDenName); + auto* hNumS = reinterpret_cast(lst->FindObject(hFakeNumSecName.c_str())); + auto* hNumF = reinterpret_cast(lst->FindObject(hFakeNumFakName.c_str())); + auto* hDenF = reinterpret_cast(lst->FindObject(hFakeDenName.c_str())); + if (hNumS && hNumF && hDenF) { hFake[pidType] = reinterpret_cast(hNumS->Clone(Form("hFake%s", suffix.c_str()))); hFake[pidType]->Add(hNumF); hFake[pidType]->SetDirectory(nullptr); hFake[pidType]->Divide(hDenF); } else { - LOGF(error, "Missing CCDB object(s) for fakes for %s. Checked path prefix: %s", - suffix.c_str(), userCcdbPath.c_str()); + LOGF(error, "Missing CCDB object(s) for fakes for %s in list.", suffix.c_str()); } }; loadEffFakeForPID(kInclusive); loadEffFakeForPID(kCombinedPID); - const bool isDataRun = cfgRunDataMean || cfgRunDataFluc; - if (isDataRun) { - LOGF(info, "Data Run: Loading flattening maps from CCDB path: %s", userCcdbPath.c_str()); + // --- 1. Load Data Flattening Maps (if DataMean or DataFluc) --- + if (cfgRunDataMean || cfgRunDataFluc) { + LOGF(info, "Data Run: Loading flattening maps from CCDB path: %s", pathDataFlat.c_str()); + + TList* lstDataFlat = ccdb->getForTimeStamp(pathDataFlat, now); + + if (lstDataFlat) { + auto* hRawIncl = reinterpret_cast(lstDataFlat->FindObject("hEtaPhiRecoEffWtd")); + if (hRawIncl) { + hFlatWeight[kInclusive] = buildWeightMapFromRaw(hRawIncl, "hFlatWeight"); + } else { + LOGF(error, "Data flattening 'hEtaPhiRecoEffWtd' not found in list from %s", pathDataFlat.c_str()); + } - auto* hRawIncl = ccdb->get(userCcdbPath + "hCentEtaPhi"); - if (hRawIncl) { - hWeightMap3D[kInclusive] = buildWeightMapFromRaw(hRawIncl, "hWeightMap3D"); + auto* hRawPID = reinterpret_cast(lstDataFlat->FindObject("hEtaPhiRecoEffWtd_PID")); + if (hRawPID) { + hFlatWeight[kCombinedPID] = buildWeightMapFromRaw(hRawPID, "hFlatWeight_PID"); + } else { + LOGF(error, "Data flattening 'hEtaPhiRecoEffWtd_PID' not found in list from %s", pathDataFlat.c_str()); + } } else { - LOGF(error, "Data flattening 'hCentEtaPhi' not found at path %s", - (userCcdbPath + "hCentEtaPhi").c_str()); + LOGF(error, "Could not retrieve TList for Data Flattening from: %s", pathDataFlat.c_str()); } + } + + // --- 2. Load MC Flattening Maps (if MCMean or MCFluc) --- + if (cfgRunMCMean || cfgRunMCFluc) { + LOGF(info, "MC Run: Loading flattening maps from MC Flat list (%s)...", pathMCFlat.c_str()); + + TList* lstMCFlat = ccdb->getForTimeStamp(pathMCFlat, now); + if (lstMCFlat) { + auto loadFlatForPID = [&](PID pidType) { + std::string suffix = pidSuffix[pidType]; + std::string hFlatSrcName = "hEtaPhiRecoEffWtd" + suffix; + + auto* hRaw = reinterpret_cast(lstMCFlat->FindObject(hFlatSrcName.c_str())); - auto* hRawPID = ccdb->get(userCcdbPath + "hCentEtaPhi_PID"); - if (hRawPID) { - hWeightMap3D[kCombinedPID] = buildWeightMapFromRaw(hRawPID, "hWeightMap3D_PID"); + if (hRaw) { + hFlatWeight[pidType] = buildWeightMapFromRaw(hRaw, Form("hFlatWeight%s", suffix.c_str())); + } else { + LOGF(warning, "MC flattening source '%s' not found in list; skipping this PID.", hFlatSrcName.c_str()); + } + }; + + loadFlatForPID(kInclusive); + loadFlatForPID(kCombinedPID); } else { - LOGF(error, "Data flattening 'hCentEtaPhi_PID' not found at path %s", - (userCcdbPath + "hCentEtaPhi_PID").c_str()); + LOGF(error, "Could not retrieve TList for MC Flattening from: %s", pathMCFlat.c_str()); } - } else { - LOGF(info, "MC Run: Loading flattening maps from CCDB path: %s", userCcdbPath.c_str()); - - auto loadFlatForPID = [&](PID pidType) { - std::string suffix = pidSuffix[pidType]; - std::string hFlatSrcName = "hCentEtaPhiReco" + suffix; - auto* hRaw = ccdb->get(userCcdbPath + hFlatSrcName); - if (hRaw) { - hWeightMap3D[pidType] = buildWeightMapFromRaw(hRaw, Form("hWeightMap3D%s", suffix.c_str())); - } else { - LOGF(warning, "MC flattening source '%s' not found at %s; skipping this PID.", - hFlatSrcName.c_str(), (userCcdbPath + hFlatSrcName).c_str()); - } - }; - loadFlatForPID(kInclusive); - loadFlatForPID(kCombinedPID); } } - auto loadTProfile3DFromCCDB = [&](const std::string& ccdbPath, const char* objName, TProfile3D*& target) { - std::string fullPath = ccdbPath + objName; - LOGF(info, "Loading TProfile3D from CCDB: %s", fullPath.c_str()); - if (auto* tp = ccdb->get(fullPath)) { + auto loadTProfile3DFromList = [&](TList* sourceList, const char* objName, TProfile3D*& target) { + if (!sourceList) + return; + + auto* tp = reinterpret_cast(sourceList->FindObject(objName)); + if (tp) { target = reinterpret_cast(tp->Clone()); target->SetDirectory(nullptr); + LOGF(info, "Loaded %s from list", objName); } else { - LOGF(error, "Histogram %s missing in CCDB at path: %s", objName, fullPath.c_str()); + LOGF(error, "Histogram %s missing in CCDB TList", objName); } }; if (cfgRunMCFluc) { - LOGF(info, "Loading MC Mean profiles from CCDB path: %s", userCcdbPath.c_str()); - - loadTProfile3DFromCCDB(userCcdbPath, "pmeanTruNchEtabinPtbin", pmeanTruNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoNchEtabinPtbin", pmeanRecoNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoMatchedNchEtabinPtbin", pmeanRecoMatchedNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoEffcorrNchEtabinPtbin", pmeanRecoEffcorrNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoMatchedEffcorrNchEtabinPtbin", pmeanRecoMatchedEffcorrNchEtabinPtbinStep2); - - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtTruNchEtabinPtbin", pmeanEtTruNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoNchEtabinPtbin", pmeanEtRecoNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoMatchedNchEtabinPtbin", pmeanEtRecoMatchedNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoEffcorrNchEtabinPtbin", pmeanEtRecoEffcorrNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoMatchedEffcorrNchEtabinPtbin", pmeanEtRecoMatchedEffcorrNchEtabinPtbinStep2); + LOGF(info, "Loading MC Mean profiles from CCDB path: %s", pathMCMean.c_str()); + TList* lstMCMean = ccdb->getForTimeStamp(pathMCMean, now); + + if (lstMCMean) { + loadTProfile3DFromList(lstMCMean, "pmeanTruNchEtabinPtbin", pmeanTruNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanRecoNchEtabinPtbin", pmeanRecoNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanRecoMatchedNchEtabinPtbin", pmeanRecoMatchedNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanRecoEffcorrNchEtabinPtbin", pmeanRecoEffcorrNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanRecoMatchedEffcorrNchEtabinPtbin", pmeanRecoMatchedEffcorrNchEtabinPtbinStep2); + + loadTProfile3DFromList(lstMCMean, "pmeanEtTruNchEtabinPtbin", pmeanEtTruNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanEtRecoNchEtabinPtbin", pmeanEtRecoNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanEtRecoMatchedNchEtabinPtbin", pmeanEtRecoMatchedNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanEtRecoEffcorrNchEtabinPtbin", pmeanEtRecoEffcorrNchEtabinPtbinStep2); + loadTProfile3DFromList(lstMCMean, "pmeanEtRecoMatchedEffcorrNchEtabinPtbin", pmeanEtRecoMatchedEffcorrNchEtabinPtbinStep2); + } else { + LOGF(error, "Could not retrieve TList for MC Mean from: %s", pathMCMean.c_str()); + } } if (cfgRunDataFluc) { - LOGF(info, "Loading Data Mean profiles from CCDB path: %s", userCcdbPath.c_str()); - loadTProfile3DFromCCDB(userCcdbPath, "pmean_nch_etabin_ptbin", pmeanNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEt_nch_etabin_ptbin", pmeanEtNchEtabinPtbinStep2); - } + LOGF(info, "Loading Data Mean profiles from CCDB path: %s", pathDataMean.c_str()); + TList* lstDataMean = ccdb->getForTimeStamp(pathDataMean, now); + if (lstDataMean) { + loadTProfile3DFromList(lstDataMean, "pmean_nch_etabin_ptbin", pmeanNchEtabinPtbinStep2); + loadTProfile3DFromList(lstDataMean, "pmeanEt_nch_etabin_ptbin", pmeanEtNchEtabinPtbinStep2); + } else { + LOGF(error, "Could not retrieve TList for Data Mean from: %s", pathDataMean.c_str()); + } + } LOGF(info, "CCDB initialization complete for RadialFlowDecorr."); } @@ -962,6 +1068,7 @@ struct RadialFlowDecorr { for (const auto& col : colSlice) { if (!col.has_mcCollision()) continue; + histos.fill(HIST("hVtxZ"), col.posZ()); if (!isEventSelected(col)) continue; @@ -972,15 +1079,17 @@ struct RadialFlowDecorr { auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); if (partSlice.size() < 1) continue; - if (col.globalIndex() >= trackSlice.size()) { - LOGF(warning, "Skipping invalid globalIndex=%d for tracks (tracks.size=%d)", col.globalIndex(), tracks.size()); - continue; - } float cent = getCentrality(col); if (cent > KCentMax) continue; + histos.fill(HIST("hZvtx_after_sel"), col.posZ()); + + histos.fill(HIST("hCentrality"), cent); + histos.fill(HIST("Hist2D_globalTracks_PVTracks"), col.multNTracksPV(), tracks.size()); + histos.fill(HIST("Hist2D_cent_nch"), col.multNTracksPV(), cent); + for (const auto& particle : partSlice) { if (!isParticleSelected(particle)) continue; @@ -994,16 +1103,10 @@ struct RadialFlowDecorr { const bool isPid = (isPion || isKaon || isProton); histos.fill(HIST("hTruth_ParticleWeight"), cent, particle.pt(), particle.eta(), particle.weight()); - histos.fill(HIST("hCentEtaPhiTrue"), cent, particle.eta(), particle.phi()); histos.fill(HIST("h3_AllPrimary"), col.multNTracksPV(), particle.pt(), particle.eta()); - - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhi"), particle.eta(), particle.phi()); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhi"), particle.eta(), particle.phi()); + histos.fill(HIST("h_AllPrimary"), particle.pt()); if (isPid) { - histos.fill(HIST("hCentEtaPhiTrue_PID"), cent, particle.eta(), particle.phi()); histos.fill(HIST("h3_AllPrimary_PID"), col.multNTracksPV(), particle.pt(), particle.eta()); } } @@ -1019,13 +1122,20 @@ struct RadialFlowDecorr { const bool isKaon = selectionKaon(track); const bool isProton = selectionProton(track); const bool isPid = (isPion || isKaon || isProton); + histos.fill(HIST("hP"), track.p()); + histos.fill(HIST("hPt"), track.pt()); + histos.fill(HIST("hEta"), track.eta()); + histos.fill(HIST("hPhi"), track.phi()); + histos.fill(HIST("h_AllReco"), track.pt()); histos.fill(HIST("h3_AllReco"), col.multNTracksPV(), track.pt(), track.eta()); - histos.fill(HIST("hCentEtaPhiReco"), cent, track.eta(), track.phi()); + histos.fill(HIST("hEtaPhiReco"), col.posZ(), track.sign(), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("hDCAxy_Reco"), track.dcaXY()); + histos.fill(HIST("hDCAz_Reco"), track.dcaZ()); if (isPid) { histos.fill(HIST("h3_AllReco_PID"), col.multNTracksPV(), track.pt(), track.eta()); - histos.fill(HIST("hCentEtaPhiReco_PID"), cent, track.eta(), track.phi()); + histos.fill(HIST("hEtaPhiReco_PID"), col.posZ(), track.sign(), track.pt(), track.eta(), track.phi()); } if (track.has_mcParticle()) { @@ -1043,16 +1153,19 @@ struct RadialFlowDecorr { histos.fill(HIST("etaResolution"), mcPart2.eta(), mcPart2.eta() - track.eta()); histos.fill(HIST("etaTruthReco"), mcPart2.eta(), track.eta()); histos.fill(HIST("h3_RecoMatchedToPrimary"), col.multNTracksPV(), mcPart2.pt(), mcPart2.eta()); - histos.fill(HIST("hCentEtaPhiRecoMatched"), cent, mcPart2.eta(), mcPart2.phi()); + histos.fill(HIST("h_RecoMatchedToPrimary"), mcPart2.pt()); + + histos.fill(HIST("hDCAxy_RecoMatched"), track.dcaXY()); + histos.fill(HIST("hDCAz_RecoMatched"), track.dcaZ()); if (isPid && isPidTrue) { histos.fill(HIST("h3_RecoMatchedToPrimary_PID"), col.multNTracksPV(), mcPart2.pt(), mcPart2.eta()); - histos.fill(HIST("hCentEtaPhiRecoMatched_PID"), cent, mcPart2.eta(), mcPart2.phi()); } } else { // Matched to secondary histos.fill(HIST("h3_RecoUnMatchedToPrimary_Secondary"), col.multNTracksPV(), track.pt(), track.eta()); + histos.fill(HIST("h_RecoUnMatchedToPrimary"), track.pt()); histos.fill(HIST("hDCAxy_Unmatched"), track.dcaXY()); histos.fill(HIST("hDCAz_Unmatched"), track.dcaZ()); if (isPid) { @@ -1062,6 +1175,7 @@ struct RadialFlowDecorr { } else { // Fake track histos.fill(HIST("h3_RecoUnMatchedToPrimary_Fake"), col.multNTracksPV(), track.pt(), track.eta()); + histos.fill(HIST("h_RecoUnMatchedToPrimary"), track.pt()); histos.fill(HIST("hDCAxy_NotPrimary"), track.dcaXY()); histos.fill(HIST("hDCAz_NotPrimary"), track.dcaZ()); if (isPid) { @@ -1075,18 +1189,72 @@ struct RadialFlowDecorr { } PROCESS_SWITCH(RadialFlowDecorr, processGetEffHists, "process MC to calculate Eff and Fakes", cfgRunGetEff); + void processMCFlat(aod::McCollisions const& mcColl, soa::SmallGroups const& collisions, TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) + { + for (const auto& mcCollision : mcColl) { + auto colSlice = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + if (colSlice.size() != 1) + continue; + + for (const auto& col : colSlice) { + if (!col.has_mcCollision()) + continue; + if (!isEventSelected(col)) + continue; + + auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); + if (trackSlice.size() < 1) + continue; + + auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); + if (partSlice.size() < 1) + continue; + + float cent = getCentrality(col); + if (cent > KCentMax) + continue; + + // Reconstructed + for (const auto& track : trackSlice) { + if (!isTrackSelected(track)) + continue; + + float effIncl = getEfficiency(col.multNTracksPV(), track.pt(), track.eta(), kInclusive, 0); + float fakeIncl = getEfficiency(col.multNTracksPV(), track.pt(), track.eta(), kInclusive, 1); + float wIncl = (1.0 - fakeIncl) / effIncl; + if (!std::isfinite(wIncl) || wIncl <= 0.f) + continue; + if (effIncl <= 0 || !std::isfinite(effIncl) || !std::isfinite(fakeIncl)) + continue; + histos.fill(HIST("hEtaPhiRecoEffWtd"), col.posZ(), track.sign(), track.pt(), track.eta(), track.phi(), wIncl); + const bool isPion = selectionPion(track); + const bool isKaon = selectionKaon(track); + const bool isProton = selectionProton(track); + const bool isPid = (isPion || isKaon || isProton); + float effPid = getEfficiency(col.multNTracksPV(), track.pt(), track.eta(), kCombinedPID, 0); + float fakePid = getEfficiency(col.multNTracksPV(), track.pt(), track.eta(), kCombinedPID, 1); + float wPid = (1.0 - fakePid) / effPid; + if (effPid >= 1 || fakePid >= 1 || !std::isfinite(effPid) || effPid <= KFloatEpsilon || !std::isfinite(fakePid)) + continue; + + if (isPid) { + histos.fill(HIST("hEtaPhiRecoEffWtd_PID"), col.posZ(), track.sign(), track.pt(), track.eta(), track.phi(), wPid); + } + } // tracks + } // cols + } // mcColl + LOGF(info, "FINISHED RUNNING processMCFlat"); + } + PROCESS_SWITCH(RadialFlowDecorr, processMCFlat, "process MC to calculate FlatWeights", cfgRunGetMCFlat); + void processMCMean(aod::McCollisions const& mcColl, MyRun3MCCollisions const& collisions, TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) { float sumWiTruth[KNEta][KNpT], sumWiptiTruth[KNEta][KNpT]; float sumWiReco[KNEta][KNpT], sumWiptiReco[KNEta][KNpT]; - float sumWiRecoMatched[KNEta][KNpT], sumWiptiRecoMatched[KNEta][KNpT]; float sumWiRecoEffCorr[KNEta][KNpT], sumWiptiRecoEffCorr[KNEta][KNpT]; - float sumWiRecoMatchedEffCorr[KNEta][KNpT], sumWiptiRecoMatchedEffCorr[KNEta][KNpT]; float sumWiTruthEt[KNEta][KNpT], sumWiptiTruthEt[KNEta][KNpT]; float sumWiRecoEt[KNEta][KNpT], sumWiptiRecoEt[KNEta][KNpT]; - float sumWiRecoMatchedEt[KNEta][KNpT], sumWiptiRecoMatchedEt[KNEta][KNpT]; float sumWiRecoEffCorrEt[KNEta][KNpT], sumWiptiRecoEffCorrEt[KNEta][KNpT]; - float sumWiRecoMatchedEffCorrEt[KNEta][KNpT], sumWiptiRecoMatchedEffCorrEt[KNEta][KNpT]; for (const auto& mcCollision : mcColl) { auto colSlice = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); @@ -1098,7 +1266,7 @@ struct RadialFlowDecorr { continue; if (!isEventSelected(col)) continue; - + histos.fill(HIST("hVtxZ"), col.posZ()); auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); if (trackSlice.size() < 1) continue; @@ -1106,41 +1274,31 @@ struct RadialFlowDecorr { auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); if (partSlice.size() < 1) continue; - if (col.globalIndex() >= trackSlice.size()) { - LOGF(warning, "Skipping invalid globalIndex=%d for tracks (tracks.size=%d)", col.globalIndex(), tracks.size()); - continue; - } float cent = getCentrality(col); if (cent > KCentMax) continue; - if (col.globalIndex() >= trackSlice.size()) { - LOGF(warning, "Skipping invalid globalIndex=%d for tracks (tracks.size=%d)", col.globalIndex(), tracks.size()); - continue; - } + histos.fill(HIST("hZvtx_after_sel"), col.posZ()); + histos.fill(HIST("hCentrality"), cent); + histos.fill(HIST("Hist2D_globalTracks_PVTracks"), col.multNTracksPV(), tracks.size()); + histos.fill(HIST("Hist2D_cent_nch"), col.multNTracksPV(), cent); + histos.fill(HIST("TruthTracKVz"), mcCollision.posZ(), col.posZ()); + histos.fill(HIST("vzResolution"), mcCollision.posZ(), mcCollision.posZ() - col.posZ()); - LOGF(info, "Event Check: cent = %.1f, nTracks = %d", cent, (int)trackSlice.size()); + // LOGF(info, "Event Check: cent = %.1f, nTracks = %d", cent, (int)trackSlice.size()); memset(sumWiTruth, 0, sizeof(sumWiTruth)); memset(sumWiptiTruth, 0, sizeof(sumWiptiTruth)); memset(sumWiReco, 0, sizeof(sumWiReco)); memset(sumWiptiReco, 0, sizeof(sumWiptiReco)); - memset(sumWiRecoMatched, 0, sizeof(sumWiRecoMatched)); - memset(sumWiptiRecoMatched, 0, sizeof(sumWiptiRecoMatched)); memset(sumWiRecoEffCorr, 0, sizeof(sumWiRecoEffCorr)); memset(sumWiptiRecoEffCorr, 0, sizeof(sumWiptiRecoEffCorr)); - memset(sumWiRecoMatchedEffCorr, 0, sizeof(sumWiRecoMatchedEffCorr)); - memset(sumWiptiRecoMatchedEffCorr, 0, sizeof(sumWiptiRecoMatchedEffCorr)); memset(sumWiTruthEt, 0, sizeof(sumWiTruthEt)); memset(sumWiptiTruthEt, 0, sizeof(sumWiptiTruthEt)); memset(sumWiRecoEt, 0, sizeof(sumWiRecoEt)); memset(sumWiptiRecoEt, 0, sizeof(sumWiptiRecoEt)); - memset(sumWiRecoMatchedEt, 0, sizeof(sumWiRecoMatchedEt)); - memset(sumWiptiRecoMatchedEt, 0, sizeof(sumWiptiRecoMatchedEt)); memset(sumWiRecoEffCorrEt, 0, sizeof(sumWiRecoEffCorrEt)); memset(sumWiptiRecoEffCorrEt, 0, sizeof(sumWiptiRecoEffCorrEt)); - memset(sumWiRecoMatchedEffCorrEt, 0, sizeof(sumWiRecoMatchedEffCorrEt)); - memset(sumWiptiRecoMatchedEffCorrEt, 0, sizeof(sumWiptiRecoMatchedEffCorrEt)); // Truth for (const auto& particle : partSlice) { @@ -1187,24 +1345,18 @@ struct RadialFlowDecorr { float p = track.p(); float phi = track.phi(); - histos.fill(HIST("hCentEtaPhi"), cent, eta, phi); - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhi"), eta, phi); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhi"), eta, phi); + histos.fill(HIST("hEtaPhiReco"), col.posZ(), track.sign(), track.pt(), eta, phi); float effIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 0); float fakeIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - if (!cfgFlat) - flatWeightIncl = 1.0; + float flatWeightIncl = getFlatteningWeight(col.posZ(), track.sign(), pt, eta, phi, kInclusive, cfgFlat); float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; - - histos.fill(HIST("hCentEtaPhiWtd"), cent, eta, track.phi(), flatWeightIncl); - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhiWtd"), track.eta(), track.phi(), flatWeightIncl); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhiWtd"), track.eta(), track.phi(), flatWeightIncl); + if (!std::isfinite(wIncl) || wIncl <= 0.f) + continue; + if (effIncl <= 0 || !std::isfinite(effIncl) || !std::isfinite(fakeIncl) || !std::isfinite(flatWeightIncl)) + continue; + histos.fill(HIST("hEtaPhiRecoWtd"), col.posZ(), track.sign(), pt, eta, phi, flatWeightIncl); + histos.fill(HIST("hEtaPhiRecoEffWtd"), col.posZ(), track.sign(), pt, eta, phi, wIncl); for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) @@ -1235,18 +1387,15 @@ struct RadialFlowDecorr { const bool isKaon = selectionKaon(track); const bool isProton = selectionProton(track); if (isPion || isKaon || isProton) { + histos.fill(HIST("hEtaPhiReco_PID"), col.posZ(), track.sign(), track.pt(), eta, phi); float effPid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 0); float fakePid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); - if (!cfgFlat) - flatWeightPid = 1.0; + float flatWeightPid = getFlatteningWeight(col.posZ(), track.sign(), pt, eta, phi, kCombinedPID, cfgFlat); float wPid = flatWeightPid * (1.0 - fakePid) / effPid; - - histos.fill(HIST("hCentEtaPhiWtd_PID"), cent, eta, track.phi(), flatWeightPid); - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhiWtd_PID"), track.eta(), track.phi(), flatWeightPid); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhiWtd_PID"), track.eta(), track.phi(), flatWeightPid); + if (effPid >= 1 || fakePid >= 1 || !std::isfinite(effPid) || effPid <= KFloatEpsilon || !std::isfinite(fakePid) || !std::isfinite(flatWeightPid)) + continue; + histos.fill(HIST("hEtaPhiRecoWtd_PID"), col.posZ(), track.sign(), track.pt(), eta, track.phi(), flatWeightPid); + histos.fill(HIST("hEtaPhiRecoEffWtd_PID"), col.posZ(), track.sign(), track.pt(), eta, track.phi(), wPid); float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus : o2::constants::physics::MassProton; @@ -1377,7 +1526,6 @@ struct RadialFlowDecorr { } } // end col loop } - LOGF(info, "FINISHED RUNNING processMCMean (pT + Et)"); } PROCESS_SWITCH(RadialFlowDecorr, processMCMean, "process MC to calculate mean pt/Et and Eff Hists", cfgRunMCMean); @@ -1498,7 +1646,6 @@ struct RadialFlowDecorr { } } } - } // end truth loop for (const auto& track : trackSlice) { @@ -1511,9 +1658,7 @@ struct RadialFlowDecorr { float effIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 0); float fakeIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - if (!cfgFlat) - flatWeightIncl = 1.0; + float flatWeightIncl = getFlatteningWeight(col.posZ(), track.sign(), pt, eta, phi, kInclusive, cfgFlat); float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; if (!std::isfinite(wIncl) || wIncl <= 0.f) continue; @@ -1528,10 +1673,10 @@ struct RadialFlowDecorr { continue; for (int k = 0; k < KIntK; ++k) { for (int m = 0; m < KIntM; ++m) { - sumPmwkReco[ieta][ipt][m][k] += std::pow(1.0f, k) * std::pow(pt, m); + sumPmwkReco[ieta][ipt][m][k] += std::pow(1.0, k) * std::pow(pt, m); sumPmwkRecoEffCor[ieta][ipt][m][k] += std::pow(wIncl, k) * std::pow(pt, m); } - sumWkReco[ieta][ipt][k] += std::pow(1.0f, k); + sumWkReco[ieta][ipt][k] += std::pow(1.0, k); sumWkRecoEffCor[ieta][ipt][k] += std::pow(wIncl, k); } } @@ -1548,11 +1693,9 @@ struct RadialFlowDecorr { float et = energy * (pt / p); // E_T = E * sin(theta) float effPid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 0); float fakePid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); - if (!cfgFlat) - flatWeightPid = 1.0; - float wPid = flatWeightPid * (1.0 - fakePid) / effPid; - if (effPid >= 1.f || fakePid >= 1.f || !std::isfinite(effPid) || effPid <= KFloatEpsilon || !std::isfinite(fakePid) || !std::isfinite(flatWeightPid)) + float flatWeightPid = getFlatteningWeight(col.posZ(), track.sign(), pt, eta, phi, kCombinedPID, cfgFlat); + float wPid = flatWeightPid * (1 - fakePid) / effPid; + if (effPid >= 1 || fakePid >= 1 || !std::isfinite(effPid) || effPid <= KFloatEpsilon || !std::isfinite(fakePid) || !std::isfinite(flatWeightPid)) continue; for (int ieta = 0; ieta < KNEta; ++ieta) { @@ -1563,10 +1706,10 @@ struct RadialFlowDecorr { continue; for (int k = 0; k < KIntK; ++k) { for (int m = 0; m < KIntM; ++m) { - sumPmwkRecoEt[ieta][ipt][m][k] += std::pow(1.0f, k) * std::pow(et, m); + sumPmwkRecoEt[ieta][ipt][m][k] += std::pow(1.0, k) * std::pow(et, m); sumPmwkRecoEffCorEt[ieta][ipt][m][k] += std::pow(wPid, k) * std::pow(et, m); } - sumWkRecoEt[ieta][ipt][k] += std::pow(1.0f, k); + sumWkRecoEt[ieta][ipt][k] += std::pow(1.0, k); sumWkRecoEffCorEt[ieta][ipt][k] += std::pow(wPid, k); } } @@ -1707,98 +1850,68 @@ struct RadialFlowDecorr { } } - // 1D Covariance (vs eta) + // --- 1D Covariance --- for (int ietaA = 1; ietaA <= (KNEta - 1) / 2; ++ietaA) { int ietaC = KNEta - ietaA; float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - { - const int ipt = 0; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCGen/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCGen/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCGen/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); - } - } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCGen/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCGen/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCGen/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); - } - } - // ipt = 2 - { - const int ipt = 2; + + for (int ipt = 0; ipt < KNpT; ++ipt) { float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; if (std::isfinite(c2Sub)) { histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCGen/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt2_Cov_Eta"), valy, c2Sub); + switch (ipt) { + case 0: + histos.fill(HIST("MCGen/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCGen/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCGen/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("MCGen/Prof_ipt0_Cov_Eta"), valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCGen/Prof_ipt1_Cov_Eta"), valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCGen/Prof_ipt2_Cov_Eta"), valy, c2Sub); + break; + } + } } + float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; if (std::isfinite(c2SubEt)) { histos.fill(HIST("MCGen/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCGen/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); - } - } - } - - for (int ietaA = 1; ietaA < KNEta; ++ietaA) { - for (int ietaC = 1; ietaC < KNEta; ++ietaC) { - float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCGen/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCGen/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCGen/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCGen/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCGen/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCGen/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + switch (ipt) { + case 0: + histos.fill(HIST("MCGen/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCGen/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCGen/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("MCGen/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCGen/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCGen/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + break; + } + } } } } @@ -1806,100 +1919,64 @@ struct RadialFlowDecorr { for (int ietaA = 1; ietaA <= (KNEta - 1) / 2; ++ietaA) { int ietaC = KNEta - ietaA; float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCReco/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCReco/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCReco/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); - } - } - // ipt = 1 - { - const int ipt = 1; + for (int ipt = 0; ipt < KNpT; ++ipt) { float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; if (std::isfinite(c2Sub)) { histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCReco/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt1_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCReco/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCReco/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + switch (ipt) { + case 0: + histos.fill(HIST("MCReco/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCReco/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCReco/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("MCReco/Prof_ipt0_Cov_Eta"), valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCReco/Prof_ipt1_Cov_Eta"), valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCReco/Prof_ipt2_Cov_Eta"), valy, c2Sub); + break; + } + } } - } - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCReco/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt2_Cov_Eta"), valy, c2Sub); - } float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; if (std::isfinite(c2SubEt)) { histos.fill(HIST("MCReco/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCReco/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); - } - } - } - - for (int ietaA = 1; ietaA < KNEta; ++ietaA) { - for (int ietaC = 1; ietaC < KNEta; ++ietaC) { - float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCReco/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCReco/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCReco/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCReco/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCReco/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCReco/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + switch (ipt) { + case 0: + histos.fill(HIST("MCReco/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCReco/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCReco/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("MCReco/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCReco/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCReco/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + break; + } + } } } } @@ -1908,100 +1985,178 @@ struct RadialFlowDecorr { int ietaC = KNEta - ietaA; float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - // ipt = 0 - { - const int ipt = 0; + for (int ipt = 0; ipt < KNpT; ++ipt) { float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; if (std::isfinite(c2Sub)) { histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); + switch (ipt) { + case 0: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov_Eta"), valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov_Eta"), valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov_Eta"), valy, c2Sub); + break; + } + } } - } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov_Eta"), valy, c2Sub); - } float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; if (std::isfinite(c2SubEt)) { histos.fill(HIST("MCRecoEffCorr/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + switch (ipt) { + case 0: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + break; + } + } } } + } - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + // --- 2D Correlations --- + for (int ietaA = 1; ietaA < KNEta; ++ietaA) { + for (int ietaC = 1; ietaC < KNEta; ++ietaC) { + float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); + float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); + + for (int ipt = 0; ipt < KNpT; ++ipt) { + float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; + if (std::isfinite(c2Sub)) { + switch (ipt) { + case 0: + histos.fill(HIST("MCGen/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCGen/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCGen/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + } + } + float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; + if (std::isfinite(c2SubEt)) { + switch (ipt) { + case 0: + histos.fill(HIST("MCGen/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCGen/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCGen/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + } + } } } } for (int ietaA = 1; ietaA < KNEta; ++ietaA) { for (int ietaC = 1; ietaC < KNEta; ++ietaC) { - float valx = 0.5f * (etaLw[ietaA] + etaUp[ietaA]); + float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + for (int ipt = 0; ipt < KNpT; ++ipt) { + float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; + if (std::isfinite(c2Sub)) { + switch (ipt) { + case 0: + histos.fill(HIST("MCReco/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCReco/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCReco/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + } + } + float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; + if (std::isfinite(c2SubEt)) { + switch (ipt) { + case 0: + histos.fill(HIST("MCReco/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCReco/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCReco/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + } + } } + } + } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } + for (int ietaA = 1; ietaA < KNEta; ++ietaA) { + for (int ietaC = 1; ietaC < KNEta; ++ietaC) { + float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); + float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - // ipt = 2 - { - const int ipt = 2; + for (int ipt = 0; ipt < KNpT; ++ipt) { float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + if (std::isfinite(c2Sub)) { + switch (ipt) { + case 0: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + case 1: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + case 2: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); + break; + } + } float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + if (std::isfinite(c2SubEt)) { + switch (ipt) { + case 0: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + case 1: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + case 2: + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + break; + } + } } } } @@ -2011,7 +2166,7 @@ struct RadialFlowDecorr { } PROCESS_SWITCH(RadialFlowDecorr, processMCFluc, "process MC to calculate pt/Et fluc", cfgRunMCFluc); - void processGetFlat(AodCollisionsSel::iterator const& coll, aod::BCsWithTimestamps const&, AodTracksSel const& tracks) + void processGetDataFlat(AodCollisionsSel::iterator const& coll, aod::BCsWithTimestamps const&, AodTracksSel const& tracks) { if (!isEventSelected(coll)) return; @@ -2022,20 +2177,34 @@ struct RadialFlowDecorr { if (!isTrackSelected(track)) continue; float p = track.p(); + float pt = track.pt(); float eta = track.eta(); float phi = track.phi(); if (p < KFloatEpsilon) continue; - histos.fill(HIST("hCentEtaPhi"), cent, eta, phi); + float effIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 0); + float fakeIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 1); + float wIncl = (1.0 - fakeIncl) / effIncl; + if (!std::isfinite(wIncl) || wIncl <= KFloatEpsilon || effIncl <= KFloatEpsilon) + continue; + histos.fill(HIST("hEtaPhiReco"), coll.posZ(), track.sign(), pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd"), coll.posZ(), track.sign(), pt, eta, phi, wIncl); + const bool isPion = selectionPion(track); const bool isKaon = selectionKaon(track); const bool isProton = selectionProton(track); if (isPion || isKaon || isProton) { - histos.fill(HIST("hCentEtaPhi_PID"), cent, eta, phi); + float effPid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 0); + float fakePid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 1); + float wPid = (1.0 - fakePid) / effPid; + if (!std::isfinite(wPid) || wPid <= KFloatEpsilon || effPid <= KFloatEpsilon) + continue; + histos.fill(HIST("hEtaPhiReco_PID"), coll.posZ(), track.sign(), pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_PID"), coll.posZ(), track.sign(), pt, eta, phi, wPid); } } } - PROCESS_SWITCH(RadialFlowDecorr, processGetFlat, "process real data to calculate mean pT and Et", cfgRunGetFlat); + PROCESS_SWITCH(RadialFlowDecorr, processGetDataFlat, "process data to calculate Flattening maps", cfgRunGetDataFlat); void processDataMean(AodCollisionsSel::iterator const& coll, aod::BCsWithTimestamps const&, AodTracksSel const& tracks) { @@ -2070,15 +2239,14 @@ struct RadialFlowDecorr { float effIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 0); float fakeIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - if (!cfgFlat) - flatWeightIncl = 1.0; + float flatWeightIncl = getFlatteningWeight(coll.posZ(), track.sign(), pt, eta, phi, kInclusive, cfgFlat); float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; if (!std::isfinite(wIncl) || wIncl <= KFloatEpsilon || effIncl <= KFloatEpsilon) continue; - histos.fill(HIST("hCentEtaPhi"), cent, eta, track.phi()); - histos.fill(HIST("hCentEtaPhiWtd"), cent, eta, track.phi(), flatWeightIncl); + histos.fill(HIST("hEtaPhiReco"), coll.posZ(), track.sign(), pt, eta, track.phi()); + histos.fill(HIST("hEtaPhiRecoEffWtd"), coll.posZ(), track.sign(), eta, pt, track.phi(), (1.0 - fakeIncl) / effIncl); + histos.fill(HIST("hEtaPhiRecoWtd"), coll.posZ(), track.sign(), eta, pt, track.phi(), wIncl); for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) @@ -2095,17 +2263,17 @@ struct RadialFlowDecorr { const bool isKaon = selectionKaon(track); const bool isProton = selectionProton(track); if (isPion || isKaon || isProton) { - float effPid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 0); float fakePid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); - if (!cfgFlat) - flatWeightPid = 1.0; + float flatWeightPid = getFlatteningWeight(coll.posZ(), track.sign(), pt, eta, phi, kCombinedPID, cfgFlat); float wPid = flatWeightPid * (1.0 - fakePid) / effPid; if (!std::isfinite(wPid) || wPid <= KFloatEpsilon || effPid <= KFloatEpsilon) continue; - histos.fill(HIST("hCentEtaPhiWtd_PID"), cent, eta, track.phi(), flatWeightPid); + histos.fill(HIST("hEtaPhiReco_PID"), coll.posZ(), track.sign(), pt, eta, track.phi()); + histos.fill(HIST("hEtaPhiRecoEffWtd_PID"), coll.posZ(), track.sign(), eta, pt, track.phi(), (1.0 - fakePid) / effPid); + histos.fill(HIST("hEtaPhiRecoWtd_PID"), coll.posZ(), track.sign(), eta, pt, track.phi(), wPid); + float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus : o2::constants::physics::MassProton; float energy = std::sqrt(p * p + m * m); @@ -2137,7 +2305,7 @@ struct RadialFlowDecorr { } } } - PROCESS_SWITCH(RadialFlowDecorr, processDataMean, "process real data to calculate mean pT and Et", cfgRunDataMean); + PROCESS_SWITCH(RadialFlowDecorr, processDataMean, "process data to calculate mean pT and Et", cfgRunDataMean); void processDataFluc(AodCollisionsSel::iterator const& coll, aod::BCsWithTimestamps const&, AodTracksSel const& tracks) { @@ -2151,7 +2319,7 @@ struct RadialFlowDecorr { return; } - if (!hEff[kInclusive] || !hFake[kInclusive] || !hWeightMap3D[kInclusive] || !hEff[kCombinedPID] || !hFake[kCombinedPID] || !hWeightMap3D[kCombinedPID]) { + if (!hEff[kInclusive] || !hFake[kInclusive] || !hFlatWeight[kInclusive] || !hEff[kCombinedPID] || !hFake[kCombinedPID] || !hFlatWeight[kCombinedPID]) { LOGF(warning, "Data fluc: Inclusive or PID correction maps are null"); return; } @@ -2176,12 +2344,13 @@ struct RadialFlowDecorr { float effIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 0); float fakeIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - if (!cfgFlat) - flatWeightIncl = 1.0; + float flatWeightIncl = getFlatteningWeight(coll.posZ(), track.sign(), pt, eta, phi, kInclusive, cfgFlat); float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; if (!std::isfinite(wIncl) || wIncl <= KFloatEpsilon || effIncl <= KFloatEpsilon) continue; + histos.fill(HIST("hEtaPhiReco"), coll.posZ(), track.sign(), pt, eta, track.phi()); + histos.fill(HIST("hEtaPhiRecoEffWtd"), coll.posZ(), track.sign(), eta, pt, track.phi(), (1.0 - fakeIncl) / effIncl); + histos.fill(HIST("hEtaPhiRecoWtd"), coll.posZ(), track.sign(), eta, pt, track.phi(), wIncl); for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) @@ -2203,12 +2372,13 @@ struct RadialFlowDecorr { if (isPion || isKaon || isProton) { float effPid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 0); float fakePid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); - if (!cfgFlat) - flatWeightPid = 1.0; + float flatWeightPid = getFlatteningWeight(coll.posZ(), track.sign(), pt, eta, phi, kCombinedPID, cfgFlat); float wPid = flatWeightPid * (1.0 - fakePid) / effPid; if (!std::isfinite(wPid) || wPid <= KFloatEpsilon || effPid <= KFloatEpsilon) continue; + histos.fill(HIST("hEtaPhiReco_PID"), coll.posZ(), track.sign(), pt, eta, track.phi()); + histos.fill(HIST("hEtaPhiRecoEffWtd_PID"), coll.posZ(), track.sign(), eta, pt, track.phi(), (1.0 - fakePid) / effPid); + histos.fill(HIST("hEtaPhiRecoWtd_PID"), coll.posZ(), track.sign(), eta, pt, track.phi(), wPid); float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus : o2::constants::physics::MassProton; @@ -2280,52 +2450,61 @@ struct RadialFlowDecorr { for (int ietaA = 1; ietaA <= (KNEta - 1) / 2; ++ietaA) { int ietaC = KNEta - ietaA; float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - - { - const int ipt = 0; + for (int ipt = 0; ipt < KNpT; ++ipt) { float c2Sub = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt0_Cov_Eta"), valy, c2Sub); - } float c2SubEt = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt0_CovEt_Eta"), valy, c2SubEt); - } - } - - { - const int ipt = 1; - float c2Sub = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; if (std::isfinite(c2Sub)) { - histos.fill(HIST("Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt1_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + switch (ipt) { + case 0: + histos.fill(HIST("Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 1: + histos.fill(HIST("Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); + break; + case 2: + histos.fill(HIST("Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("Prof_ipt0_Cov_Eta"), valy, c2Sub); + break; + case 1: + histos.fill(HIST("Prof_ipt1_Cov_Eta"), valy, c2Sub); + break; + case 2: + histos.fill(HIST("Prof_ipt2_Cov_Eta"), valy, c2Sub); + break; + } + } } - } - { - const int ipt = 2; - float c2Sub = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt2_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; if (std::isfinite(c2SubEt)) { - histos.fill(HIST("Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + switch (ipt) { + case 0: + histos.fill(HIST("Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 1: + histos.fill(HIST("Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + case 2: + histos.fill(HIST("Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); + break; + } + if (cent < KCentCovCut) { + switch (ipt) { + case 0: + histos.fill(HIST("Prof_ipt0_CovEt_Eta"), valy, c2SubEt); + break; + case 1: + histos.fill(HIST("Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + break; + case 2: + histos.fill(HIST("Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + break; + } + } } } } @@ -2334,42 +2513,42 @@ struct RadialFlowDecorr { for (int ietaC = 1; ietaC < KNEta; ++ietaC) { float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - { - const int ipt = 0; - float covpt = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(covpt)) - histos.fill(HIST("Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); - - float covet = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(covet)) - histos.fill(HIST("Prof_ipt0_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); - } - - { - const int ipt = 1; - float covpt = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(covpt)) - histos.fill(HIST("Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); - - float covet = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(covet)) - histos.fill(HIST("Prof_ipt1_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); - } - { - const int ipt = 2; + for (int ipt = 0; ipt < KNpT; ++ipt) { float covpt = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(covpt)) - histos.fill(HIST("Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); + if (std::isfinite(covpt)) { + switch (ipt) { + case 0: + histos.fill(HIST("Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); + break; + case 1: + histos.fill(HIST("Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); + break; + case 2: + histos.fill(HIST("Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); + break; + } + } float covet = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(covet)) - histos.fill(HIST("Prof_ipt2_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); + if (std::isfinite(covet)) { + switch (ipt) { + case 0: + histos.fill(HIST("Prof_ipt0_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); + break; + case 1: + histos.fill(HIST("Prof_ipt1_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); + break; + case 2: + histos.fill(HIST("Prof_ipt2_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); + break; + } + } } } } } - PROCESS_SWITCH(RadialFlowDecorr, processDataFluc, "process real data to calculate fluc pT and Et", cfgRunDataFluc); + PROCESS_SWITCH(RadialFlowDecorr, processDataFluc, "process data to calculate fluc pT and Et", cfgRunDataFluc); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Femto/Core/cascadeHistManager.h b/PWGCF/Femto/Core/cascadeHistManager.h index e5c4e7c610e..39559a16f7e 100644 --- a/PWGCF/Femto/Core/cascadeHistManager.h +++ b/PWGCF/Femto/Core/cascadeHistManager.h @@ -215,30 +215,30 @@ constexpr std::array, kCascadeHistLast> HistT template auto makeCascadeHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ CASCADE_HIST_ANALYSIS_MAP(confBinningAnalysis)}; } template auto makeCascadeMcHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ CASCADE_HIST_ANALYSIS_MAP(confBinningAnalysis) CASCADE_HIST_MC_MAP(confBinningAnalysis)}; } template -std::map> makeCascadeQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +std::map> makeCascadeQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ CASCADE_HIST_ANALYSIS_MAP(confBinningAnalysis) CASCADE_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; } template -std::map> makeCascadeMcQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +std::map> makeCascadeMcQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ CASCADE_HIST_ANALYSIS_MAP(confBinningAnalysis) CASCADE_HIST_QA_MAP(confBinningAnalysis, confBinningQa) CASCADE_HIST_MC_MAP(confBinningAnalysis) @@ -494,7 +494,7 @@ class CascadeHistManager mHistogramRegistry->add(mcDir + getHistNameV2(kTruePhiVsPhi, HistTable), getHistDesc(kTruePhiVsPhi, HistTable), getHistType(kTruePhiVsPhi, HistTable), {V0Specs.at(kTruePhiVsPhi)}); // mc origin can be configured here - const framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; + const o2::framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {axisOrigin}); mHistogramRegistry->get(HIST(cascadePrefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kNoMcParticle), modes::mcOriginToString(modes::McOrigin::kNoMcParticle)); mHistogramRegistry->get(HIST(cascadePrefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromWrongCollision), modes::mcOriginToString(modes::McOrigin::kFromWrongCollision)); diff --git a/PWGCF/Femto/Core/closePairRejection.h b/PWGCF/Femto/Core/closePairRejection.h index 90bbf9b7f46..9fa4abf3388 100644 --- a/PWGCF/Femto/Core/closePairRejection.h +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -18,7 +18,6 @@ #include "RecoDecay.h" -#include "PWGCF/Femto/Core/femtoUtils.h" #include "PWGCF/Femto/Core/histManager.h" #include "Framework/Configurable.h" @@ -125,7 +124,7 @@ constexpr std::array, kCprHistogramLast> HistTabl template auto makeCprHistSpecMap(const T& confCpr) { - return std::map>{ + return std::map>{ {kAverage, {confCpr.binningDeta, confCpr.binningDphistar}}, {kRadius0, {confCpr.binningDeta, confCpr.binningDphistar}}, {kRadius1, {confCpr.binningDeta, confCpr.binningDphistar}}, diff --git a/PWGCF/Femto/Core/closeTripletRejection.h b/PWGCF/Femto/Core/closeTripletRejection.h index 9a678032a97..5bb006e04ab 100644 --- a/PWGCF/Femto/Core/closeTripletRejection.h +++ b/PWGCF/Femto/Core/closeTripletRejection.h @@ -41,6 +41,11 @@ constexpr char PrefixTrack1Track2Me[] = "CPR_Track1Track2/ME/"; constexpr char PrefixTrack2Track3Me[] = "CPR_Track2Track3/ME/"; constexpr char PrefixTrack1Track3Me[] = "CPR_Track1Track3/ME/"; +constexpr char PrefixTrack1V0Se[] = "CPR_Track1V0/SE/"; +constexpr char PrefixTrack2V0Se[] = "CPR_Track2V0/SE/"; +constexpr char PrefixTrack1V0Me[] = "CPR_Track1V0/ME/"; +constexpr char PrefixTrack2V0Me[] = "CPR_Track2V0/ME/"; + template @@ -58,40 +63,92 @@ class CloseTripletRejectionTrackTrackTrack int absChargeTrack2, int absChargeTrack3) { - mCtr1.init(registry, specs, confCpr, absChargeTrack1, absChargeTrack2); - mCtr2.init(registry, specs, confCpr, absChargeTrack2, absChargeTrack3); - mCtr3.init(registry, specs, confCpr, absChargeTrack1, absChargeTrack3); + mCtrTrack12.init(registry, specs, confCpr, absChargeTrack1, absChargeTrack2); + mCtrTrack23.init(registry, specs, confCpr, absChargeTrack2, absChargeTrack3); + mCtrTrack13.init(registry, specs, confCpr, absChargeTrack1, absChargeTrack3); + } + + void setMagField(float magField) + { + mCtrTrack12.setMagField(magField); + mCtrTrack23.setMagField(magField); + mCtrTrack13.setMagField(magField); + } + template + void setTriplet(T1 const& track1, T2 const& track2, T3 const& track3, T4 const& trackTable) + { + mCtrTrack12.setPair(track1, track2, trackTable); + mCtrTrack23.setPair(track2, track3, trackTable); + mCtrTrack13.setPair(track1, track3, trackTable); + } + bool isCloseTriplet() const + { + return mCtrTrack12.isClosePair() || mCtrTrack23.isClosePair() || mCtrTrack13.isClosePair(); + } + + void fill(float q3) + { + mCtrTrack12.fill(q3); + mCtrTrack23.fill(q3); + mCtrTrack13.fill(q3); + } + + private: + closepairrejection::ClosePairRejectionTrackTrack mCtrTrack12; + closepairrejection::ClosePairRejectionTrackTrack mCtrTrack23; + closepairrejection::ClosePairRejectionTrackTrack mCtrTrack13; +}; + +template +class CloseTripletRejectionTrackTrackV0 +{ + public: + CloseTripletRejectionTrackTrackV0() = default; + ~CloseTripletRejectionTrackTrackV0() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& specs, + T const& confCpr, + int absChargeTrack1, + int absChargeTrack2) + { + mCtrTrack12.init(registry, specs, confCpr, absChargeTrack1, absChargeTrack2); + mCtrTrack1V0.init(registry, specs, confCpr, absChargeTrack1); + mCtrTrack2V0.init(registry, specs, confCpr, absChargeTrack2); } void setMagField(float magField) { - mCtr1.setMagField(magField); - mCtr2.setMagField(magField); - mCtr3.setMagField(magField); + mCtrTrack12.setMagField(magField); + mCtrTrack1V0.setMagField(magField); + mCtrTrack2V0.setMagField(magField); } template - void setTriplet(T1 const& track1, T2 const& track2, T3 const& track3, T4 const& /*tracks*/) + void setTriplet(T1 const& track1, T2 const& track2, T3 const& v0, T4 const& trackTable) { - mCtr1.compute(track1, track2); - mCtr2.compute(track2, track3); - mCtr3.compute(track1, track3); + mCtrTrack12.setPair(track1, track2, trackTable); + mCtrTrack1V0.setPair(track1, v0, trackTable); + mCtrTrack2V0.setPair(track2, v0, trackTable); } bool isCloseTriplet() const { - return mCtr1.isClosePair() || mCtr2.isClosePair() || mCtr3.isClosePair(); + return mCtrTrack12.isClosePair() || mCtrTrack1V0.isClosePair() || mCtrTrack2V0.isClosePair(); } void fill(float q3) { - mCtr1.fill(q3); - mCtr2.fill(q3); - mCtr3.fill(q3); + mCtrTrack12.fill(q3); + mCtrTrack1V0.fill(q3); + mCtrTrack2V0.fill(q3); } private: - closepairrejection::CloseTrackRejection mCtr1; - closepairrejection::CloseTrackRejection mCtr2; - closepairrejection::CloseTrackRejection mCtr3; + closepairrejection::ClosePairRejectionTrackTrack mCtrTrack12; + closepairrejection::ClosePairRejectionTrackV0 mCtrTrack1V0; + closepairrejection::ClosePairRejectionTrackV0 mCtrTrack2V0; }; }; // namespace closetripletrejection diff --git a/PWGCF/Femto/Core/collisionHistManager.h b/PWGCF/Femto/Core/collisionHistManager.h index 108921ba5be..0fb6fd231b4 100644 --- a/PWGCF/Femto/Core/collisionHistManager.h +++ b/PWGCF/Femto/Core/collisionHistManager.h @@ -109,14 +109,14 @@ constexpr std::array, kColHistLast> HistTable = { template auto makeColHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ COL_HIST_ANALYSIS_MAP(confBinningAnalysis)}; } template auto makeColMcHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ COL_HIST_ANALYSIS_MAP(confBinningAnalysis) COL_HIST_MC_MAP(confBinningAnalysis)}; } @@ -124,7 +124,7 @@ auto makeColMcHistSpecMap(const T& confBinningAnalysis) template auto makeColQaHistSpecMap(const T1& confBinningAnalysis, const T2& confBinningQa) { - return std::map>{ + return std::map>{ COL_HIST_ANALYSIS_MAP(confBinningAnalysis) COL_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; } @@ -132,7 +132,7 @@ auto makeColQaHistSpecMap(const T1& confBinningAnalysis, const T2& confBinningQa template auto makeColMcQaHistSpecMap(const T1& confBinningAnalysis, const T2& confBinningQa) { - return std::map>{ + return std::map>{ COL_HIST_ANALYSIS_MAP(confBinningAnalysis) COL_HIST_QA_MAP(confBinningAnalysis, confBinningQa) COL_HIST_MC_MAP(confBinningAnalysis)}; diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index 6a3c00c189a..fd60c9e8072 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -210,30 +210,30 @@ constexpr std::array, kKinkHistLast> HistTable = template auto makeKinkHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ KINK_HIST_ANALYSIS_MAP(confBinningAnalysis)}; } template auto makeKinkMcHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ KINK_HIST_ANALYSIS_MAP(confBinningAnalysis) KINK_HIST_MC_MAP(confBinningAnalysis)}; } template -std::map> makeKinkQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +std::map> makeKinkQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ KINK_HIST_ANALYSIS_MAP(confBinningAnalysis) KINK_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; } template -std::map> makeKinkMcQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +std::map> makeKinkMcQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ KINK_HIST_ANALYSIS_MAP(confBinningAnalysis) KINK_HIST_QA_MAP(confBinningAnalysis, confBinningQa) KINK_HIST_MC_MAP(confBinningAnalysis) @@ -450,7 +450,7 @@ class KinkHistManager mHistogramRegistry->add(mcDir + getHistNameV2(kTruePhi, HistTable), getHistDesc(kTruePhi, HistTable), getHistType(kTruePhi, HistTable), {KinkSpecs.at(kTruePhi)}); // mc origin can be configured here - const framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; + const o2::framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {axisOrigin}); mHistogramRegistry->get(HIST(kinkPrefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kNoMcParticle), modes::mcOriginToString(modes::McOrigin::kNoMcParticle)); mHistogramRegistry->get(HIST(kinkPrefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromWrongCollision), modes::mcOriginToString(modes::McOrigin::kFromWrongCollision)); diff --git a/PWGCF/Femto/Core/pairBuilder.h b/PWGCF/Femto/Core/pairBuilder.h index 06145605685..d7c2dcb4fd3 100644 --- a/PWGCF/Femto/Core/pairBuilder.h +++ b/PWGCF/Femto/Core/pairBuilder.h @@ -76,11 +76,11 @@ class PairTrackTrackBuilder T6 const& confMixing, T7 const& confPairBinning, T8 const& confPairCuts, - std::map> const& colHistSpec, - std::map> const& trackHistSpec1, - std::map> const& trackHistSpec2, - std::map> const& pairHistSpec, - std::map> const& cprHistSpec) + std::map> const& colHistSpec, + std::map> const& trackHistSpec1, + std::map> const& trackHistSpec2, + std::map> const& pairHistSpec, + std::map> const& cprHistSpec) { // check if correlate the same tracks or not @@ -328,14 +328,14 @@ class PairV0V0Builder T7 const& confMixing, T8 const& confPairBinning, T9 const& confPairCuts, - std::map> const& colHistSpec, - std::map> const& V0HistSpec1, - std::map> const& V0HistSpec2, - std::map> const& PosDauHistSpec, - std::map> const& NegDauHistSpec, - std::map> const& pairHistSpec, - std::map> const& cprHistSpecPos, - std::map> const& cprHistSpecNeg) + std::map> const& colHistSpec, + std::map> const& V0HistSpec1, + std::map> const& V0HistSpec2, + std::map> const& PosDauHistSpec, + std::map> const& NegDauHistSpec, + std::map> const& pairHistSpec, + std::map> const& cprHistSpecPos, + std::map> const& cprHistSpecNeg) { // check if correlate the same tracks or not @@ -389,7 +389,7 @@ class PairV0V0Builder } template - void processSameEvent(T1 const& col, T2& trackTable, T3& /*lambdaTable*/, T4& partition1, T5& partition2, T6& cache) + void processSameEvent(T1 const& col, T2 const& trackTable, T3& /*v0table*/, T4& partition1, T5& partition2, T6& cache) { if (mSameSpecies) { auto v0Slice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); @@ -415,8 +415,36 @@ class PairV0V0Builder } } - template - void processMixedEvent(T1 const& cols, T2& trackTable, T3& partition1, T4& partition2, T5& cache, T6& binsVtxMult, T7& binsVtxCent, T8& binsVtxMultCent) + // mc + template + void processSameEvent(T1 const& col, T2 const& mcCols, T3 const& trackTable, T4 const& /*v0table*/, T5& partition1, T6& partition2, T7 const& mcParticles, T8 const& mcMothers, T9 const& mcPartonicMothers, T10& cache) + { + if (mSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() == 0) { + return; + } + mColHistManager.template fill(col, mcCols); + mCprSe.setMagField(col.magField()); + pairprocesshelpers::PairOrder pairOrder = pairprocesshelpers::kOrder12; + if (mMixIdenticalParticles) { + pairOrder = static_cast(mDist(mRng)); + } + pairprocesshelpers::processSameEvent(trackSlice1, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mV0HistManager1, mPairHistManagerSe, mV0Cleaner1, mCprSe, mPc, pairOrder); + } else { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() == 0 || trackSlice2.size() == 0) { + return; + } + mColHistManager.template fill(col, mcCols); + mCprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice1, trackSlice2, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mV0HistManager1, mV0HistManager2, mPairHistManagerSe, mV0Cleaner1, mV0Cleaner2, mCprSe, mPc); + } + } + + template + void processMixedEvent(T1 const& cols, T2 const& trackTable, T3 const& /*v0table*/, T4& partition1, T5& partition2, T6& cache, T7& binsVtxMult, T8& binsVtxCent, T9& binsVtxMultCent) { if (mSameSpecies) { @@ -450,6 +478,40 @@ class PairV0V0Builder } } + template + void processMixedEvent(T1 const& cols, T2 const& mcCols, T3& trackTable, T4& partition1, T5& partition2, T6 const& mcParticles, T7 const& mcMothers, T8 const& mcPartonicMothers, T9& cache, T10& binsVtxMult, T11& binsVtxCent, T12& binsVtxMultCent) + { + if (mSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mV0Cleaner1, mV0Cleaner1, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mV0Cleaner1, mV0Cleaner1, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mV0Cleaner1, mV0Cleaner1, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mV0Cleaner1, mV0Cleaner2, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mV0Cleaner1, mV0Cleaner2, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mV0Cleaner1, mV0Cleaner2, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + private: colhistmanager::CollisionHistManager mColHistManager; v0histmanager::V0HistManager mV0HistManager1; @@ -509,13 +571,13 @@ class PairTrackV0Builder T6 const& confMixing, T7 const& confPairBinning, T8 const& confPairCuts, - std::map>& colHistSpec, - std::map>& trackHistSpec, - std::map>& v0HistSpec, - std::map>& posDauHistSpec, - std::map>& negDauHistSpec, - std::map>& pairHistSpec, - std::map>& cprHistSpec) + std::map>& colHistSpec, + std::map>& trackHistSpec, + std::map>& v0HistSpec, + std::map>& posDauHistSpec, + std::map>& negDauHistSpec, + std::map>& pairHistSpec, + std::map>& cprHistSpec) { mColHistManager.template init(registry, colHistSpec); @@ -654,13 +716,13 @@ class PairTrackTwoTrackResonanceBuilder T4 const& confMixing, T5 const& confPairBinning, T6 const& confPairCuts, - std::map> const& colHistSpec, - std::map> const& trackHistSpec, - std::map> const& resonanceHistSpec, - std::map> const& posDauHistSpec, - std::map> const& negDauHistSpec, - std::map> const& pairHistSpec, - std::map> const& cprHistSpec) + std::map> const& colHistSpec, + std::map> const& trackHistSpec, + std::map> const& resonanceHistSpec, + std::map> const& posDauHistSpec, + std::map> const& negDauHistSpec, + std::map> const& pairHistSpec, + std::map> const& cprHistSpec) { mColHistManager.template init(registry, colHistSpec); @@ -764,12 +826,12 @@ class PairTrackKinkBuilder T6 const& confMixing, T7 const& confPairBinning, T8 const& confPairCuts, - std::map> const& colHistSpec, - std::map> const& trackHistSpec, - std::map> const& kinkHistSpec, - std::map> const& chaDauHistSpec, - std::map> const& pairHistSpec, - std::map> const& cprHistSpec) + std::map> const& colHistSpec, + std::map> const& trackHistSpec, + std::map> const& kinkHistSpec, + std::map> const& chaDauHistSpec, + std::map> const& pairHistSpec, + std::map> const& cprHistSpec) { mColHistManager.template init(registry, colHistSpec); @@ -919,15 +981,15 @@ class PairTrackCascadeBuilder T7 const& confMixing, T8 const& confPairBinning, T9 const& confPairCuts, - std::map> const& colHistSpec, - std::map> const& trackHistSpec, - std::map> const& cascadeHistSpec, - std::map> const& bachelorHistSpec, - std::map> const& posDauHistSpec, - std::map> const& negDauHistSpec, - std::map> const& pairHistSpec, - std::map> const& cprHistSpecBachelor, - std::map> const& cprHistSpecV0Daughter) + std::map> const& colHistSpec, + std::map> const& trackHistSpec, + std::map> const& cascadeHistSpec, + std::map> const& bachelorHistSpec, + std::map> const& posDauHistSpec, + std::map> const& negDauHistSpec, + std::map> const& pairHistSpec, + std::map> const& cprHistSpecBachelor, + std::map> const& cprHistSpecV0Daughter) { mColHistManager.template init(registry, colHistSpec); @@ -965,6 +1027,19 @@ class PairTrackCascadeBuilder pairprocesshelpers::processSameEvent(trackSlice, v0Slice, trackTable, col, mTrackHistManager, mCascadeHistManager, mPairHistManagerSe, mCprSe, mPc); } + template + void processSameEvent(T1 const& col, T2 const& mcCols, T3 const& trackTable, T4& trackPartition, T5 const& /*cascadeTabel*/, T6& cascadePartition, T7 const& mcParticles, T8 const& mcMothers, T9 const& mcPartonicMothers, T10& cache) + { + auto trackSlice = trackPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto cascadeSlice = cascadePartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice.size() == 0 || cascadeSlice.size() == 0) { + return; + } + mColHistManager.template fill(col, mcCols); + mCprSe.setMagField(col.magField()); + pairprocesshelpers::processSameEvent(trackSlice, cascadeSlice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager, mCascadeHistManager, mPairHistManagerSe, mTrackCleaner, mCascadeCleaner, mCprSe, mPc); + } + template void processMixedEvent(T1 const& cols, T2& trackTable, T3& trackPartition, T4& v0Partition, T5& cache, T6& binsVtxMult, T7& binsVtxCent, T8& binsVtxMultCent) { @@ -983,6 +1058,24 @@ class PairTrackCascadeBuilder } } + template + void processMixedEvent(T1 const& cols, T2 const& mcCols, T3& trackTable, T4& trackPartition, T5& cascadePartition, T6 const& mcParticles, T7 const& mcMothers, T8 const& mcPartonicMothers, T9& cache, T10& binsVtxMult, T11& binsVtxCent, T12& binsVtxMultCent) + { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, mcCols, trackPartition, cascadePartition, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mTrackCleaner, mCascadeCleaner, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, mcCols, trackPartition, cascadePartition, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mTrackCleaner, mCascadeCleaner, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, mcCols, trackPartition, cascadePartition, trackTable, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mTrackCleaner, mCascadeCleaner, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + private: colhistmanager::CollisionHistManager mColHistManager; trackhistmanager::TrackHistManager mTrackHistManager; diff --git a/PWGCF/Femto/Core/pairCleaner.h b/PWGCF/Femto/Core/pairCleaner.h index ee1c1af92d1..506a9dbc9a4 100644 --- a/PWGCF/Femto/Core/pairCleaner.h +++ b/PWGCF/Femto/Core/pairCleaner.h @@ -94,9 +94,9 @@ class TrackTrackPairCleaner : public BasePairCleaner } template - bool isCleanPair(T1 const& track1, T2 const& track2, T3 const& /*trackTable*/, T4 const& partonicMothers) const + bool isCleanPair(T1 const& track1, T2 const& track2, T3 const& trackTable, T4 const& partonicMothers) const { - if (!this->isCleanTrackPair(track1, track2)) { + if (!this->isCleanPair(track1, track2, trackTable)) { return false; } // pair is clean @@ -124,6 +124,23 @@ class V0V0PairCleaner : public BasePairCleaner auto negDaughter2 = trackTable.rawIteratorAt(v02.negDauId() - trackTable.offset()); return this->isCleanTrackPair(posDaughter1, posDaughter2) && this->isCleanTrackPair(negDaughter1, negDaughter2); } + + template + bool isCleanPair(T1 const& v01, T2 const& v02, T3 const& trackTable, T4 const& partonicMothers) const + { + if (!this->isCleanPair(v01, v02, trackTable)) { + return false; + } + // pair is clean + // no check if we require common or non-common ancestry + if (mMixPairsWithCommonAncestor) { + return this->pairHasCommonAncestor(v01, v02, partonicMothers); + } + if (mMixPairsWithNonCommonAncestor) { + return this->pairHasNonCommonAncestor(v01, v02, partonicMothers); + } + return true; + } }; class TrackV0PairCleaner : public BasePairCleaner // also works for particles decaying into a positive and negative daughter, like resonances @@ -197,6 +214,23 @@ class TrackCascadePairCleaner : public BasePairCleaner auto negDaughter = trackTable.rawIteratorAt(cascade.negDauId() - trackTable.offset()); return (this->isCleanTrackPair(bachelor, track) && this->isCleanTrackPair(posDaughter, track) && this->isCleanTrackPair(negDaughter, track)); } + + template + bool isCleanPair(T1 const& track1, T2 const& cascade, T3 const& trackTable, T4 const& partonicMothers) const + { + if (!this->isCleanPair(track1, cascade, trackTable)) { + return false; + } + // pair is clean + // now check if we require common or non-common ancestry + if (mMixPairsWithCommonAncestor) { + return this->pairHasCommonAncestor(track1, cascade, partonicMothers); + } + if (mMixPairsWithNonCommonAncestor) { + return this->pairHasNonCommonAncestor(track1, cascade, partonicMothers); + } + return true; + } }; } // namespace paircleaner } // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h index f27785cac62..487f5f03711 100644 --- a/PWGCF/Femto/Core/pairHistManager.h +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -213,14 +213,14 @@ constexpr std::array, kPairHistogramLast> template auto makePairHistSpecMap(const T& confPairBinning) { - return std::map>{ + return std::map>{ PAIR_HIST_ANALYSIS_MAP(confPairBinning)}; }; template auto makePairMcHistSpecMap(const T& confPairBinning) { - return std::map>{ + return std::map>{ PAIR_HIST_ANALYSIS_MAP(confPairBinning) PAIR_HIST_MC_MAP(confPairBinning)}; }; diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index d399729d66b..d14bbf76196 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -17,126 +17,126 @@ #define PWGCF_FEMTO_CORE_PARTITIONS_H_ // collsion selection -#define MAKE_COLLISION_FILTER(selection) \ - (femtocollisions::posZ >= selection.vtxZMin && femtocollisions::posZ <= selection.vtxZMax) && \ - (femtocollisions::mult >= selection.multMin && femtocollisions::mult <= selection.multMax) && \ - (femtocollisions::cent >= selection.centMin && femtocollisions::cent <= selection.centMax) && \ - (femtocollisions::magField >= static_cast(selection.magFieldMin) && femtocollisions::magField <= static_cast(selection.magFieldMax)) && \ - ncheckbit(femtocollisions::mask, selection.collisionMask) +#define MAKE_COLLISION_FILTER(selection) \ + (o2::aod::femtocollisions::posZ >= selection.vtxZMin && o2::aod::femtocollisions::posZ <= selection.vtxZMax) && \ + (o2::aod::femtocollisions::mult >= selection.multMin && o2::aod::femtocollisions::mult <= selection.multMax) && \ + (o2::aod::femtocollisions::cent >= selection.centMin && o2::aod::femtocollisions::cent <= selection.centMax) && \ + (o2::aod::femtocollisions::magField >= static_cast(selection.magFieldMin) && o2::aod::femtocollisions::magField <= static_cast(selection.magFieldMax)) && \ + ncheckbit(o2::aod::femtocollisions::mask, selection.collisionMask) // standard track partition -#define MAKE_TRACK_PARTITION(selection) \ - ifnode(selection.chargeSign.node() != 0, ifnode(selection.chargeSign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f), true) && \ - (nabs(selection.chargeAbs.node() * femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(selection.chargeAbs.node() * femtobase::stored::signedPt) < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - ifnode(nabs(selection.chargeAbs.node() * femtobase::stored::signedPt) * (nexp(femtobase::stored::eta) + nexp(-1.f * femtobase::stored::eta)) / (2.f) <= selection.pidThres, \ - ncheckbit(femtotracks::mask, selection.maskLowMomentum), \ - ncheckbit(femtotracks::mask, selection.maskHighMomentum)) +#define MAKE_TRACK_PARTITION(selection) \ + ifnode(selection.chargeSign.node() != 0, ifnode(selection.chargeSign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(selection.chargeAbs.node() * o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ + (nabs(selection.chargeAbs.node() * o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + ifnode(nabs(selection.chargeAbs.node() * o2::aod::femtobase::stored::signedPt) * (nexp(o2::aod::femtobase::stored::eta) + nexp(-1.f * o2::aod::femtobase::stored::eta)) / (2.f) <= selection.pidThres, \ + ncheckbit(o2::aod::femtotracks::mask, selection.maskLowMomentum), \ + ncheckbit(o2::aod::femtotracks::mask, selection.maskHighMomentum)) // partition for phis and rhos, i.e. resonance that are their own antiparticle -#define MAKE_RESONANCE_0_PARTITON(selection) \ - (femtobase::stored::pt > selection.ptMin) && \ - (femtobase::stored::pt < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - (femtobase::stored::mass > selection.massMin) && \ - (femtobase::stored::mass < selection.massMax) && \ - ifnode(ncheckbit(femtotwotrackresonances::mask, selection.posDauBitForThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.posDauMaskAboveThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.posDauMaskBelowThres)) && \ - ifnode(ncheckbit(femtotwotrackresonances::mask, selection.negDauBitForThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.negDauMaskAboveThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.negDauMaskBelowThres)) +#define MAKE_RESONANCE_0_PARTITON(selection) \ + (o2::aod::femtobase::stored::pt > selection.ptMin) && \ + (o2::aod::femtobase::stored::pt < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauBitForThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskBelowThres)) && \ + ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauBitForThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskBelowThres)) // partition for kstars, they have distinct antiparticle -#define MAKE_RESONANCE_1_PARTITON(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f), true) && \ - (nabs(femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(femtobase::stored::signedPt) < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - (femtobase::stored::mass > selection.massMin) && \ - (femtobase::stored::mass < selection.massMax) && \ - ifnode(ncheckbit(femtotwotrackresonances::mask, selection.posDauBitForThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.posDauMaskAboveThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.posDauMaskBelowThres)) && \ - ifnode(ncheckbit(femtotwotrackresonances::mask, selection.negDauBitForThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.negDauMaskAboveThres), \ - ncheckbit(femtotwotrackresonances::mask, selection.negDauMaskBelowThres)) +#define MAKE_RESONANCE_1_PARTITON(selection) \ + ifnode(selection.sign.node() != 0, \ + ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauBitForThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.posDauMaskBelowThres)) && \ + ifnode(ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauBitForThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::mask, selection.negDauMaskBelowThres)) // partition for lambdas -#define MAKE_LAMBDA_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f), true) && \ - (nabs(femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(femtobase::stored::signedPt) < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - (femtobase::stored::mass > selection.massMin) && \ - (femtobase::stored::mass < selection.massMax) && \ - ncheckbit(femtov0s::mask, selection.mask) +#define MAKE_LAMBDA_PARTITION(selection) \ + ifnode(selection.sign.node() != 0, \ + ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ncheckbit(o2::aod::femtov0s::mask, selection.mask) // partition for k0shorts // need special partition since k0shorts have no antiparticle -#define MAKE_K0SHORT_PARTITION(selection) \ - (femtobase::stored::pt > selection.ptMin) && \ - (femtobase::stored::pt < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - (femtobase::stored::mass > selection.massMin) && \ - (femtobase::stored::mass < selection.massMax) && \ - ncheckbit(femtov0s::mask, selection.mask) +#define MAKE_K0SHORT_PARTITION(selection) \ + (o2::aod::femtobase::stored::pt > selection.ptMin) && \ + (o2::aod::femtobase::stored::pt < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ncheckbit(o2::aod::femtov0s::mask, selection.mask) -#define MAKE_CASCADE_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f), true) && \ - (nabs(femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(femtobase::stored::signedPt) < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - (femtobase::stored::mass > selection.massMin) && \ - (femtobase::stored::mass < selection.massMax) && \ - ncheckbit(femtocascades::mask, selection.mask) +#define MAKE_CASCADE_PARTITION(selection) \ + ifnode(selection.sign.node() != 0, \ + ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ncheckbit(o2::aod::femtocascades::mask, selection.mask) -#define MAKE_SIGMA_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f), true) && \ - (nabs(femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(femtobase::stored::signedPt) < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - (femtobase::stored::mass > selection.massMin) && \ - (femtobase::stored::mass < selection.massMax) && \ - ncheckbit(femtokinks::mask, selection.mask) +#define MAKE_SIGMA_PARTITION(selection) \ + ifnode(selection.sign.node() != 0, \ + ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ncheckbit(o2::aod::femtokinks::mask, selection.mask) -#define MAKE_SIGMAPLUS_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, femtobase::stored::signedPt > 0.f, femtobase::stored::signedPt < 0.f), true) && \ - (nabs(femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(femtobase::stored::signedPt) < selection.ptMax) && \ - (femtobase::stored::eta > selection.etaMin) && \ - (femtobase::stored::eta < selection.etaMax) && \ - (femtobase::stored::phi > selection.phiMin) && \ - (femtobase::stored::phi < selection.phiMax) && \ - (femtobase::stored::mass > selection.massMin) && \ - (femtobase::stored::mass < selection.massMax) && \ - ncheckbit(femtokinks::mask, selection.mask) +#define MAKE_SIGMAPLUS_PARTITION(selection) \ + ifnode(selection.sign.node() != 0, \ + ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ + (o2::aod::femtobase::stored::eta > selection.etaMin) && \ + (o2::aod::femtobase::stored::eta < selection.etaMax) && \ + (o2::aod::femtobase::stored::phi > selection.phiMin) && \ + (o2::aod::femtobase::stored::phi < selection.phiMax) && \ + (o2::aod::femtobase::stored::mass > selection.massMin) && \ + (o2::aod::femtobase::stored::mass < selection.massMax) && \ + ncheckbit(o2::aod::femtokinks::mask, selection.mask) #endif // PWGCF_FEMTO_CORE_PARTITIONS_H_ diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index be9830dc8f9..c9d736315ec 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -441,14 +441,14 @@ constexpr std::array, kTrackHistLast> template auto makeTrackHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ TRACK_HIST_ANALYSIS_MAP(confBinningAnalysis)}; } template auto makeTrackMcHistSpecMap(T const& confBinningAnalysis) { - return std::map>{ + return std::map>{ TRACK_HIST_ANALYSIS_MAP(confBinningAnalysis) TRACK_HIST_MC_MAP(confBinningAnalysis)}; }; @@ -456,7 +456,7 @@ auto makeTrackMcHistSpecMap(T const& confBinningAnalysis) template auto makeTrackQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ TRACK_HIST_ANALYSIS_MAP(confBinningAnalysis) TRACK_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; } @@ -464,7 +464,7 @@ auto makeTrackQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinning template auto makeTrackMcQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ TRACK_HIST_ANALYSIS_MAP(confBinningAnalysis) TRACK_HIST_QA_MAP(confBinningAnalysis, confBinningQa) TRACK_HIST_MC_MAP(confBinningAnalysis) @@ -744,7 +744,7 @@ class TrackHistManager mHistogramRegistry->add(mcDir + getHistNameV2(kTruePhiVsPhi, HistTable), getHistDesc(kTruePhiVsPhi, HistTable), getHistType(kTruePhiVsPhi, HistTable), {Specs.at(kTruePhiVsPhi)}); // mc origin can be configured here - const framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; + const o2::framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {axisOrigin}); mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kNoMcParticle), modes::mcOriginToString(modes::McOrigin::kNoMcParticle)); mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromWrongCollision), modes::mcOriginToString(modes::McOrigin::kFromWrongCollision)); diff --git a/PWGCF/Femto/Core/tripletBuilder.h b/PWGCF/Femto/Core/tripletBuilder.h index 1487d3766c1..f87472607ee 100644 --- a/PWGCF/Femto/Core/tripletBuilder.h +++ b/PWGCF/Femto/Core/tripletBuilder.h @@ -80,12 +80,12 @@ class TripletTrackTrackTrackBuilder T5 const& confMixing, T6 const& confTripletBinning, T7 const& confTripletCuts, - std::map> const& colHistSpec, - std::map> const& trackHistSpec1, - std::map> const& trackHistSpec2, - std::map> const& trackHistSpec3, - std::map> const& pairHistSpec, - std::map> const& cprHistSpec) + std::map> const& colHistSpec, + std::map> const& trackHistSpec1, + std::map> const& trackHistSpec2, + std::map> const& trackHistSpec3, + std::map> const& pairHistSpec, + std::map> const& cprHistSpec) { // check if correlate the same tracks or not mTrack1Track2Track3AreSameSpecies = confMixing.particle123AreSameSpecies.value; @@ -128,7 +128,7 @@ class TripletTrackTrackTrackBuilder // all three tracks are different mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); - mTrackHistManager3.template init(registry, trackHistSpec3, confTrackSelection2); + mTrackHistManager3.template init(registry, trackHistSpec3, confTrackSelection3); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confTrackSelection3.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, confTrackSelection3.chargeAbs.value); @@ -360,6 +360,260 @@ class TripletTrackTrackTrackBuilder std::uniform_int_distribution<> mDist; }; +template +class TripletTrackTrackV0Builder +{ + public: + TripletTrackTrackV0Builder() = default; + ~TripletTrackTrackV0Builder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + T1 const& confTrackSelection1, + T2 const& confTrackSelection2, + T3 const& confV0Selection, + T4 const& confCtr, + T5 const& confMixing, + T6 const& confTripletBinning, + T7 const& confTripletCuts, + std::map> const& colHistSpec, + std::map> const& trackHistSpec1, + std::map> const& trackHistSpec2, + std::map> const& v0histSpec, + std::map> const& posDauhistSpec, + std::map> const& negDauhistSpec, + std::map> const& tripletHistSpec, + std::map> const& ctrHistSpec) + { + // check if correlate the same tracks or not + mTrack1Track2AreSameSpecies = confMixing.particle12AreSameSpecies.value; + + mColHistManager.template init(registry, colHistSpec); + mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); + mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); + + mTc.template init(confTripletCuts); + + if (mTrack1Track2AreSameSpecies) { + // Track1 & Track2 & are the same particle species and track 3 is something else + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mV0HistManager.template init(registry, v0histSpec, confV0Selection, posDauhistSpec, negDauhistSpec); + + mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confV0Selection.pdgCodeAbs.value); + mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); + mCtrSe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); + + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confV0Selection.pdgCodeAbs.value); + mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); + mCtrMe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); + } else { + // all three tracks are different + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); + mV0HistManager.template init(registry, v0histSpec, confV0Selection, posDauhistSpec, negDauhistSpec); + + mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confV0Selection.pdgCodeAbs.value); + mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); + mCtrSe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); + + mTripletHistManagerMe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confV0Selection.pdgCodeAbs.value); + mTripletHistManagerMe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); + mCtrMe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value); + } + + // setup mixing + mMixingPolicy = static_cast(confMixing.policy.value); + mMixingDepth = confMixing.depth.value; + + // setup rng if necessary + if (confMixing.seed.value >= 0) { + uint64_t randomSeed = 0; + mMixIdenticalParticles = true; + if (confMixing.seed.value == 0) { + randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } else { + randomSeed = static_cast(confMixing.seed.value); + } + mRng = std::mt19937(randomSeed); + mDist = std::uniform_int_distribution<>(tripletprocesshelpers::kOrder123, tripletprocesshelpers::kOrder213); + } + } + + // data + template + void processSameEvent(T1 const& col, T2& trackTable, T3& partition1, T4& partition2, T5& partition3, T6& cache) + { + tripletprocesshelpers::TripletOrder tripletOrder = tripletprocesshelpers::kOrder123; + if (mTrack1Track2AreSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto v0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() == 0 || v0Slice.size() == 0) { + return; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + if (mMixIdenticalParticles) { + tripletOrder = static_cast(mDist(mRng)); + } + tripletprocesshelpers::processSameEvent(trackSlice1, v0Slice, trackTable, col, mTrackHistManager1, mV0HistManager, mTripletHistManagerSe, mCtrSe, mTc, tripletOrder); + } else { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto v0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() == 0 || trackSlice2.size() == 0 || v0Slice.size() == 0) { + return; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, v0Slice, trackTable, col, mTrackHistManager1, mTrackHistManager2, mV0HistManager, mTripletHistManagerSe, mCtrSe, mTc); + } + } + + // mc + template + void processSameEvent(T1 const& col, T2 const& mcCols, T3& trackTable, T4& partition1, T5& partition2, T6& partition3, T7 const& mcParticles, T8 const& mcMothers, T9 const& mcPartonicMothers, T10& cache) + { + tripletprocesshelpers::TripletOrder tripletOrder = tripletprocesshelpers::kOrder123; + if (mTrack1Track2AreSameSpecies) { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto v0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() == 0 || v0Slice.size() == 0) { + return; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + if (mMixIdenticalParticles) { + tripletOrder = static_cast(mDist(mRng)); + } + tripletprocesshelpers::processSameEvent(trackSlice1, v0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mV0HistManager, mTripletHistManagerSe, mCtrSe, mTc, tripletOrder); + } else { + auto trackSlice1 = partition1->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice2 = partition2->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + auto v0Slice = partition3->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); + if (trackSlice1.size() == 0 || trackSlice2.size() == 0 || v0Slice.size() == 0) { + return; + } + mColHistManager.template fill(col); + mCtrSe.setMagField(col.magField()); + tripletprocesshelpers::processSameEvent(trackSlice1, trackSlice2, v0Slice, trackTable, mcParticles, mcMothers, mcPartonicMothers, col, mcCols, mTrackHistManager1, mTrackHistManager2, mV0HistManager, mTripletHistManagerSe, mCtrSe, mTc); + } + } + + template + void processMixedEvent(T1 const& cols, T2& trackTable, T3& partition1, T4& partition2, T5& partition3, T6& cache, T7& binsVtxMult, T8& binsVtxCent, T9& binsVtxMultCent) + { + if (mTrack1Track2AreSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + + template + void processMixedEvent(T1 const& cols, T2 const& mcCols, T3& trackTable, T4& partition1, T5& partition2, T6& partition3, T7 const& mcParticles, T8& cache, T9& binsVtxMult, T10& binsVtxCent, T11& binsVtxMultCent) + { + if (mTrack1Track2AreSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxMult, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + + private: + colhistmanager::CollisionHistManager mColHistManager; + trackhistmanager::TrackHistManager mTrackHistManager1; + trackhistmanager::TrackHistManager mTrackHistManager2; + v0histmanager::V0HistManager mV0HistManager; + triplethistmanager::TripletHistManager mTripletHistManagerSe; + triplethistmanager::TripletHistManager mTripletHistManagerMe; + + closetripletrejection::CloseTripletRejectionTrackTrackV0 mCtrSe; + closetripletrejection::CloseTripletRejectionTrackTrackV0 mCtrMe; + tripletcleaner::TrackTrackV0TripletCleaner mTc; + triplethistmanager::MixingPolicy mMixingPolicy = triplethistmanager::MixingPolicy::kVtxMult; + bool mTrack1Track2AreSameSpecies = false; + int mMixingDepth = 5; + bool mMixIdenticalParticles = false; + std::mt19937 mRng; + std::uniform_int_distribution<> mDist; +}; + } // namespace tripletbuilder } // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/tripletCleaner.h b/PWGCF/Femto/Core/tripletCleaner.h index cf7345547a6..690c9d526b7 100644 --- a/PWGCF/Femto/Core/tripletCleaner.h +++ b/PWGCF/Femto/Core/tripletCleaner.h @@ -59,6 +59,46 @@ class TrackTrackTrackTripletCleaner : public paircleaner::BasePairCleaner } }; +class TrackTrackV0TripletCleaner : public paircleaner::BasePairCleaner +{ + public: + TrackTrackV0TripletCleaner() = default; + ~TrackTrackV0TripletCleaner() = default; + + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& v0, T4 const& trackTable) const + { + auto posDaughter = trackTable.rawIteratorAt(v0.posDauId() - trackTable.offset()); + auto negDaughter = trackTable.rawIteratorAt(v0.negDauId() - trackTable.offset()); + return this->isCleanTrackPair(track1, track2) && + this->isCleanTrackPair(track1, posDaughter) && + this->isCleanTrackPair(track1, negDaughter) && + this->isCleanTrackPair(track2, posDaughter) && + this->isCleanTrackPair(track2, negDaughter); + } + + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& v0, T4 const& trackTable, T5 const& partonicMothers) const + { + if (!this->isCleanTriplet(track1, track2, v0, trackTable)) { + return false; + } + // pair is clean + // no check if we require common or non-common ancestry + if (mMixPairsWithCommonAncestor) { + return this->pairHasCommonAncestor(track1, track2, partonicMothers) && + this->pairHasCommonAncestor(track1, v0, partonicMothers) && + this->pairHasCommonAncestor(track2, v0, partonicMothers); + } + if (mMixPairsWithNonCommonAncestor) { + return this->pairHasNonCommonAncestor(track1, track2, partonicMothers) && + this->pairHasNonCommonAncestor(track1, v0, partonicMothers) && + this->pairHasNonCommonAncestor(track2, v0, partonicMothers); + } + return true; + } +}; + } // namespace tripletcleaner } // namespace o2::analysis::femto diff --git a/PWGCF/Femto/Core/tripletHistManager.h b/PWGCF/Femto/Core/tripletHistManager.h index 3ad3062c294..2f5976d6979 100644 --- a/PWGCF/Femto/Core/tripletHistManager.h +++ b/PWGCF/Femto/Core/tripletHistManager.h @@ -177,14 +177,14 @@ constexpr std::array, kTripletHistogramLast> template auto makeTripletHistSpecMap(const T& confPairBinning) { - return std::map>{ + return std::map>{ TRIPLET_HIST_ANALYSIS_MAP(confPairBinning)}; }; template auto makeTripletMcHistSpecMap(const T& confPairBinning) { - return std::map>{ + return std::map>{ TRIPLET_HIST_ANALYSIS_MAP(confPairBinning) TRIPLET_HIST_MC_MAP(confPairBinning)}; }; @@ -195,6 +195,9 @@ auto makeTripletMcHistSpecMap(const T& confPairBinning) constexpr char PrefixTrackTrackTrackSe[] = "TrackTrackTrack/SE/"; constexpr char PrefixTrackTrackTrackMe[] = "TrackTrackTrack/ME/"; +constexpr char PrefixTrackTrackLambdaSe[] = "TrackTrackLambda/SE/"; +constexpr char PrefixTrackTrackLambdaMe[] = "TrackTrackLambda/ME/"; + constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view QaDir = "QA/"; constexpr std::string_view McDir = "MC/"; @@ -282,7 +285,7 @@ class TripletHistManager mMass2 = particle2.mass(); } if constexpr (modes::hasMass(particleType3)) { - mMass3 = particle2.mass(); + mMass3 = particle3.mass(); } } diff --git a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h index 848dd69f521..da3be07d282 100644 --- a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h +++ b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h @@ -86,9 +86,9 @@ constexpr std::array, kTwoTrackReso {kPtVsMass, o2::framework::kTH2F, "hPtVsMass", "p_{T} vs invariant mass; p_{T} (GeV/#it{c}); m (GeV/#it{c}^{2})"}}}; template -std::map> makeTwoTrackResonanceHistSpecMap(const T& confBinningAnalysis) +std::map> makeTwoTrackResonanceHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ {kPt, {confBinningAnalysis.pt}}, {kEta, {confBinningAnalysis.eta}}, {kPhi, {confBinningAnalysis.phi}}, @@ -99,7 +99,7 @@ std::map> makeTwoTrackRe template auto makeTwoTrackResonanceQaHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ {kPt, {confBinningAnalysis.pt}}, {kEta, {confBinningAnalysis.eta}}, {kPhi, {confBinningAnalysis.phi}}, diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index bdfa0cc9aaa..579b28470df 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -232,30 +232,30 @@ constexpr std::array, kV0HistLast> HistTable = { template auto makeV0HistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ V0_HIST_ANALYSIS_MAP(confBinningAnalysis)}; } template auto makeV0McHistSpecMap(const T& confBinningAnalysis) { - return std::map>{ + return std::map>{ V0_HIST_ANALYSIS_MAP(confBinningAnalysis) V0_HIST_MC_MAP(confBinningAnalysis)}; } template -std::map> makeV0QaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +std::map> makeV0QaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ V0_HIST_ANALYSIS_MAP(confBinningAnalysis) V0_HIST_QA_MAP(confBinningAnalysis, confBinningQa)}; } template -std::map> makeV0McQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) +std::map> makeV0McQaHistSpecMap(T1 const& confBinningAnalysis, T2 const& confBinningQa) { - return std::map>{ + return std::map>{ V0_HIST_ANALYSIS_MAP(confBinningAnalysis) V0_HIST_QA_MAP(confBinningAnalysis, confBinningQa) V0_HIST_MC_MAP(confBinningAnalysis) @@ -486,7 +486,7 @@ class V0HistManager mHistogramRegistry->add(mcDir + getHistNameV2(kTruePhiVsPhi, HistTable), getHistDesc(kTruePhiVsPhi, HistTable), getHistType(kTruePhiVsPhi, HistTable), {V0Specs.at(kTruePhiVsPhi)}); // mc origin can be configured here - const framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; + const o2::framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {axisOrigin}); mHistogramRegistry->get(HIST(v0Prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kNoMcParticle), modes::mcOriginToString(modes::McOrigin::kNoMcParticle)); mHistogramRegistry->get(HIST(v0Prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromWrongCollision), modes::mcOriginToString(modes::McOrigin::kFromWrongCollision)); diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index 4aa617a692a..21bafe06033 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -46,38 +46,33 @@ #include #include -#include -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; namespace o2::analysis::femto { namespace consumeddata { -using Run3PpCollisions = soa::Join; -using Run3PpMcRecoCollisions = soa::Join; -using Run3PpMcGenCollisions = soa::Join; +using Run3PpCollisions = o2::soa::Join; +using Run3PpMcRecoCollisions = o2::soa::Join; +using Run3PpMcGenCollisions = o2::soa::Join; using Run3FullPidTracks = - soa::Join; -using Run3McRecoTracks = soa::Join; + soa::Join; +using Run3McRecoTracks = soa::Join; -using Run3Vzeros = aod::V0Datas; -using Run3RecoVzeros = soa::Join; +using Run3Vzeros = o2::aod::V0Datas; +using Run3RecoVzeros = o2::soa::Join; -using Run3Cascades = CascDatas; -using Run3RecoCascades = soa::Join; +using Run3Cascades = o2::aod::CascDatas; +using Run3RecoCascades = o2::soa::Join; -using Run3Kinks = KinkCands; +using Run3Kinks = o2::aod::KinkCands; -using Run3McGenParticles = aod::McParticles; +using Run3McGenParticles = o2::aod::McParticles; } // namespace consumeddata } // namespace o2::analysis::femto @@ -138,12 +133,12 @@ struct FemtoProducer { // histogramming // add histograms in next iteration - HistogramRegistry hRegistry{"FemtoProducer", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoProducer", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; // data members - Service ccdb; /// Accessing the CCDB + o2::framework::Service ccdb; /// Accessing the CCDB - void init(InitContext& context) + void init(o2::framework::InitContext& context) { if ((xiBuilder.fillAnyTable() || omegaBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { LOG(fatal) << "At least one cascade table is enabled, but wrong process function is enabled. Breaking..."; @@ -281,29 +276,29 @@ struct FemtoProducer { // proccess functions void processTracksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); } PROCESS_SWITCH(FemtoProducer, processTracksRun3pp, "Process tracks", true); // process tracks and v0s void processTracksV0sRun3pp(consumeddata::Run3PpCollisions::iterator const& col, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, consumeddata::Run3Vzeros const& v0s) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processV0s(col, tracks, tracksWithItsPid, v0s); }; @@ -311,15 +306,15 @@ struct FemtoProducer { // process tracks and kinks void processTracksKinksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, consumeddata::Run3Kinks const& kinks) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processKinks(col, tracks, tracksWithItsPid, kinks); } @@ -327,7 +322,7 @@ struct FemtoProducer { // process tracks, v0s and cascades void processTracksV0sCascadesRun3pp(consumeddata::Run3PpCollisions::iterator const& col, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, consumeddata::Run3Vzeros const& v0s, consumeddata::Run3Cascades const& cascades) @@ -335,8 +330,8 @@ struct FemtoProducer { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processV0s(col, tracks, tracksWithItsPid, v0s); processCascades(col, tracks, tracksWithItsPid, cascades); @@ -345,7 +340,7 @@ struct FemtoProducer { // process tracks, v0s, cascades and kinks void processTracksV0sCascadesKinksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3FullPidTracks const& tracks, consumeddata::Run3Vzeros const& v0s, consumeddata::Run3Cascades const& cascades, @@ -354,8 +349,8 @@ struct FemtoProducer { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processV0s(col, tracks, tracksWithItsPid, v0s); processKinks(col, tracks, tracksWithItsPid, kinks); @@ -366,15 +361,15 @@ struct FemtoProducer { // process monte carlo tracks void processTracksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, consumeddata::Run3PpMcGenCollisions const& mcCols, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3McRecoTracks const& tracks, consumeddata::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); } PROCESS_SWITCH(FemtoProducer, processTracksRun3ppMc, "Provide reconstructed and generated Tracks", false); @@ -382,7 +377,7 @@ struct FemtoProducer { // process monte carlo tracks and v0s void processTracksV0sRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, consumeddata::Run3PpMcGenCollisions const& mcCols, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3McRecoTracks const& tracks, consumeddata::Run3RecoVzeros const& v0s, consumeddata::Run3McGenParticles const& mcParticles) @@ -390,8 +385,8 @@ struct FemtoProducer { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); } @@ -400,7 +395,7 @@ struct FemtoProducer { // process monte carlo tracks and kinks void processTracksKinksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, consumeddata::Run3PpMcGenCollisions const& mcCols, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3McRecoTracks const& tracks, consumeddata::Run3Kinks const& kinks, consumeddata::Run3McGenParticles const& mcParticles) @@ -408,8 +403,8 @@ struct FemtoProducer { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcKinks(col, mcCols, tracks, tracksWithItsPid, kinks, mcParticles); } @@ -418,7 +413,7 @@ struct FemtoProducer { // process monte carlo tracks and v0s and kinks (adding cascades later here) void processTracksV0sKinksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, consumeddata::Run3PpMcGenCollisions const& mcCols, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3McRecoTracks const& tracks, consumeddata::Run3RecoVzeros const& v0s, consumeddata::Run3Kinks const& kinks, @@ -427,8 +422,8 @@ struct FemtoProducer { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); processMcKinks(col, mcCols, tracks, tracksWithItsPid, kinks, mcParticles); @@ -438,7 +433,7 @@ struct FemtoProducer { // process monte carlo tracks and v0s void processTracksV0sCascadesRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, consumeddata::Run3PpMcGenCollisions const& mcCols, - BCsWithTimestamps const& bcs, + o2::aod::BCsWithTimestamps const& bcs, consumeddata::Run3McRecoTracks const& tracks, consumeddata::Run3RecoVzeros const& v0s, consumeddata::Run3RecoCascades const& cascades, @@ -447,8 +442,8 @@ struct FemtoProducer { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); + auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, tracksWithItsPid, v0s, mcParticles); processMcCascades(col, mcCols, tracks, tracksWithItsPid, cascades, mcParticles); @@ -456,8 +451,8 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksV0sCascadesRun3ppMc, "Provide reconstructed and generated tracks and v0s", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + o2::framework::WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; return workflow; } diff --git a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx index 6f9347015eb..ec684af5f62 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx @@ -27,34 +27,26 @@ #include "Framework/InitContext.h" #include "Framework/runDataProcessing.h" -#include -#include -#include - -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoProducerDerivedToDerived { // setup tables - using Collisions = Join; + using Collisions = o2::soa::Join; using Collision = Collisions::iterator; using FilteredCollisions = o2::soa::Filtered; using FilteredCollision = FilteredCollisions::iterator; - using Tracks = o2::soa::Join; - using Lambdas = o2::soa::Join; - using K0shorts = o2::soa::Join; + using Tracks = o2::soa::Join; + using Lambdas = o2::soa::Join; + using K0shorts = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // collision builder collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); collisionbuilder::CollisionBuilderDerivedToDerivedProducts collisionBuilderProducts; collisionbuilder::CollisionBuilderDerivedToDerived collisionBuilder; @@ -65,9 +57,9 @@ struct FemtoProducerDerivedToDerived { trackbuilder::ConfTrackSelection1 trackSelections1; trackbuilder::ConfTrackSelection2 trackSelections2; - Partition trackPartition1 = MAKE_TRACK_PARTITION(trackSelections1); - Partition trackPartition2 = MAKE_TRACK_PARTITION(trackSelections2); - Preslice perColTracks = femtobase::stored::fColId; + o2::framework::Partition trackPartition1 = MAKE_TRACK_PARTITION(trackSelections1); + o2::framework::Partition trackPartition2 = MAKE_TRACK_PARTITION(trackSelections2); + o2::framework::Preslice perColTracks = o2::aod::femtobase::stored::fColId; // v0 builder v0builder::V0BuilderDerivedToDerived v0Builder; @@ -75,14 +67,14 @@ struct FemtoProducerDerivedToDerived { v0builder::ConfV0TablesDerivedToDerived confV0Builder; v0builder::ConfLambdaSelection1 lambdaSelection1; - Partition lambdaPartition = MAKE_LAMBDA_PARTITION(lambdaSelection1); - Preslice perColLambdas = femtobase::stored::fColId; + o2::framework::Partition lambdaPartition = MAKE_LAMBDA_PARTITION(lambdaSelection1); + o2::framework::Preslice perColLambdas = o2::aod::femtobase::stored::fColId; v0builder::ConfK0shortSelection1 k0shortSelection1; - Partition k0shortPartition = MAKE_K0SHORT_PARTITION(k0shortSelection1); - Preslice perColK0shorts = femtobase::stored::fColId; + o2::framework::Partition k0shortPartition = MAKE_K0SHORT_PARTITION(k0shortSelection1); + o2::framework::Preslice perColK0shorts = o2::aod::femtobase::stored::fColId; - void init(InitContext& /*context*/) + void init(o2::framework::InitContext& /*context*/) { trackBuilder.init(confTrackBuilder); v0Builder.init(confV0Builder); @@ -130,8 +122,8 @@ struct FemtoProducerDerivedToDerived { PROCESS_SWITCH(FemtoProducerDerivedToDerived, processK0shorts, "Process k0short and tracks", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + o2::framework::WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; return workflow; } diff --git a/PWGCF/Femto/Tasks/CMakeLists.txt b/PWGCF/Femto/Tasks/CMakeLists.txt index c7c365a8140..baad9c28a8a 100644 --- a/PWGCF/Femto/Tasks/CMakeLists.txt +++ b/PWGCF/Femto/Tasks/CMakeLists.txt @@ -68,3 +68,8 @@ o2physics_add_dpl_workflow(femto-triplet-track-track-track SOURCES femtoTripletTrackTrackTrack.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femto-triplet-track-track-v0 + SOURCES femtoTripletTrackTrackV0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx index 74c2617b87b..c46c02f5737 100644 --- a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx +++ b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx @@ -34,37 +34,33 @@ #include "Framework/runDataProcessing.h" #include -#include #include -using namespace o2::aod; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoCascadeQa { - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using FemtoXis = o2::soa::Join; - using FemtoOmegas = o2::soa::Join; - using FemtoTracks = o2::soa::Join; + using FemtoXis = o2::soa::Join; + using FemtoOmegas = o2::soa::Join; + using FemtoTracks = o2::soa::Join; - using FemtoXisWithLabel = o2::soa::Join; - using FemtoOmegasWithLabel = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; + using FemtoXisWithLabel = o2::soa::Join; + using FemtoOmegasWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; colhistmanager::ConfCollisionQaBinning confCollisionQaBinning; @@ -75,11 +71,11 @@ struct FemtoCascadeQa { particlecleaner::ConfXiCleaner1 confXiCleaner; particlecleaner::ParticleCleaner xiCleaner; - Partition xiPartition = MAKE_CASCADE_PARTITION(confXiSelection); - Preslice preColXis = femtobase::stored::fColId; + o2::framework::Partition xiPartition = MAKE_CASCADE_PARTITION(confXiSelection); + o2::framework::Preslice preColXis = o2::aod::femtobase::stored::fColId; - Partition xiWithLabelPartition = MAKE_CASCADE_PARTITION(confXiSelection); - Preslice perColXisWithLabel = femtobase::stored::fColId; + o2::framework::Partition xiWithLabelPartition = MAKE_CASCADE_PARTITION(confXiSelection); + o2::framework::Preslice perColXisWithLabel = o2::aod::femtobase::stored::fColId; cascadehistmanager::ConfXiBinning confXiBinning; cascadehistmanager::ConfXiQaBinning confXiQaBinning; @@ -97,11 +93,11 @@ struct FemtoCascadeQa { particlecleaner::ConfOmegaCleaner1 confOmegaCleaner; particlecleaner::ParticleCleaner omegaCleaner; - Partition omegaPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); - Preslice preColOmegas = femtobase::stored::fColId; + o2::framework::Partition omegaPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); + o2::framework::Preslice preColOmegas = o2::aod::femtobase::stored::fColId; - Partition omegaWithLabelPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); - Preslice perColOmegasWithLabel = femtobase::stored::fColId; + o2::framework::Partition omegaWithLabelPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); + o2::framework::Preslice perColOmegasWithLabel = o2::aod::femtobase::stored::fColId; cascadehistmanager::ConfOmegaBinning confOmegaBinning; cascadehistmanager::ConfOmegaQaBinning confOmegaQaBinning; @@ -121,42 +117,51 @@ struct FemtoCascadeQa { trackhistmanager::ConfCascadeBachelorBinning confBachelorBinning; trackhistmanager::ConfCascadeBachelorQaBinning confBachelorQaBinning; - HistogramRegistry hRegistry{"FemtoCascadeQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoCascadeQA", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(o2::framework::InitContext&) { if ((doprocessXi + doprocessXiMc + doprocessOmega + doprocessOmegaMc) > 1) { LOG(fatal) << "Only one process can be activated"; } bool processData = doprocessXi || doprocessOmega; + xiCleaner.init(confXiCleaner); omegaCleaner.init(confOmegaCleaner); + + std::map> colHistSpec; + std::map> bachelorHistSpec; + std::map> posDaughterHistSpec; + std::map> negDaughterHistSpec; + std::map> xiHistSpec; + std::map> omegaHistSpec; + if (processData) { - auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto bachelorHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confBachelorBinning, confBachelorQaBinning); - auto posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confPosDaughterBinning, confPosDaughterQaBinning); - auto negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confNegDaughterBinning, confNegDaughterQaBinning); + bachelorHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confBachelorBinning, confBachelorQaBinning); + posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confPosDaughterBinning, confPosDaughterQaBinning); + negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confNegDaughterBinning, confNegDaughterQaBinning); if (doprocessXi) { - auto xiHistSpec = cascadehistmanager::makeCascadeQaHistSpecMap(confXiBinning, confXiQaBinning); + xiHistSpec = cascadehistmanager::makeCascadeQaHistSpecMap(confXiBinning, confXiQaBinning); xiHistManager.init(&hRegistry, xiHistSpec, confXiSelection, confXiQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } if (doprocessOmega) { - auto omegaHistSpec = cascadehistmanager::makeCascadeQaHistSpecMap(confOmegaBinning, confOmegaQaBinning); + omegaHistSpec = cascadehistmanager::makeCascadeQaHistSpecMap(confOmegaBinning, confOmegaQaBinning); omegaHistManager.init(&hRegistry, omegaHistSpec, confOmegaSelection, confOmegaQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } } else { - auto colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto bachelorHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confBachelorBinning, confBachelorQaBinning); - auto posDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confPosDaughterBinning, confPosDaughterQaBinning); - auto negDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confNegDaughterBinning, confNegDaughterQaBinning); + bachelorHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confBachelorBinning, confBachelorQaBinning); + posDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confPosDaughterBinning, confPosDaughterQaBinning); + negDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confNegDaughterBinning, confNegDaughterQaBinning); if (doprocessXiMc) { - auto xiHistSpec = cascadehistmanager::makeCascadeMcQaHistSpecMap(confXiBinning, confXiQaBinning); + xiHistSpec = cascadehistmanager::makeCascadeMcQaHistSpecMap(confXiBinning, confXiQaBinning); xiHistManager.init(&hRegistry, xiHistSpec, confXiSelection, confXiQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } if (doprocessOmegaMc) { - auto omegaHistSpec = cascadehistmanager::makeCascadeMcQaHistSpecMap(confOmegaBinning, confOmegaQaBinning); + omegaHistSpec = cascadehistmanager::makeCascadeMcQaHistSpecMap(confOmegaBinning, confOmegaQaBinning); omegaHistManager.init(&hRegistry, omegaHistSpec, confOmegaSelection, confOmegaQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } } @@ -166,17 +171,17 @@ struct FemtoCascadeQa { void processXi(FilteredFemtoCollision const& col, FemtoXis const& /*xis*/, FemtoTracks const& tracks) { colHistManager.fill(col); - auto xiSlice = xiPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto xiSlice = xiPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& xi : xiSlice) { xiHistManager.fill(xi, tracks); } } PROCESS_SWITCH(FemtoCascadeQa, processXi, "Process Xis", true); - void processXiMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processXiMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { colHistManager.fill(col, mcCols); - auto xiSlice = xiWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto xiSlice = xiWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& xi : xiSlice) { if (!xiCleaner.isClean(xi, mcParticles, mcMothers, mcPartonicMothers)) { continue; @@ -189,17 +194,17 @@ struct FemtoCascadeQa { void processOmega(FilteredFemtoCollision const& col, FemtoOmegas const& /*omegas*/, FemtoTracks const& tracks) { colHistManager.fill(col); - auto omegaSlice = omegaPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto omegaSlice = omegaPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& omega : omegaSlice) { omegaHistManager.fill(omega, tracks); } } PROCESS_SWITCH(FemtoCascadeQa, processOmega, "Process Omegas", false); - void processOmegaMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& /*omegas*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processOmegaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& /*omegas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { colHistManager.fill(col, mcCols); - auto omegaSlice = omegaWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto omegaSlice = omegaWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& omega : omegaSlice) { if (!omegaCleaner.isClean(omega, mcParticles, mcMothers, mcPartonicMothers)) { continue; @@ -210,9 +215,9 @@ struct FemtoCascadeQa { PROCESS_SWITCH(FemtoCascadeQa, processOmegaMc, "Process Omegas with MC information", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index e64c99b193a..89c7de3c100 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -35,39 +35,36 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -#include +#include #include -using namespace o2::aod; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoKinkQa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; // Define kink/sigma tables (joining tables for comprehensive information) - using FemtoSigmas = o2::soa::Join; - using FemtoSigmaPlus = o2::soa::Join; - using FemtoTracks = o2::soa::Join; + using FemtoSigmas = o2::soa::Join; + using FemtoSigmaPlus = o2::soa::Join; + using FemtoTracks = o2::soa::Join; - using FemtoSigmasWithLabel = o2::soa::Join; - using FemtoSigmaPlusWithLabel = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; + using FemtoSigmasWithLabel = o2::soa::Join; + using FemtoSigmaPlusWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup for collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; @@ -79,11 +76,11 @@ struct FemtoKinkQa { particlecleaner::ConfSigmaCleaner1 confSigmaCleaner; particlecleaner::ParticleCleaner sigmaCleaner; - Partition sigmaPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); - Preslice perColSigmas = femtobase::stored::fColId; + o2::framework::Partition sigmaPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); + o2::framework::Preslice perColSigmas = o2::aod::femtobase::stored::fColId; - Partition sigmaWithLabelPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); - Preslice perColSigmasWithLabel = femtobase::stored::fColId; + o2::framework::Partition sigmaWithLabelPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); + o2::framework::Preslice perColSigmasWithLabel = o2::aod::femtobase::stored::fColId; kinkhistmanager::ConfSigmaBinning1 confSigmaBinning; kinkhistmanager::ConfSigmaQaBinning1 confSigmaQaBinning; @@ -99,11 +96,11 @@ struct FemtoKinkQa { particlecleaner::ConfSigmaPlusCleaner1 confSigmaPlusCleaner; particlecleaner::ParticleCleaner sigmaPlusCleaner; - Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); - Preslice perColSigmaPlus = femtobase::stored::fColId; + o2::framework::Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); + o2::framework::Preslice perColSigmaPlus = o2::aod::femtobase::stored::fColId; - Partition sigmaPlusWithLabelPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaSelection); - Preslice perColSigmaPlussWithLabel = femtobase::stored::fColId; + o2::framework::Partition sigmaPlusWithLabelPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaSelection); + o2::framework::Preslice perColSigmaPlussWithLabel = o2::aod::femtobase::stored::fColId; kinkhistmanager::ConfSigmaPlusBinning1 confSigmaPlusBinning; kinkhistmanager::ConfSigmaPlusQaBinning1 confSigmaPlusQaBinning; @@ -117,39 +114,46 @@ struct FemtoKinkQa { trackhistmanager::ConfKinkChaDauBinning confKinkChaDaughterBinning; trackhistmanager::ConfKinkChaDauQaBinning confKinkChaDaughterQaBinning; - HistogramRegistry hRegistry{"FemtoKinkQa", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoKinkQa", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(o2::framework::InitContext&) { if ((doprocessSigma + doprocessSigmaMc + doprocessSigmaPlus + doprocessSigmaPlusMc) > 1) { LOG(fatal) << "Only one process can be activated"; } bool processData = doprocessSigma || doprocessSigmaPlus; + sigmaCleaner.init(confSigmaCleaner); sigmaPlusCleaner.init(confSigmaPlusCleaner); + + std::map> colHistSpec; + std::map> chaDauHistSpec; + std::map> sigmaHistSpec; + std::map> sigmaPlusHistSpec; + if (processData) { - auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto chaDauHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); + chaDauHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); if (doprocessSigma) { - auto sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); + sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaSelection, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } if (doprocessSigmaPlus) { - auto sigmaPlusHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); + sigmaPlusHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusSelection, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } } else { - auto colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto chaDauHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); + chaDauHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); if (doprocessSigmaMc) { - auto sigmaHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); + sigmaHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaSelection, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } if (doprocessSigmaPlusMc) { - auto sigmaPlusHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); + sigmaPlusHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusSelection, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } } @@ -159,17 +163,17 @@ struct FemtoKinkQa { void processSigma(FilteredFemtoCollision const& col, FemtoSigmas const& /*sigmas*/, FemtoTracks const& tracks) { colHistManager.fill(col); - auto sigmaSlice = sigmaPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto sigmaSlice = sigmaPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& sigma : sigmaSlice) { sigmaHistManager.fill(sigma, tracks); } } PROCESS_SWITCH(FemtoKinkQa, processSigma, "Process sigmas", true); - void processSigmaMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSigmaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { colHistManager.fill(col, mcCols); - auto sigmaSlice = sigmaWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto sigmaSlice = sigmaWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& sigma : sigmaSlice) { if (!sigmaCleaner.isClean(sigma, mcParticles, mcMothers, mcPartonicMothers)) { continue; @@ -183,7 +187,7 @@ struct FemtoKinkQa { { colHistManager.fill(col); - auto sigmaplusSlice = sigmaPlusPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto sigmaplusSlice = sigmaPlusPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& sp : sigmaplusSlice) { sigmaPlusHistManager.fill(sp, tracks); @@ -191,10 +195,10 @@ struct FemtoKinkQa { } PROCESS_SWITCH(FemtoKinkQa, processSigmaPlus, "Process sigma plus", false); - void processSigmaPlusMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaPlus*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSigmaPlusMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaPlus*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { colHistManager.fill(col, mcCols); - auto sigmaPlusSlice = sigmaPlusWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto sigmaPlusSlice = sigmaPlusWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& sigmaPlus : sigmaPlusSlice) { if (!sigmaPlusCleaner.isClean(sigmaPlus, mcParticles, mcMothers, mcPartonicMothers)) { continue; @@ -205,9 +209,9 @@ struct FemtoKinkQa { PROCESS_SWITCH(FemtoKinkQa, processSigmaPlusMc, "Process sigmas", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx b/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx index cb3b929537c..4552c9d6fd7 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx @@ -38,42 +38,47 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -#include +#include #include -using namespace o2; -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoPairTrackCascade { // setup tables - using Collisions = Join; - using Collision = Collisions::iterator; + using FemtoCollisions = o2::soa::Join; + using FilteredFemtoCollisions = o2::soa::Filtered; + using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FilteredCollisions = o2::soa::Filtered; - using FilteredCollision = FilteredCollisions::iterator; + using FemtoCollisionsWithLabel = o2::soa::Join; + using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; + using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using Tracks = o2::soa::Join; - using Xis = o2::soa::Join; - using Omegas = o2::soa::Join; + using FemtoTracks = o2::soa::Join; + using FemtoXis = o2::soa::Join; + using FemtoOmegas = o2::soa::Join; - SliceCache cache; + using FemtoTracksWithLabel = o2::soa::Join; + using FemtoXisWithLabel = o2::soa::Join; + using FemtoOmegasWithLabel = o2::soa::Join; + + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; // setup tracks trackbuilder::ConfTrackSelection1 confTrackSelection; trackhistmanager::ConfTrackBinning1 confTrackBinning; particlecleaner::ConfTrackCleaner1 confTrackCleaner; - Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); - Preslice perColTracks = aod::femtobase::stored::fColId; + + o2::framework::Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColTracks = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition trackWithLabelPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; // setup for daughters/bachelor trackhistmanager::ConfCascadePosDauBinning confPosDauBinning; @@ -84,15 +89,23 @@ struct FemtoPairTrackCascade { cascadebuilder::ConfXiSelection confXiSelection; cascadehistmanager::ConfXiBinning confXiBinning; particlecleaner::ConfXiCleaner1 confXiCleaner; - Partition xiPartition = MAKE_CASCADE_PARTITION(confXiSelection); - Preslice perColXis = aod::femtobase::stored::fColId; + + o2::framework::Partition xiPartition = MAKE_CASCADE_PARTITION(confXiSelection); + o2::framework::Preslice perColXis = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition xiWithLabelPartition = MAKE_CASCADE_PARTITION(confXiSelection); + o2::framework::Preslice perColXisWithLabel = o2::aod::femtobase::stored::fColId; // setup omegas cascadebuilder::ConfOmegaSelection confOmegaSelection; cascadehistmanager::ConfOmegaBinning confOmegaBinning; particlecleaner::ConfOmegaCleaner1 confOmegaCleaner; - Partition omegaPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); - Preslice perColOmegas = aod::femtobase::stored::fColId; + + o2::framework::Partition omegaPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); + o2::framework::Preslice perColOmegas = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition omegaWithLabelPartition = MAKE_CASCADE_PARTITION(confOmegaSelection); + o2::framework::Preslice perColOmegasWithLabel = o2::aod::femtobase::stored::fColId; // setup pairs pairhistmanager::ConfPairBinning confPairBinning; @@ -132,19 +145,32 @@ struct FemtoPairTrackCascade { std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; std::vector defaultCentBins{10, 0, 100}; - ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; - ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; - ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; pairhistmanager::ConfMixing confMixing; - HistogramRegistry hRegistry{"FemtoTrackCascade", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoTrackCascade", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; // setup cpr closepairrejection::ConfCprTrackCascadeBachelor confCprBachelor; closepairrejection::ConfCprTrackV0Daughter confCprV0Daughter; - void init(InitContext&) + void init(o2::framework::InitContext&) { + bool processData = doprocessXiSameEvent || doprocessXiMixedEvent || doprocessOmegaSameEvent || doprocessOmegaMixedEvent; + bool processMc = doprocessXiSameEventMc || doprocessXiMixedEventMc || doprocessOmegaSameEventMc || doprocessOmegaMixedEventMc; + + if (processData && processMc) { + LOG(fatal) << "Both data and mc processing is enabled. Breaking..."; + } + + bool processXi = doprocessXiSameEvent || doprocessXiSameEventMc || doprocessXiMixedEvent || doprocessXiMixedEventMc; + bool processOmega = doprocessOmegaSameEvent || doprocessOmegaSameEventMc || doprocessOmegaMixedEvent || doprocessOmegaMixedEventMc; + + if (processXi && processOmega) { + LOG(fatal) << "Both xi-track and omega-track processing is enabled. Breaking..."; + } // setup columnpolicy for binning // default values are used during instantiation, so we need to explicity update them here @@ -152,63 +178,105 @@ struct FemtoPairTrackCascade { mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; - // setup histograms - auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - auto trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); - auto bachelorHistSpec = trackhistmanager::makeTrackHistSpecMap(confBachelorBinning); - auto posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); - auto negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); - auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); - auto cprHistSpecBachelor = closepairrejection::makeCprHistSpecMap(confCprBachelor); - auto cprHistSpecV0Daughter = closepairrejection::makeCprHistSpecMap(confCprV0Daughter); - - // setup for xis - if (doprocessXiSameEvent || doprocessXiMixedEvent) { - auto xiHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confXiBinning); - auto pairTrackXiHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); - pairTrackXiBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackXiHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); - } - - // setup for omegas - if (doprocessOmegaSameEvent || doprocessOmegaMixedEvent) { - auto omegaHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confOmegaBinning); - auto pairTrackOmegaHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); - pairTrackOmegaBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackOmegaHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); - } - - if (((doprocessXiSameEvent || doprocessXiMixedEvent) + (doprocessOmegaSameEvent || doprocessOmegaMixedEvent)) > 1) { - LOG(fatal) << "Can only process xi-tracks Or omega-tracks"; + std::map> colHistSpec; + std::map> trackHistSpec; + std::map> bachelorHistSpec; + std::map> posDauSpec; + std::map> negDauSpec; + std::map> xiHistSpec; + std::map> omegaHistSpec; + std::map> pairTrackCascadeHistSpec; + + std::map> cprHistSpecBachelor = closepairrejection::makeCprHistSpecMap(confCprBachelor); + std::map> cprHistSpecV0Daughter = closepairrejection::makeCprHistSpecMap(confCprV0Daughter); + + if (processData) { + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); + bachelorHistSpec = trackhistmanager::makeTrackHistSpecMap(confBachelorBinning); + posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); + pairTrackCascadeHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + if (processXi) { + xiHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confXiBinning); + pairTrackCascadeHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + pairTrackXiBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + } else { + omegaHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confOmegaBinning); + pairTrackCascadeHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + pairTrackOmegaBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + } + } else { + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + trackHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning); + bachelorHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confBachelorBinning); + posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); + pairTrackCascadeHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); + if (processXi) { + xiHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confXiBinning); + pairTrackCascadeHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); + pairTrackXiBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + } else { + omegaHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confOmegaBinning); + pairTrackCascadeHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + pairTrackOmegaBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + } } }; - void processXiSameEvent(FilteredCollision const& col, Tracks const& tracks, Xis const& xis) + void processXiSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoXis const& xis) { pairTrackXiBuilder.processSameEvent(col, tracks, trackPartition, xis, xiPartition, cache); } PROCESS_SWITCH(FemtoPairTrackCascade, processXiSameEvent, "Enable processing same event processing for tracks and xis", true); - void processXiMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, Xis const& /*xis*/) + void processXiSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& xis, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairTrackXiBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, xis, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoPairTrackCascade, processXiSameEventMc, "Enable processing same event processing for tracks and xis with mc information", false); + + void processXiMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoXis const& /*xis*/) { pairTrackXiBuilder.processMixedEvent(cols, tracks, trackPartition, xiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackCascade, processXiMixedEvent, "Enable processing mixed event processing for tracks and xis", true); - void processOmegaSameEvent(FilteredCollision const& col, Tracks const& tracks, Omegas const& omegas) + void processXiMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairTrackXiBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairTrackCascade, processXiMixedEventMc, "Enable processing mixed event processing for tracks and xis with mc information", false); + + void processOmegaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoOmegas const& omegas) { pairTrackOmegaBuilder.processSameEvent(col, tracks, trackPartition, omegas, omegaPartition, cache); } PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaSameEvent, "Enable processing same event processing for tracks and omegas", false); - void processOmegaMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, Omegas const& /*omegas*/) + void processOmegaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& omegas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairTrackOmegaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, omegas, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaSameEventMc, "Enable processing same event processing for tracks and omegas with mc information", false); + + void processOmegaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoOmegas const& /*omegas*/) { pairTrackOmegaBuilder.processMixedEvent(cols, tracks, trackPartition, omegaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaMixedEvent, "Enable processing mixed event processing for tracks and omegas", false); + + void processOmegaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairTrackOmegaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaMixedEventMc, "Enable processing mixed event processing for tracks and omegas with mc information", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx index 55b1717b0c8..87ee22c43e6 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx @@ -39,40 +39,35 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -#include +#include #include -using namespace o2; -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoPairTrackKink { // setup tables - using FemtoCollisions = Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using FemtoTracks = o2::soa::Join; - using FemtoSigmas = o2::soa::Join; - using FemtoSigmaPlus = o2::soa::Join; + using FemtoTracks = o2::soa::Join; + using FemtoSigmas = o2::soa::Join; + using FemtoSigmaPlus = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; - using FemtoSigmasWithLabel = o2::soa::Join; - using FemtoSigmaPlusWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; + using FemtoSigmasWithLabel = o2::soa::Join; + using FemtoSigmaPlusWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; // setup tracks @@ -80,11 +75,11 @@ struct FemtoPairTrackKink { trackhistmanager::ConfTrackBinning1 confTrackBinning; particlecleaner::ConfTrackCleaner1 confTrackCleaner; - Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); - Preslice perColTracks = aod::femtobase::stored::fColId; + o2::framework::Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColTracks = o2::aod::femtobase::stored::fColId; - Partition trackWithLabelPartition = MAKE_TRACK_PARTITION(confTrackSelection); - Preslice perColtracksWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition trackWithLabelPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; // setup for daughters trackhistmanager::ConfKinkChaDauBinning confChaDauBinning; @@ -94,22 +89,22 @@ struct FemtoPairTrackKink { kinkhistmanager::ConfSigmaBinning1 confSigmaBinning; particlecleaner::ConfSigmaCleaner1 confSigmaCleaner; - Partition sigmaPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); - Preslice perColSigmas = aod::femtobase::stored::fColId; + o2::framework::Partition sigmaPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); + o2::framework::Preslice perColSigmas = o2::aod::femtobase::stored::fColId; - Partition sigmaWithLabelPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); - Preslice perColSigmasWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition sigmaWithLabelPartition = MAKE_SIGMA_PARTITION(confSigmaSelection); + o2::framework::Preslice perColSigmasWithLabel = o2::aod::femtobase::stored::fColId; // setup for sigma plus kinkbuilder::ConfSigmaPlusSelection1 confSigmaPlusSelection; kinkhistmanager::ConfSigmaPlusBinning1 confSigmaPlusBinning; particlecleaner::ConfSigmaPlusCleaner1 confSigmaPlusCleaner; - Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); - Preslice perColSigmaPlus = aod::femtobase::stored::fColId; + o2::framework::Partition sigmaPlusPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); + o2::framework::Preslice perColSigmaPlus = o2::aod::femtobase::stored::fColId; - Partition sigmaPlusWithLabelPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); - Preslice perColSigmaPlusWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition sigmaPlusWithLabelPartition = MAKE_SIGMAPLUS_PARTITION(confSigmaPlusSelection); + o2::framework::Preslice perColSigmaPlusWithLabel = o2::aod::femtobase::stored::fColId; // setup pairs pairhistmanager::ConfPairBinning confPairBinning; @@ -141,17 +136,17 @@ struct FemtoPairTrackKink { std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; std::vector defaultCentBins{10, 0, 100}; - ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; - ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; - ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; pairhistmanager::ConfMixing confMixing; - HistogramRegistry hRegistry{"FemtoTrackKink", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoTrackKink", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; // setup cpr closepairrejection::ConfCprTrackKinkDaughter confCpr; - void init(InitContext&) + void init(o2::framework::InitContext&) { bool processData = doprocessSigmaSameEvent || doprocessSigmaMixedEvent || doprocessSigmaPlusSameEvent || doprocessSigmaPlusMixedEvent; bool processMc = doprocessSigmaSameEventMc || doprocessSigmaMixedEventMc || doprocessSigmaPlusSameEventMc || doprocessSigmaPlusMixedEventMc; @@ -173,31 +168,37 @@ struct FemtoPairTrackKink { mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; - auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + std::map> colHistSpec; + std::map> trackHistSpec; + std::map> chaDauSpec; + std::map> sigmaHistSpec; + std::map> sigmaPlusHistSpec; + std::map> pairTrackKinkHistSpec; + std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); if (processData) { - auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - auto trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); - auto chaDauSpec = trackhistmanager::makeTrackHistSpecMap(confChaDauBinning); - auto pairTrackKinkHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); + chaDauSpec = trackhistmanager::makeTrackHistSpecMap(confChaDauBinning); + pairTrackKinkHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); if (processSigma) { - auto sigmaHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaBinning); + sigmaHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaBinning); pairTrackSigmaBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } else { - auto sigmaplusHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaPlusBinning); - pairTrackSigmaPlusBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaplusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); + sigmaPlusHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaPlusBinning); + pairTrackSigmaPlusBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } } else { - auto colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); - auto trackHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning); - auto chaDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confChaDauBinning); - auto pairTrackKinkHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + trackHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning); + chaDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confChaDauBinning); + pairTrackKinkHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); if (processSigma) { - auto sigmaHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaBinning); + sigmaHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaBinning); pairTrackSigmaBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } else { - auto sigmaplusHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaPlusBinning); - pairTrackSigmaPlusBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaplusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); + sigmaPlusHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaPlusBinning); + pairTrackSigmaPlusBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } } hRegistry.print(); @@ -209,7 +210,7 @@ struct FemtoPairTrackKink { } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaSameEvent, "Enable processing same event processing for tracks and sigmas", true); - void processSigmaSameEventMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& sigmas, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSigmaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& sigmas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackSigmaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, sigmas, sigmaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } @@ -221,7 +222,7 @@ struct FemtoPairTrackKink { } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaMixedEvent, "Enable processing mixed event processing for tracks and sigmas", true); - void processSigmaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSigmaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackSigmaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } @@ -233,7 +234,7 @@ struct FemtoPairTrackKink { } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusSameEvent, "Enable processing same event processing for tracks and sigma plus", false); - void processSigmaPlusSameEventMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& sigmaplus, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSigmaPlusSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& sigmaplus, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackSigmaPlusBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, sigmaplus, sigmaPlusWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } @@ -245,16 +246,16 @@ struct FemtoPairTrackKink { } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusMixedEvent, "Enable processing mixed event processing for tracks and sigma plus", false); - void processSigmaPlusMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaplus*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSigmaPlusMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaplus*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackSigmaPlusBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaPlusWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusMixedEventMc, "Enable processing mixed event processing for tracks and sigma plus with MC information", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx index 6a13f9b5745..c60281006c6 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx @@ -36,35 +36,31 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" +#include #include -using namespace o2; -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoPairTrackTrack { // setup tables - using FemtoCollisions = Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using FemtoTracks = o2::soa::Join; + using FemtoTracks = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; // setup tracks @@ -76,13 +72,13 @@ struct FemtoPairTrackTrack { particlecleaner::ConfTrackCleaner2 confTrackCleaner2; trackhistmanager::ConfTrackBinning2 confTrackBinning2; - Partition trackPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); - Partition trackPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); - Preslice perColtracks = aod::femtobase::stored::fColId; + o2::framework::Partition trackPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracks = o2::aod::femtobase::stored::fColId; - Partition trackWithLabelPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); - Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); - Preslice perColtracksWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition trackWithLabelPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; // setup pairs pairhistmanager::ConfPairBinning confPairBinning; @@ -103,14 +99,14 @@ struct FemtoPairTrackTrack { std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; std::vector defaultCentBins{10, 0, 100}; - ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; - ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; - ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; pairhistmanager::ConfMixing confMixing; - HistogramRegistry hRegistry{"FemtoTrackTrack", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoTrackTrack", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(o2::framework::InitContext&) { if ((doprocessSameEvent + doprocessSameEventMc) > 1 || (doprocessMixedEvent + doprocessMixedEventMc) > 1) { LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; @@ -128,19 +124,23 @@ struct FemtoPairTrackTrack { mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; // setup histogram specs - auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + std::map> colHistSpec; + std::map> trackHistSpec1; + std::map> trackHistSpec2; + std::map> pairHistSpec; + std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); if (processData) { - auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - auto trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); - auto trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); - auto pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); + pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); pairTrackTrackBuilder.init(&hRegistry, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confTrackCleaner2, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); } else { - auto colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); - auto trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); - auto trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); - auto pairHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); + pairHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); pairTrackTrackBuilder.init(&hRegistry, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confTrackCleaner2, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); } hRegistry.print(); @@ -152,7 +152,7 @@ struct FemtoPairTrackTrack { } PROCESS_SWITCH(FemtoPairTrackTrack, processSameEvent, "Enable processing same event processing", true); - void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackTrackBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache); } @@ -164,16 +164,16 @@ struct FemtoPairTrackTrack { } PROCESS_SWITCH(FemtoPairTrackTrack, processMixedEvent, "Enable processing mixed event processing", true); - void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackTrackBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTrack, processMixedEventMc, "Enable processing mixed event processing", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx index 934e8406684..bab46c73725 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx @@ -38,40 +38,35 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -#include +#include #include -using namespace o2; -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoPairTrackV0 { // setup tables - using FemtoCollisions = Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using FemtoTracks = o2::soa::Join; - using FemtoLambdas = o2::soa::Join; - using FemtoK0shorts = o2::soa::Join; + using FemtoTracks = o2::soa::Join; + using FemtoLambdas = o2::soa::Join; + using FemtoK0shorts = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; - using FemtoLambdasWithLabel = o2::soa::Join; - using FemtoK0shortsWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; + using FemtoLambdasWithLabel = o2::soa::Join; + using FemtoK0shortsWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; // setup tracks @@ -79,11 +74,11 @@ struct FemtoPairTrackV0 { trackhistmanager::ConfTrackBinning1 confTrackBinning; particlecleaner::ConfTrackCleaner1 confTrackCleaner; - Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); - Preslice perColTracks = aod::femtobase::stored::fColId; + o2::framework::Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColTracks = o2::aod::femtobase::stored::fColId; - Partition trackWithLabelPartition = MAKE_TRACK_PARTITION(confTrackSelection); - Preslice perColtracksWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition trackWithLabelPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; // setup for daughters trackhistmanager::ConfV0PosDauBinning confPosDauBinning; @@ -94,22 +89,22 @@ struct FemtoPairTrackV0 { v0histmanager::ConfLambdaBinning1 confLambdaBinning; particlecleaner::ConfLambdaCleaner1 confLambdaCleaner; - Partition lambdaPartition = MAKE_LAMBDA_PARTITION(lambdaSelection); - Preslice perColLambdas = aod::femtobase::stored::fColId; + o2::framework::Partition lambdaPartition = MAKE_LAMBDA_PARTITION(lambdaSelection); + o2::framework::Preslice perColLambdas = o2::aod::femtobase::stored::fColId; - Partition lambdaWithLabelPartition = MAKE_LAMBDA_PARTITION(lambdaSelection); - Preslice perColLambdasWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition lambdaWithLabelPartition = MAKE_LAMBDA_PARTITION(lambdaSelection); + o2::framework::Preslice perColLambdasWithLabel = o2::aod::femtobase::stored::fColId; // setup k0shorts v0builder::ConfK0shortSelection1 k0shortSelection; v0histmanager::ConfK0shortBinning1 confK0shortBinning; particlecleaner::ConfK0shortCleaner1 confK0shortCleaner; - Partition k0shortPartition = MAKE_K0SHORT_PARTITION(k0shortSelection); - Preslice perColk0shorts = aod::femtobase::stored::fColId; + o2::framework::Partition k0shortPartition = MAKE_K0SHORT_PARTITION(k0shortSelection); + o2::framework::Preslice perColk0shorts = o2::aod::femtobase::stored::fColId; - Partition k0shortWithLabelPartition = MAKE_K0SHORT_PARTITION(k0shortSelection); - Preslice perColk0shortsWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition k0shortWithLabelPartition = MAKE_K0SHORT_PARTITION(k0shortSelection); + o2::framework::Preslice perColk0shortsWithLabel = o2::aod::femtobase::stored::fColId; // setup pairs pairhistmanager::ConfPairBinning confPairBinning; @@ -143,17 +138,17 @@ struct FemtoPairTrackV0 { std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; std::vector defaultCentBins{10, 0, 100}; - ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; - ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; - ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; pairhistmanager::ConfMixing confMixing; - HistogramRegistry hRegistry{"FemtoTrackV0", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoTrackV0", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; // setup cpr closepairrejection::ConfCprTrackV0Daughter confCpr; - void init(InitContext&) + void init(o2::framework::InitContext&) { bool processData = doprocessLambdaSameEvent || doprocessLambdaMixedEvent || doprocessK0shortSameEvent || doprocessK0shortMixedEvent; bool processMc = doprocessLambdaSameEventMc || doprocessLambdaMixedEventMc || doprocessK0shortSameEventMc || doprocessK0shortMixedEventMc; @@ -175,32 +170,39 @@ struct FemtoPairTrackV0 { mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; - auto cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + std::map> colHistSpec; + std::map> trackHistSpec; + std::map> posDauSpec; + std::map> negDauSpec; + std::map> lambdaHistSpec; + std::map> k0shortHistSpec; + std::map> pairTrackV0HistSpec; + std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); if (processData) { - auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - auto trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); - auto posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); - auto negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); - auto pairTrackV0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec = trackhistmanager::makeTrackHistSpecMap(confTrackBinning); + posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); + pairTrackV0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); if (processLambda) { - auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); + lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); pairTrackLambdaBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } else { - auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); + k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); pairTrackK0shortBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, lambdaSelection, confTrackCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } } else { - auto colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); - auto trackHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning); - auto posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); - auto negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); - auto pairTrackV0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + trackHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning); + posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); + pairTrackV0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); if (processLambda) { - auto lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); + lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); pairTrackLambdaBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } else { - auto k0shortHistSpec = v0histmanager::makeV0McHistSpecMap(confK0shortBinning); + k0shortHistSpec = v0histmanager::makeV0McHistSpecMap(confK0shortBinning); pairTrackK0shortBuilder.init(&hRegistry, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } } @@ -213,7 +215,7 @@ struct FemtoPairTrackV0 { } PROCESS_SWITCH(FemtoPairTrackV0, processLambdaSameEvent, "Enable processing same event processing for tracks and lambdas", true); - void processLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackLambdaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, lambdas, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } @@ -225,7 +227,7 @@ struct FemtoPairTrackV0 { } PROCESS_SWITCH(FemtoPairTrackV0, processLambdaMixedEvent, "Enable processing mixed event processing for tracks and lambdas", true); - void processLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambas*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackLambdaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } @@ -237,7 +239,7 @@ struct FemtoPairTrackV0 { } PROCESS_SWITCH(FemtoPairTrackV0, processK0shortSameEvent, "Enable processing same event processing for tracks and k0shorts", false); - void processK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackK0shortBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, k0shorts, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } @@ -249,16 +251,16 @@ struct FemtoPairTrackV0 { } PROCESS_SWITCH(FemtoPairTrackV0, processK0shortMixedEvent, "Enable processing mixed event processing for tracks and k0shorts", false); - void processK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { pairTrackK0shortBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackV0, processK0shortMixedEventMc, "Enable processing mixed event processing for tracks and k0shorts with mc information", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoPairV0V0.cxx b/PWGCF/Femto/Tasks/femtoPairV0V0.cxx index d1d8c045724..c901d2ec49f 100644 --- a/PWGCF/Femto/Tasks/femtoPairV0V0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairV0V0.cxx @@ -37,34 +37,35 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -#include +#include #include -using namespace o2; -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoPairV0V0 { // setup tables - using Collisions = Join; - using Collision = Collisions::iterator; + using FemtoCollisions = o2::soa::Join; + using FilteredFemtoCollisions = o2::soa::Filtered; + using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FilteredCollisions = o2::soa::Filtered; - using FilteredCollision = FilteredCollisions::iterator; + using FemtoCollisionsWithLabel = o2::soa::Join; + using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; + using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using Tracks = o2::soa::Join; - using Lambdas = o2::soa::Join; - using K0shorts = o2::soa::Join; + using FemtoTracks = o2::soa::Join; + using FemtoLambdas = o2::soa::Join; + using FemtoK0shorts = o2::soa::Join; - SliceCache cache; + using FemtoTracksWithLabel = o2::soa::Join; + using FemtoLambdasWithLabel = o2::soa::Join; + using FemtoK0shortsWithLabel = o2::soa::Join; + // + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; // setup for daughters @@ -75,15 +76,23 @@ struct FemtoPairV0V0 { v0builder::ConfLambdaSelection1 confLambdaSelection; particlecleaner::ConfLambdaCleaner1 confLambdaCleaner; v0histmanager::ConfLambdaBinning1 confLambdaBinning; - Partition lambdaPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); - Preslice perColLambdas = aod::femtobase::stored::fColId; + + o2::framework::Partition lambdaPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); + o2::framework::Preslice perColLambdas = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition lambdaWithLabelPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); + o2::framework::Preslice perCollambdasWithLabel = o2::aod::femtobase::stored::fColId; // setup k0shorts v0builder::ConfK0shortSelection1 confK0shortSelection; particlecleaner::ConfK0shortCleaner1 confK0shortCleaner; v0histmanager::ConfK0shortBinning1 confK0shortBinning; - Partition k0shortPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); - Preslice perColk0shorts = aod::femtobase::stored::fColId; + + o2::framework::Partition k0shortPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); + o2::framework::Preslice perColk0shorts = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition k0shortWithLabelPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); + o2::framework::Preslice perColk0shortsWithLabel = o2::aod::femtobase::stored::fColId; // setup pairs pairhistmanager::ConfPairBinning confPairBinning; @@ -127,22 +136,32 @@ struct FemtoPairV0V0 { std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; std::vector defaultCentBins{10, 0, 100}; - ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; - ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; - ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; pairhistmanager::ConfMixing confMixing; - HistogramRegistry hRegistry{"FemtoV0V0", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoV0V0", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; // setup cpr closepairrejection::ConfCprV0DaugherV0DaughterPos confCprPos; closepairrejection::ConfCprV0DaugherV0DaughterNeg confCprNeg; - void init(InitContext&) + void init(o2::framework::InitContext&) { + // TODO: implement lambda-k0short + bool processData = doprocessLambdaLambdaSameEvent || doprocessLambdaLambdaSameEvent || doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortSameEvent; + bool processMc = doprocessLambdaLambdaSameEventMc || doprocessLambdaLambdaSameEventMc || doprocessK0shortK0shortSameEventMc || doprocessK0shortK0shortSameEventMc; - if (((doprocessLambdaLambdaSameEvent || doprocessLambdaLambdaMixedEvent) + (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent)) > 1) { - LOG(fatal) << "Can only process lambda-tracks Or k0short-tracks"; + if (processData && processMc) { + LOG(fatal) << "Both data and mc processing is enabled. Breaking..."; + } + + bool processLambdaLambda = doprocessLambdaLambdaSameEvent || doprocessLambdaLambdaMixedEvent || doprocessLambdaLambdaSameEventMc || doprocessLambdaLambdaMixedEventMc; + bool processK0shortK0short = doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent || doprocessK0shortK0shortSameEventMc || doprocessK0shortK0shortMixedEventMc; + + if (processLambdaLambda && processK0shortK0short) { + LOG(fatal) << "Both lambda-lambda and k0short-k0short processing is enabled. Breaking..."; } // setup columnpolicy for binning @@ -152,55 +171,103 @@ struct FemtoPairV0V0 { mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; // setup histograms - auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - auto posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); - auto negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); - auto cprHistSpecPos = closepairrejection::makeCprHistSpecMap(confCprPos); - auto cprHistSpecNeg = closepairrejection::makeCprHistSpecMap(confCprNeg); - - // setup for lambda - if (doprocessLambdaLambdaSameEvent || doprocessLambdaLambdaMixedEvent) { - auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); - auto pairLambdaLambdaHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); - pairLambdaLambdaBuilder.init(&hRegistry, confLambdaSelection, confLambdaSelection, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairLambdaLambdaHistSpec, cprHistSpecPos, cprHistSpecNeg); - } + std::map> colHistSpec; + std::map> trackHistSpec; + std::map> posDauSpec; + std::map> negDauSpec; + std::map> lambdaHistSpec; + std::map> k0shortHistSpec; + std::map> pairV0V0HistSpec; + std::map> cprHistSpecPos = closepairrejection::makeCprHistSpecMap(confCprPos); + std::map> cprHistSpecNeg = closepairrejection::makeCprHistSpecMap(confCprNeg); + + if (processData) { + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); + if (processLambdaLambda) { + lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); + pairV0V0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + pairLambdaLambdaBuilder.init(&hRegistry, confLambdaSelection, confLambdaSelection, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + } - // setup for k0short - if (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent) { - auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); - auto pairK0shortK0shortHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); - pairK0shortK0shortBuilder.init(&hRegistry, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairK0shortK0shortHistSpec, cprHistSpecPos, cprHistSpecNeg); + // setup for k0short + if (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent) { + k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); + pairV0V0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning); + pairK0shortK0shortBuilder.init(&hRegistry, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + } + } else { + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); + if (processLambdaLambda) { + lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); + pairV0V0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); + pairLambdaLambdaBuilder.init(&hRegistry, confLambdaSelection, confLambdaSelection, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + } + + // setup for k0short + if (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent) { + k0shortHistSpec = v0histmanager::makeV0McHistSpecMap(confK0shortBinning); + pairV0V0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning); + pairK0shortK0shortBuilder.init(&hRegistry, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + } } }; - void processLambdaLambdaSameEvent(FilteredCollision const& col, Tracks const& tracks, Lambdas const& lambdas) + void processLambdaLambdaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& lambdas) { pairLambdaLambdaBuilder.processSameEvent(col, tracks, lambdas, lambdaPartition, lambdaPartition, cache); } - PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaSameEvent, "Enable processing same event processing for lambdas", true); + PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaSameEvent, "Enable processing same event processing for lambda-lambda", true); + + void processLambdaLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairLambdaLambdaBuilder.processSameEvent(col, mcCols, tracks, lambdas, lambdaWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaSameEventMc, "Enable processing same event processing for lambda-lambda with mc information", false); + + void processLambdaLambdaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& lambdas) + { + pairLambdaLambdaBuilder.processMixedEvent(cols, tracks, lambdas, lambdaPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaMixedEvent, "Enable processing mixed event processing for lambda-lambda", true); + + void processLambdaLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairLambdaLambdaBuilder.processMixedEvent(cols, mcCols, tracks, lambdaWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaMixedEventMc, "Enable processing mixed event processing for lambda-lambda with mc information", false); + + void processK0shortK0shortSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& k0shorts) + { + pairK0shortK0shortBuilder.processSameEvent(col, tracks, k0shorts, k0shortPartition, k0shortPartition, cache); + } + PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortSameEvent, "Enable processing same event processing for k0short-k0short", false); - void processLambdaLambdaMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, Lambdas const& /*lambas*/) + void processK0shortK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairLambdaLambdaBuilder.processMixedEvent(cols, tracks, lambdaPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortK0shortBuilder.processSameEvent(col, mcCols, tracks, k0shorts, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } - PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaMixedEvent, "Enable processing mixed event processing for lambdas", true); + PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortSameEventMc, "Enable processing same event processing for k0short-k0short with mc information", false); - void processK0shortK0shortSameEvent(FilteredCollision const& col, Tracks const& tracks, K0shorts const& k0shorts) + void processK0shortK0shortMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoK0shorts const& k0shorts) { - pairK0shortK0shortBuilder.processSameEvent(col, tracks, k0shorts, k0shortPartition, lambdaPartition, cache); + pairK0shortK0shortBuilder.processMixedEvent(cols, tracks, k0shorts, k0shortPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } - PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortSameEvent, "Enable processing same event processing for lambdas", false); + PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortMixedEvent, "Enable processing mixed event processing for k0short-k0short", false); - void processK0shortK0shortMixedEvent(FilteredCollisions const& cols, Tracks const& tracks, K0shorts const& /*k0shorts*/) + void processK0shortK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairK0shortK0shortBuilder.processMixedEvent(cols, tracks, k0shortPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortK0shortBuilder.processMixedEvent(cols, mcCols, tracks, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } - PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortMixedEvent, "Enable processing mixed event processing for lambdas", false); + PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortMixedEventMc, "Enable processing mixed event processing for k0short-k0short with mc information", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index aa85a2c4d17..7a7c9ef046a 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -31,31 +31,31 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -using namespace o2::aod; -using namespace o2::framework; -using namespace o2::framework::expressions; +#include +#include + using namespace o2::analysis::femto; struct FemtoTrackQa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using FemtoTracks = o2::soa::Join; + using FemtoTracks = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; colhistmanager::ConfCollisionQaBinning confCollisionQaBinning; colhistmanager::CollisionHistManager colHistManager; @@ -66,52 +66,37 @@ struct FemtoTrackQa { trackhistmanager::ConfTrackQaBinning1 confTrackQaBinning; trackhistmanager::TrackHistManager trackHistManager; - Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); - Preslice perColReco = femtobase::stored::fColId; + o2::framework::Partition trackPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColReco = o2::aod::femtobase::stored::fColId; particlecleaner::ConfTrackCleaner1 confTrackCleaner; particlecleaner::ParticleCleaner trackCleaner; - Partition trackWithLabelPartition = MAKE_TRACK_PARTITION(confTrackSelection); - Preslice perColRecoWithLabel = femtobase::stored::fColId; - - HistogramRegistry hRegistry{"FemtoTrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::Partition trackWithLabelPartition = MAKE_TRACK_PARTITION(confTrackSelection); + o2::framework::Preslice perColRecoWithLabel = o2::aod::femtobase::stored::fColId; - template - void initMode(MakeColSpec&& makeColSpec, - MakeTrackSpec&& makeTrackSpec) - { - auto colHistSpec = makeColSpec(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto trackHistSpec = makeTrackSpec(confTrackBinning, confTrackQaBinning); - - trackHistManager.init( - &hRegistry, - trackHistSpec, - confTrackSelection.chargeAbs.value, - confTrackSelection.chargeSign.value, - confTrackSelection.pdgCodeAbs.value, - confTrackQaBinning); - } + o2::framework::HistogramRegistry hRegistry{"FemtoTrackQA", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(o2::framework::InitContext&) { if ((doprocessData + doprocessMc) > 1) { LOG(fatal) << "More than 1 process function is activated. Breaking..."; } bool processData = doprocessData; trackCleaner.init(confTrackCleaner); + + std::map> colHistSpec; + std::map> trackHistSpec; + if (processData) { - auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto trackHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confTrackBinning, confTrackQaBinning); + trackHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confTrackBinning, confTrackQaBinning); trackHistManager.init(&hRegistry, trackHistSpec, confTrackSelection, confTrackQaBinning); } else { - auto colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto trackHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confTrackBinning, confTrackQaBinning); + trackHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confTrackBinning, confTrackQaBinning); trackHistManager.init(&hRegistry, trackHistSpec, confTrackSelection, confTrackQaBinning); } hRegistry.print(); @@ -120,18 +105,17 @@ struct FemtoTrackQa { void processData(FilteredFemtoCollision const& col, FemtoTracks const& tracks) { colHistManager.fill(col); - auto trackSlice = trackPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto trackSlice = trackPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& track : trackSlice) { trackHistManager.fill(track, tracks); } }; PROCESS_SWITCH(FemtoTrackQa, processData, "Track QA in Data", true); - void processMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { colHistManager.fill(col, mcCols); - auto trackSlice = trackWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); - + auto trackSlice = trackWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& track : trackSlice) { if (!trackCleaner.isClean(track, mcParticles, mcMothers, mcPartonicMothers)) { continue; @@ -142,10 +126,10 @@ struct FemtoTrackQa { PROCESS_SWITCH(FemtoTrackQa, processMc, "Track QA in Monte Carlo", false); }; -WorkflowSpec - defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec + defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx index a7595e513d3..a1d0102366a 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file femtoTripletTrackTrackTrack.cxx -/// \brief Tasks that computes correlation between two tracks +/// \brief Tasks that computes correlation between three tracks /// \author Anton Riedel, TU München, anton.riedel@cern.ch #include "PWGCF/Femto/Core/closeTripletRejection.h" @@ -35,36 +35,31 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -#include +#include #include -using namespace o2; -using namespace o2::aod; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoTripletTrackTrackTrack { // setup tables - using FemtoCollisions = Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using FemtoTracks = o2::soa::Join; + using FemtoTracks = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::ConfCollisionBinning confCollisionBinning; // setup tracks @@ -75,15 +70,15 @@ struct FemtoTripletTrackTrackTrack { trackbuilder::ConfTrackSelection3 confTrackSelections3; trackhistmanager::ConfTrackBinning3 confTrackBinning3; - Partition trackPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); - Partition trackPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); - Partition trackPartition3 = MAKE_TRACK_PARTITION(confTrackSelections3); - Preslice perColtracks = aod::femtobase::stored::fColId; + o2::framework::Partition trackPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Partition trackPartition3 = MAKE_TRACK_PARTITION(confTrackSelections3); + o2::framework::Preslice perColtracks = o2::aod::femtobase::stored::fColId; - Partition trackWithLabelPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); - Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); - Partition trackWithLabelPartition3 = MAKE_TRACK_PARTITION(confTrackSelections3); - Preslice perColtracksWithLabel = aod::femtobase::stored::fColId; + o2::framework::Partition trackWithLabelPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Partition trackWithLabelPartition3 = MAKE_TRACK_PARTITION(confTrackSelections3); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; // setup triplets triplethistmanager::ConfTripletBinning confTripletBinning; @@ -109,14 +104,14 @@ struct FemtoTripletTrackTrackTrack { std::vector defaultVtxBins{10, -10, 10}; std::vector defaultMultBins{50, 0, 200}; std::vector defaultCentBins{10, 0, 100}; - ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; - ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; - ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; triplethistmanager::ConfMixing confMixing; - HistogramRegistry hRegistry{"FemtoTrackTrackTrack", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoTrackTrackTrack", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(o2::framework::InitContext&) { if ((doprocessSameEvent + doprocessSameEventMc) > 1 || (doprocessMixedEvent + doprocessMixedEventMc) > 1) { LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; @@ -134,21 +129,27 @@ struct FemtoTripletTrackTrackTrack { mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; // setup histogram specs - auto ctrHistSpec = closepairrejection::makeCprHistSpecMap(confCtr); + + std::map> colHistSpec; + std::map> trackHistSpec1; + std::map> trackHistSpec2; + std::map> trackHistSpec3; + std::map> tripletHistSpec; + std::map> ctrHistSpec = closepairrejection::makeCprHistSpecMap(confCtr); if (processData) { - auto colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); - auto trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); - auto trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); - auto trackHistSpec3 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning3); - auto tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning); + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); + trackHistSpec3 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning3); + tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning); tripletTrackTrackTrackBuilder.init(&hRegistry, confTrackSelections1, confTrackSelections2, confTrackSelections3, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, trackHistSpec3, tripletHistSpec, ctrHistSpec); } else { - auto colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); - auto trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); - auto trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); - auto trackHistSpec3 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning3); - auto tripletHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning); + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); + trackHistSpec3 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning3); + tripletHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning); tripletTrackTrackTrackBuilder.init(&hRegistry, confTrackSelections1, confTrackSelections2, confTrackSelections3, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, trackHistSpec3, tripletHistSpec, ctrHistSpec); } hRegistry.print(); @@ -160,7 +161,7 @@ struct FemtoTripletTrackTrackTrack { } PROCESS_SWITCH(FemtoTripletTrackTrackTrack, processSameEvent, "Enable processing same event processing", true); - void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { tripletTrackTrackTrackBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, trackWithLabelPartition3, mcParticles, mcMothers, mcPartonicMothers, cache); } @@ -172,16 +173,16 @@ struct FemtoTripletTrackTrackTrack { } PROCESS_SWITCH(FemtoTripletTrackTrackTrack, processMixedEvent, "Enable processing mixed event processing", true); - void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FMcParticles const& mcParticles) + void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles) { tripletTrackTrackTrackBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, trackWithLabelPartition3, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackTrack, processMixedEventMc, "Enable processing mixed event processing", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx new file mode 100644 index 00000000000..40ca91df199 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx @@ -0,0 +1,216 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// \file femtoTripletTrackTrackV0.cxx +/// \brief Tasks that computes correlation between two tracks +/// \author Anton Riedel, TU München, anton.riedel@cern.ch + +#include "PWGCF/Femto/Core/closeTripletRejection.h" +#include "PWGCF/Femto/Core/collisionBuilder.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/Core/trackBuilder.h" +#include "PWGCF/Femto/Core/trackHistManager.h" +#include "PWGCF/Femto/Core/tripletBuilder.h" +#include "PWGCF/Femto/Core/tripletHistManager.h" +#include "PWGCF/Femto/Core/v0Builder.h" +#include "PWGCF/Femto/Core/v0HistManager.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include "Framework/ASoA.h" +#include "Framework/AnalysisHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/BinningPolicy.h" +#include "Framework/Configurable.h" +#include "Framework/Expressions.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/InitContext.h" +#include "Framework/OutputObjHeader.h" +#include "Framework/runDataProcessing.h" + +#include +#include + +using namespace o2::analysis::femto; + +struct FemtoTripletTrackTrackV0 { + + // setup tables + using FemtoCollisions = o2::soa::Join; + using FilteredFemtoCollisions = o2::soa::Filtered; + using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; + + using FemtoCollisionsWithLabel = o2::soa::Join; + using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; + using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; + + // TODO also implement K0shorts + using FemtoTracks = o2::soa::Join; + using FemtoLambdas = o2::soa::Join; + // using FemtoK0shorts = o2::soa::Join; + + using FemtoTracksWithLabel = o2::soa::Join; + using FemtoLambdasWithLabel = o2::soa::Join; + // using FemtoK0shortsWithLabel = o2::soa::Join; + + o2::framework::SliceCache cache; + + // setup collisions + collisionbuilder::ConfCollisionSelection collisionSelection; + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + + // setup tracks + trackbuilder::ConfTrackSelection1 confTrackSelections1; + trackhistmanager::ConfTrackBinning1 confTrackBinning1; + trackbuilder::ConfTrackSelection2 confTrackSelections2; + trackhistmanager::ConfTrackBinning2 confTrackBinning2; + + o2::framework::Partition trackPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracks = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition trackWithLabelPartition1 = MAKE_TRACK_PARTITION(confTrackSelections1); + o2::framework::Partition trackWithLabelPartition2 = MAKE_TRACK_PARTITION(confTrackSelections2); + o2::framework::Preslice perColtracksWithLabel = o2::aod::femtobase::stored::fColId; + + // setup for daughters + trackhistmanager::ConfV0PosDauBinning confPosDauBinning; + trackhistmanager::ConfV0NegDauBinning confNegDauBinning; + + // setup lambdas + v0builder::ConfLambdaSelection1 confLambdaSelection; + v0histmanager::ConfLambdaBinning1 confLambdaBinning; + particlecleaner::ConfLambdaCleaner1 confLambdaCleaner; + + o2::framework::Partition lambdaPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); + o2::framework::Preslice perColLambdas = o2::aod::femtobase::stored::fColId; + + o2::framework::Partition lambdaWithLabelPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); + o2::framework::Preslice perColLambdasWithLabel = o2::aod::femtobase::stored::fColId; + + // setup triplets + triplethistmanager::ConfTripletBinning confTripletBinning; + triplethistmanager::ConfTripletCuts confTripletCuts; + + closetripletrejection::ConfCtrTrackTrackTrack confCtr; + + tripletbuilder::TripletTrackTrackV0Builder< + modes::V0::kLambda, + trackhistmanager::PrefixTrack1, + trackhistmanager::PrefixTrack2, + v0histmanager::PrefixLambda1, + trackhistmanager::PrefixV01PosDaughter, + trackhistmanager::PrefixV02NegDaughter, + triplethistmanager::PrefixTrackTrackLambdaSe, + triplethistmanager::PrefixTrackTrackLambdaMe, + closetripletrejection::PrefixTrack1Track2Se, + closetripletrejection::PrefixTrack1V0Se, + closetripletrejection::PrefixTrack2V0Se, + closetripletrejection::PrefixTrack1Track2Me, + closetripletrejection::PrefixTrack1V0Me, + closetripletrejection::PrefixTrack2V0Me> + tripletTrackTrackLambdaBuilder; + + // setup mixing + std::vector defaultVtxBins{10, -10, 10}; + std::vector defaultMultBins{50, 0, 200}; + std::vector defaultCentBins{10, 0, 100}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + triplethistmanager::ConfMixing confMixing; + + o2::framework::HistogramRegistry hRegistry{"FemtoTrackTrackTrack", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + if ((doprocessSameEvent + doprocessSameEventMc) > 1 || (doprocessMixedEvent + doprocessMixedEventMc) > 1) { + LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; + } + bool processData = doprocessSameEvent || doprocessMixedEvent; + bool processMc = doprocessSameEventMc || doprocessMixedEventMc; + if (processData && processMc) { + LOG(fatal) << "Both data and mc processing is activated. Breaking..."; + } + + // setup columnpolicy for binning + // default values are used during instantiation, so we need to explicity update them here + mixBinsVtxMult = {{confMixing.vtxBins, confMixing.multBins.value}, true}; + mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; + mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; + + // setup histogram specs + std::map> colHistSpec; + std::map> trackHistSpec1; + std::map> trackHistSpec2; + + std::map> posDauSpec; + std::map> negDauSpec; + std::map> lambdaHistSpec; + std::map> tripletHistSpec; + std::map> ctrHistSpec = closepairrejection::makeCprHistSpecMap(confCtr); + + if (processData) { + colHistSpec = colhistmanager::makeColHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); + lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); + posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); + tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning); + tripletTrackTrackLambdaBuilder.init(&hRegistry, confTrackSelections1, confTrackSelections2, confLambdaSelection, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, lambdaHistSpec, posDauSpec, negDauSpec, tripletHistSpec, ctrHistSpec); + } else { + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); + trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); + lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); + posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); + negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); + tripletHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning); + tripletTrackTrackLambdaBuilder.init(&hRegistry, confTrackSelections1, confTrackSelections2, confLambdaSelection, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, lambdaHistSpec, posDauSpec, negDauSpec, tripletHistSpec, ctrHistSpec); + } + hRegistry.print(); + }; + + void processSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/) + { + tripletTrackTrackLambdaBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, lambdaPartition, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackV0, processSameEvent, "Enable processing same event processing", true); + + void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdas const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + tripletTrackTrackLambdaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + } + PROCESS_SWITCH(FemtoTripletTrackTrackV0, processSameEventMc, "Enable processing same event processing", false); + + void processMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/) + { + tripletTrackTrackLambdaBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackV0, processMixedEvent, "Enable processing mixed event processing", true); + + void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdas const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles) + { + tripletTrackTrackLambdaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, lambdaWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoTripletTrackTrackV0, processMixedEventMc, "Enable processing mixed event processing", false); +}; + +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +{ + o2::framework::WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/Femto/Tasks/femtoV0Qa.cxx b/PWGCF/Femto/Tasks/femtoV0Qa.cxx index bfe3c56d588..52448e25f56 100644 --- a/PWGCF/Femto/Tasks/femtoV0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoV0Qa.cxx @@ -33,38 +33,35 @@ #include "Framework/OutputObjHeader.h" #include "Framework/runDataProcessing.h" -#include +#include #include -using namespace o2::aod; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoV0Qa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoCollisionsWithLabel = o2::soa::Join; + using FemtoCollisionsWithLabel = o2::soa::Join; using FilteredFemtoCollisionsWithLabel = o2::soa::Filtered; using FilteredFemtoCollisionWithLabel = FilteredFemtoCollisionsWithLabel::iterator; - using FemtoLambdas = o2::soa::Join; - using FemtoK0shorts = o2::soa::Join; - using FemtoTracks = o2::soa::Join; + using FemtoLambdas = o2::soa::Join; + using FemtoK0shorts = o2::soa::Join; + using FemtoTracks = o2::soa::Join; - using FemtoLambdasWithLabel = o2::soa::Join; - using FemtoK0shortsWithLabel = o2::soa::Join; - using FemtoTracksWithLabel = o2::soa::Join; + using FemtoLambdasWithLabel = o2::soa::Join; + using FemtoK0shortsWithLabel = o2::soa::Join; + using FemtoTracksWithLabel = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup for collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; colhistmanager::ConfCollisionQaBinning confCollisionQaBinning; @@ -73,11 +70,11 @@ struct FemtoV0Qa { particlecleaner::ConfLambdaCleaner1 confLambdaCleaner; v0builder::ConfLambdaSelection1 confLambdaSelection; - Partition lambdaPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); - Preslice perColLambdas = femtobase::stored::fColId; + o2::framework::Partition lambdaPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); + o2::framework::Preslice perColLambdas = o2::aod::femtobase::stored::fColId; - Partition lambdaWithLabelPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); - Preslice perColLambdasWithLabel = femtobase::stored::fColId; + o2::framework::Partition lambdaWithLabelPartition = MAKE_LAMBDA_PARTITION(confLambdaSelection); + o2::framework::Preslice perColLambdasWithLabel = o2::aod::femtobase::stored::fColId; particlecleaner::ParticleCleaner lambdaCleaner; @@ -94,11 +91,11 @@ struct FemtoV0Qa { particlecleaner::ConfK0shortCleaner1 confK0shortCleaner; v0builder::ConfK0shortSelection1 confK0shortSelection; - Partition k0shortPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); - Preslice perColK0shorts = femtobase::stored::fColId; + o2::framework::Partition k0shortPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); + o2::framework::Preslice perColK0shorts = o2::aod::femtobase::stored::fColId; - Partition k0shortWithLabelPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); - Preslice perColK0shortsWithLabel = femtobase::stored::fColId; + o2::framework::Partition k0shortWithLabelPartition = MAKE_K0SHORT_PARTITION(confK0shortSelection); + o2::framework::Preslice perColK0shortsWithLabel = o2::aod::femtobase::stored::fColId; particlecleaner::ParticleCleaner k0shortCleaner; @@ -118,9 +115,9 @@ struct FemtoV0Qa { trackhistmanager::ConfV0NegDauBinning confV0NegDaughterBinning; trackhistmanager::ConfV0NegDauQaBinning confV0NegDaughterQaBinning; - HistogramRegistry hRegistry{"FemtoV0Qa", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoV0Qa", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(o2::framework::InitContext&) { if ((doprocessLambda + doprocessLambdaMc + doprocessK0short + doprocessK0shortMc) > 1) { LOG(fatal) << "Only one process can be activated"; @@ -129,30 +126,37 @@ struct FemtoV0Qa { lambdaCleaner.init(confLambdaCleaner); k0shortCleaner.init(confK0shortCleaner); + + std::map> colHistSpec; + std::map> posDaughterHistSpec; + std::map> negDaughterHistSpec; + std::map> lambdaHistSpec; + std::map> k0shortHistSpec; + if (processData) { - auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); - auto negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); + posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); + negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); if (doprocessLambda) { - auto lambdaHistSpec = v0histmanager::makeV0QaHistSpecMap(confLambdaBinning, confLambdaQaBinning); + lambdaHistSpec = v0histmanager::makeV0QaHistSpecMap(confLambdaBinning, confLambdaQaBinning); lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaSelection, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } if (doprocessK0short) { - auto k0shortHistSpec = v0histmanager::makeV0QaHistSpecMap(confK0shortBinning, confK0shortQaBinning); + k0shortHistSpec = v0histmanager::makeV0QaHistSpecMap(confK0shortBinning, confK0shortQaBinning); k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortSelection, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } } else { - auto colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); + colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); colHistManager.init(&hRegistry, colHistSpec, confCollisionQaBinning); - auto posDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); - auto negDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); + posDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); + negDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); if (doprocessLambdaMc) { - auto lambdaHistSpec = v0histmanager::makeV0McQaHistSpecMap(confLambdaBinning, confLambdaQaBinning); + lambdaHistSpec = v0histmanager::makeV0McQaHistSpecMap(confLambdaBinning, confLambdaQaBinning); lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaSelection, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } if (doprocessK0shortMc) { - auto k0shortHistSpec = v0histmanager::makeV0McQaHistSpecMap(confK0shortBinning, confK0shortQaBinning); + k0shortHistSpec = v0histmanager::makeV0McQaHistSpecMap(confK0shortBinning, confK0shortQaBinning); k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortSelection, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } } @@ -162,17 +166,17 @@ struct FemtoV0Qa { void processK0short(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/) { colHistManager.fill(col); - auto k0shortSlice = k0shortPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto k0shortSlice = k0shortPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& k0short : k0shortSlice) { k0shortHistManager.fill(k0short, tracks); } } PROCESS_SWITCH(FemtoV0Qa, processK0short, "Process k0shorts", false); - void processK0shortMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processK0shortMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { colHistManager.fill(col, mcCols); - auto k0shortSlice = k0shortWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto k0shortSlice = k0shortWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& k0short : k0shortSlice) { if (!k0shortCleaner.isClean(k0short, mcParticles, mcMothers, mcPartonicMothers)) { continue; @@ -185,17 +189,17 @@ struct FemtoV0Qa { void processLambda(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/) { colHistManager.fill(col); - auto lambdaSlice = lambdaPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto lambdaSlice = lambdaPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& lambda : lambdaSlice) { lambdaHistManager.fill(lambda, tracks); } } PROCESS_SWITCH(FemtoV0Qa, processLambda, "Process lambdas", true); - void processLambdaMc(FilteredFemtoCollisionWithLabel const& col, FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, FMcParticles const& mcParticles, FMcMothers const& mcMothers, FMcPartMoths const& mcPartonicMothers) + void processLambdaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { colHistManager.fill(col, mcCols); - auto lambdaSlice = lambdaWithLabelPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto lambdaSlice = lambdaWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); for (auto const& lambda : lambdaSlice) { if (!lambdaCleaner.isClean(lambda, mcParticles, mcMothers, mcPartonicMothers)) { continue; @@ -206,9 +210,9 @@ struct FemtoV0Qa { PROCESS_SWITCH(FemtoV0Qa, processLambdaMc, "Process lambdas", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { - WorkflowSpec workflow{ + o2::framework::WorkflowSpec workflow{ adaptAnalysisTask(cfgc), }; return workflow; diff --git a/PWGCF/Flow/TableProducer/zdcQVectors.cxx b/PWGCF/Flow/TableProducer/zdcQVectors.cxx index 9e902690923..217b62337f3 100644 --- a/PWGCF/Flow/TableProducer/zdcQVectors.cxx +++ b/PWGCF/Flow/TableProducer/zdcQVectors.cxx @@ -156,6 +156,7 @@ struct ZdcQVectors { O2_DEFINE_CONFIGURABLE(cfgFillHistRegistry, bool, true, "Fill common registry with histograms"); O2_DEFINE_CONFIGURABLE(cfgFillCutAnalysis, bool, true, "Fill cut analysis with histograms"); O2_DEFINE_CONFIGURABLE(cfgFillNothing, bool, false, "Disable ALL Histograms -> ONLY use to reduce memory"); + O2_DEFINE_CONFIGURABLE(cfgNoGain, bool, false, "Do not apply gain correction to ZDC energy calibration"); O2_DEFINE_CONFIGURABLE(cfgCCDBdir_Shift, std::string, "Users/c/ckoster/ZDC/LHC23_PbPb_pass5/Shift", "CCDB directory for Shift ZDC"); @@ -724,7 +725,6 @@ struct ZdcQVectors { std::vector centralities; auto cent = collision.centFT0C(); - centrality = cent; centralities.push_back(collision.centFT0C()); @@ -751,6 +751,7 @@ struct ZdcQVectors { v = {collision.posX(), collision.posY(), collision.posZ()}; cents = centralities; + centrality = cent; const auto& foundBC = collision.foundBC_as(); runnumber = foundBC.runNumber(); @@ -992,6 +993,22 @@ struct ZdcQVectors { } } + if (cfgFillHistRegistry && !cfgFillNothing) { + registry.get(HIST("QA/before/ZNA_Qx"))->Fill(Form("%d", runnumber), q[0]); + registry.get(HIST("QA/before/ZNA_Qy"))->Fill(Form("%d", runnumber), q[1]); + registry.get(HIST("QA/before/ZNC_Qx"))->Fill(Form("%d", runnumber), q[2]); + registry.get(HIST("QA/before/ZNC_Qy"))->Fill(Form("%d", runnumber), q[3]); + + registry.get(HIST("QA/before/ZNA_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[0]); + registry.get(HIST("QA/before/ZNA_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[1]); + registry.get(HIST("QA/before/ZNC_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[2]); + registry.get(HIST("QA/before/ZNC_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[3]); + } + + if (cfgNoGain) { + q = qNoEq; + } + if (cal.calibfilesLoaded[1]) { v[0] = v[0] - getCorrection(vnames[0].Data()); v[1] = v[1] - getCorrection(vnames[1].Data()); @@ -1008,18 +1025,6 @@ struct ZdcQVectors { std::vector qRec(q); - if (cfgFillHistRegistry && !cfgFillNothing) { - registry.get(HIST("QA/before/ZNA_Qx"))->Fill(Form("%d", runnumber), q[0]); - registry.get(HIST("QA/before/ZNA_Qy"))->Fill(Form("%d", runnumber), q[1]); - registry.get(HIST("QA/before/ZNC_Qx"))->Fill(Form("%d", runnumber), q[2]); - registry.get(HIST("QA/before/ZNC_Qy"))->Fill(Form("%d", runnumber), q[3]); - - registry.get(HIST("QA/before/ZNA_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[0]); - registry.get(HIST("QA/before/ZNA_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[1]); - registry.get(HIST("QA/before/ZNC_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[2]); - registry.get(HIST("QA/before/ZNC_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[3]); - } - if (cal.atIteration == 0) { if (isSelected && cfgFillHistRegistry) fillCommonRegistry(q[0], q[1], q[2], q[3], v, centrality); diff --git a/PWGCF/Flow/Tasks/flowZdcTask.cxx b/PWGCF/Flow/Tasks/flowZdcTask.cxx index 2875a2d7aa5..24aacde821e 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -202,9 +202,13 @@ struct FlowZdcTask { histos.add("ZNVsFT0A", ";T0A (#times 1/100);ZNA+ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNVsFT0C", ";T0C (#times 1/100);ZNA+ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); + histos.add("CommonZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC Common Energy;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); + histos.add("SectorZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC Sector Energy;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZPVsFT0A", ";T0A (#times 1/100);ZPA+ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPVsFT0C", ";T0C (#times 1/100);ZPA+ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPVsFT0M", ";T0A+T0C (#times 1/100);ZPA+ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); + histos.add("CommonZPVsFT0M", ";T0A+T0C (#times 1/100);ZPA+ZPC Common Energy;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); + histos.add("SectorZPVsFT0M", ";T0A+T0C (#times 1/100);ZPA+ZPC Sector Energy;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZNAVsFT0A", ";T0A (#times 1/100);ZNA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNAVsFT0C", ";T0C (#times 1/100);ZNA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNAVsFT0M", ";T0A+T0C (#times 1/100);ZNA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); @@ -279,6 +283,14 @@ struct FlowZdcTask { histos.add("ampZpa", ";ZPA Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); histos.add("ampZnc", ";ZNC Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); histos.add("ampZpc", ";ZPC Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("commonZna", ";ZNA Common;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("commonZpa", ";ZPA Common;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("commonZnc", ";ZNC Common;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("commonZpc", ";ZPC Common;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("sectorSumZna", ";ZNA Sector Sum;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("sectorSumZnc", ";ZNC Sector Sum;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("sectorSumZpa", ";ZPA Sector Sum;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("sectorSumZpc", ";ZPC Sector Sum;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); histos.add("ampZEM1", ";ZEM1 Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZem}}); histos.add("ampZEM2", ";ZEM2 Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZem}}); histos.add("ZnVsZem", "ZnVsZEM; ZEM; ZNA + ZNC", kTH2F, {{{nBinsZDC, -0.5, maxZem}, {nBinsZDC, -0.5, maxZn}}}); @@ -428,26 +440,30 @@ struct FlowZdcTask { float znC = zdc.amplitudeZNC() / cfgCollisionEnergy; float zpA = zdc.amplitudeZPA() / cfgCollisionEnergy; float zpC = zdc.amplitudeZPC() / cfgCollisionEnergy; + float commonSumZnc = zdc.energyCommonZNC() / cfgCollisionEnergy; + float commonSumZna = zdc.energyCommonZNA() / cfgCollisionEnergy; + float commonSumZpc = zdc.energyCommonZPC() / cfgCollisionEnergy; + float commonSumZpa = zdc.energyCommonZPA() / cfgCollisionEnergy; + float sumZNC = ((zdc.energySectorZNC())[0] + (zdc.energySectorZNC())[1] + (zdc.energySectorZNC())[2] + (zdc.energySectorZNC())[3]) / cfgCollisionEnergy; + float sumZNA = ((zdc.energySectorZNA())[0] + (zdc.energySectorZNA())[1] + (zdc.energySectorZNA())[2] + (zdc.energySectorZNA())[3]) / cfgCollisionEnergy; + float sumZPC = ((zdc.energySectorZPC())[0] + (zdc.energySectorZPC())[1] + (zdc.energySectorZPC())[2] + (zdc.energySectorZPC())[3]) / cfgCollisionEnergy; + float sumZPA = ((zdc.energySectorZPA())[0] + (zdc.energySectorZPA())[1] + (zdc.energySectorZPA())[2] + (zdc.energySectorZPA())[3]) / cfgCollisionEnergy; if (applyZdcCorrection) { const float a = zpaCoeff; const float b = zpcCoeff; zpA = zpA - a * znA; + commonSumZpa = commonSumZpa - a * commonSumZna; + sumZPA = sumZPA - a * sumZNA; zpC = zpC - b * znC; + commonSumZpc = commonSumZpc - b * commonSumZnc; + sumZPC = sumZPC - b * sumZNC; } - float commonSumZnc = zdc.energyCommonZNC() / cfgCollisionEnergy; - float commonSumZna = zdc.energyCommonZNA() / cfgCollisionEnergy; - float commonSumZpc = zdc.energyCommonZPC() / cfgCollisionEnergy; - float commonSumZpa = zdc.energyCommonZPA() / cfgCollisionEnergy; float aZEM1{zdc.amplitudeZEM1()}; float aZEM2{zdc.amplitudeZEM2()}; float sumZEMs{aZEM1 + aZEM2}; float tZEM1{zdc.timeZEM1()}; float tZEM2{zdc.timeZEM2()}; float sumZNs{znA + znC}; - float sumZNC = ((zdc.energySectorZNC())[0] + (zdc.energySectorZNC())[1] + (zdc.energySectorZNC())[2] + (zdc.energySectorZNC())[3]) / cfgCollisionEnergy; - float sumZNA = ((zdc.energySectorZNA())[0] + (zdc.energySectorZNA())[1] + (zdc.energySectorZNA())[2] + (zdc.energySectorZNA())[3]) / cfgCollisionEnergy; - float sumZPC = ((zdc.energySectorZPC())[0] + (zdc.energySectorZPC())[1] + (zdc.energySectorZPC())[2] + (zdc.energySectorZPC())[3]) / cfgCollisionEnergy; - float sumZPA = ((zdc.energySectorZPA())[0] + (zdc.energySectorZPA())[1] + (zdc.energySectorZPA())[2] + (zdc.energySectorZPA())[3]) / cfgCollisionEnergy; float sumSectZN = (sumZNC + sumZNA); float sumSectZP = (sumZPC + sumZPA); @@ -492,12 +508,16 @@ struct FlowZdcTask { histos.fill(HIST("ZN"), znA + znC); histos.fill(HIST("ZNVsFT0C"), aT0C / 100., znA + znC); histos.fill(HIST("ZNVsFT0M"), (aT0A + aT0C) / 100., znA + znC); + histos.fill(HIST("CommonZNVsFT0M"), (aT0A + aT0C) / 100., commonSumZna + commonSumZnc); + histos.fill(HIST("SectorZNVsFT0M"), (aT0A + aT0C) / 100., sumZNA + sumZNC); } - if (((tZPA >= minTdcZn) && (tZPA <= maxTdcZn)) && ((tZPC >= minTdcZn) && (tZPC <= maxTdcZn))) { + if (((tZPA >= minTdcZp) && (tZPA <= maxTdcZp)) && ((tZPC >= minTdcZp) && (tZPC <= maxTdcZp))) { histos.fill(HIST("ZPAVsZPC"), zpC, zpA); histos.fill(HIST("ZPVsFT0A"), aT0A / 100., zpA + zpC); histos.fill(HIST("ZPVsFT0C"), aT0C / 100., zpA + zpC); histos.fill(HIST("ZPVsFT0M"), (aT0A + aT0C) / 100., zpA + zpC); + histos.fill(HIST("CommonZPVsFT0M"), (aT0A + aT0C) / 100., commonSumZpa + commonSumZpc); + histos.fill(HIST("SectorZPVsFT0M"), (aT0A + aT0C) / 100., sumZPA + sumZPC); } if (((tZNA >= minTdcZn) && (tZNA <= maxTdcZn)) && ((tZPA >= minTdcZp) && (tZPA <= maxTdcZp))) histos.fill(HIST("ZNAVsZPA"), zpA, znA); @@ -525,11 +545,15 @@ struct FlowZdcTask { histos.fill(HIST("ZPVsFT0A"), aT0A / 100., zpA + zpC); histos.fill(HIST("ZPVsFT0C"), aT0C / 100., zpA + zpC); histos.fill(HIST("ZPVsFT0M"), (aT0A + aT0C) / 100., zpA + zpC); + histos.fill(HIST("CommonZPVsFT0M"), (aT0A + aT0C) / 100., commonSumZpa + commonSumZpc); + histos.fill(HIST("SectorZPVsFT0M"), (aT0A + aT0C) / 100., sumZPA + sumZPC); histos.fill(HIST("ZPAVsFT0A"), aT0A / 100., zpA); histos.fill(HIST("ZPAVsFT0C"), aT0C / 100., zpA); histos.fill(HIST("ZPAVsFT0M"), (aT0A + aT0C) / 100., zpA); histos.fill(HIST("ZNVsFT0C"), aT0C / 100., znA + znC); histos.fill(HIST("ZNVsFT0M"), (aT0A + aT0C) / 100., znA + znC); + histos.fill(HIST("CommonZNVsFT0M"), (aT0A + aT0C) / 100., commonSumZna + commonSumZnc); + histos.fill(HIST("SectorZNVsFT0M"), (aT0A + aT0C) / 100., sumZNA + sumZNC); histos.fill(HIST("ZPCVsFT0A"), aT0A / 100., zpC); histos.fill(HIST("ZPCVsFT0C"), aT0C / 100., zpC); histos.fill(HIST("ZPCVsFT0M"), (aT0A + aT0C) / 100., zpC); @@ -674,10 +698,10 @@ struct FlowZdcTask { auto znC = zdc.amplitudeZNC() / cfgCollisionEnergy; auto zpA = zdc.amplitudeZPA() / cfgCollisionEnergy; auto zpC = zdc.amplitudeZPC() / cfgCollisionEnergy; - float sumZNC = ((zdc.energySectorZNC())[0] + (zdc.energySectorZNC())[1] + (zdc.energySectorZNC())[2] + (zdc.energySectorZNC())[3]) / cfgCollisionEnergy; - float sumZNA = ((zdc.energySectorZNA())[0] + (zdc.energySectorZNA())[1] + (zdc.energySectorZNA())[2] + (zdc.energySectorZNA())[3]) / cfgCollisionEnergy; - float sumZPC = ((zdc.energySectorZPC())[0] + (zdc.energySectorZPC())[1] + (zdc.energySectorZPC())[2] + (zdc.energySectorZPC())[3]) / cfgCollisionEnergy; - float sumZPA = ((zdc.energySectorZPA())[0] + (zdc.energySectorZPA())[1] + (zdc.energySectorZPA())[2] + (zdc.energySectorZPA())[3]) / cfgCollisionEnergy; + float sectorSumZNC = ((zdc.energySectorZNC())[0] + (zdc.energySectorZNC())[1] + (zdc.energySectorZNC())[2] + (zdc.energySectorZNC())[3]) / cfgCollisionEnergy; + float sectorSumZNA = ((zdc.energySectorZNA())[0] + (zdc.energySectorZNA())[1] + (zdc.energySectorZNA())[2] + (zdc.energySectorZNA())[3]) / cfgCollisionEnergy; + float sectorSumZPC = ((zdc.energySectorZPC())[0] + (zdc.energySectorZPC())[1] + (zdc.energySectorZPC())[2] + (zdc.energySectorZPC())[3]) / cfgCollisionEnergy; + float sectorSumZPA = ((zdc.energySectorZPA())[0] + (zdc.energySectorZPA())[1] + (zdc.energySectorZPA())[2] + (zdc.energySectorZPA())[3]) / cfgCollisionEnergy; float commonSumZnc = zdc.energyCommonZNC() / cfgCollisionEnergy; float commonSumZna = zdc.energyCommonZNA() / cfgCollisionEnergy; float commonSumZpc = zdc.energyCommonZPC() / cfgCollisionEnergy; @@ -690,14 +714,26 @@ struct FlowZdcTask { auto tZPA = zdc.timeZPA(); auto tZPC = zdc.timeZPC(); if (isTDCcut) { - if ((tZNA >= minTdcZn) && (tZNA <= maxTdcZn)) + if ((tZNA >= minTdcZn) && (tZNA <= maxTdcZn)) { histos.fill(HIST("ampZna"), znA); - if ((tZNC >= minTdcZn) && (tZNC <= maxTdcZn)) + histos.fill(HIST("commonZna"), commonSumZna); + histos.fill(HIST("sectorSumZna"), sectorSumZNA); + } + if ((tZNC >= minTdcZn) && (tZNC <= maxTdcZn)) { histos.fill(HIST("ampZnc"), znC); - if ((tZPA >= minTdcZp) && (tZPA <= maxTdcZp)) + histos.fill(HIST("commonZnc"), commonSumZnc); + histos.fill(HIST("sectorSumZnc"), sectorSumZNC); + } + if ((tZPA >= minTdcZp) && (tZPA <= maxTdcZp)) { histos.fill(HIST("ampZpa"), zpA); - if ((tZPC >= minTdcZp) && (tZPC <= maxTdcZp)) + histos.fill(HIST("commonZpa"), commonSumZpa); + histos.fill(HIST("sectorSumZpa"), sectorSumZPA); + } + if ((tZPC >= minTdcZp) && (tZPC <= maxTdcZp)) { histos.fill(HIST("ampZpc"), zpC); + histos.fill(HIST("commonZpc"), commonSumZpc); + histos.fill(HIST("sectorSumZpc"), sectorSumZPC); + } if (((tZNC >= minTdcZn) && (tZNC <= maxTdcZn)) && ((tZNA >= minTdcZn) && (tZNA <= maxTdcZn))) histos.fill(HIST("ZnVsZem"), sumZEMs, znC + znA); if (((tZNC >= minTdcZn) && (tZNC <= maxTdcZn)) && ((tZNA >= minTdcZn) && (tZNA <= maxTdcZn))) @@ -713,6 +749,14 @@ struct FlowZdcTask { histos.fill(HIST("ampZnc"), znC); histos.fill(HIST("ampZpa"), zpA); histos.fill(HIST("ampZpc"), zpC); + histos.fill(HIST("commonZna"), commonSumZna); + histos.fill(HIST("commonZnc"), commonSumZnc); + histos.fill(HIST("commonZpa"), commonSumZpa); + histos.fill(HIST("commonZpc"), commonSumZpc); + histos.fill(HIST("sectorSumZna"), sectorSumZNA); + histos.fill(HIST("sectorSumZnc"), sectorSumZNC); + histos.fill(HIST("sectorSumZpa"), sectorSumZPA); + histos.fill(HIST("sectorSumZpc"), sectorSumZPC); histos.fill(HIST("ZnVsZem"), sumZEMs, znC + znA); histos.fill(HIST("ZnaVsZnc"), znA, znC); histos.fill(HIST("ZpaVsZpc"), zpA, zpC); @@ -721,10 +765,10 @@ struct FlowZdcTask { } histos.fill(HIST("ampZEM1"), aZEM1); histos.fill(HIST("ampZEM2"), aZEM2); - histos.fill(HIST("ZnccVsZncSum"), sumZNC, commonSumZnc); - histos.fill(HIST("ZnacVsZnaSum"), sumZNA, commonSumZna); - histos.fill(HIST("ZpccVsZpcSum"), sumZPC, commonSumZpc); - histos.fill(HIST("ZpacVsZpaSum"), sumZPA, commonSumZpa); + histos.fill(HIST("ZnccVsZncSum"), sectorSumZNC, commonSumZnc); + histos.fill(HIST("ZnacVsZnaSum"), sectorSumZNA, commonSumZna); + histos.fill(HIST("ZpccVsZpcSum"), sectorSumZPC, commonSumZpc); + histos.fill(HIST("ZpacVsZpaSum"), sectorSumZPA, commonSumZpa); histos.fill(HIST("ZncVsTdc"), zdc.timeZNC(), znC); histos.fill(HIST("ZnaVsTdc"), zdc.timeZNA(), znA); histos.fill(HIST("ZpcVsTdc"), zdc.timeZPC(), zpC); diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 30ee366d842..7eac6bb8cf8 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -3709,6 +3709,92 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + //--------------------------------------------------------------- + // ALICE 3 studies composite cuts + + if (!nameStr.compare("alice3StandardKine")) { + cut->AddCut(GetAnalysisCut("alice3StandardKine")); + return cut; + } + + if (!nameStr.compare("alice3KineSkim")) { + cut->AddCut(GetAnalysisCut("alice3KineSkim")); + return cut; + } + + if (!nameStr.compare("alice3TrackQuality")) { + cut->AddCut(GetAnalysisCut("alice3TrackQuality")); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDEl")) { + cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDPi")) { + cut->AddCut(GetAnalysisCut("alice3iTOFPIDPi")); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDKa")) { + cut->AddCut(GetAnalysisCut("alice3iTOFPIDKa")); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDPr")) { + cut->AddCut(GetAnalysisCut("alice3iTOFPIDPr")); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDEl")) { + cut->AddCut(GetAnalysisCut("alice3oTOFPIDEl")); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDPi")) { + cut->AddCut(GetAnalysisCut("alice3oTOFPIDPi")); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDKa")) { + cut->AddCut(GetAnalysisCut("alice3oTOFPIDKa")); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDPr")) { + cut->AddCut(GetAnalysisCut("alice3oTOFPIDPr")); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDEl")) { + cut->AddCut(GetAnalysisCut("alice3RICHPIDEl")); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDPi")) { + cut->AddCut(GetAnalysisCut("alice3RICHPIDPi")); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDKa")) { + cut->AddCut(GetAnalysisCut("alice3RICHPIDKa")); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDPr")) { + cut->AddCut(GetAnalysisCut("alice3RICHPIDPr")); + return cut; + } + + if (!nameStr.compare("alice3DielectronPID")) { + cut->AddCut(GetAnalysisCut("alice3StandardKine")); + cut->AddCut(GetAnalysisCut("alice3TrackQuality")); + cut->AddCut(GetAnalysisCut("alice3RICHPIDEl")); + cut->AddCut(GetAnalysisCut("alice3RICHPIDPiPrRejection")); + return cut; + } + delete cut; LOGF(fatal, Form("Did not find cut %s. Returning nullptr", cutName)); return nullptr; @@ -6750,6 +6836,122 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + //--------------------------------------------------------------- + // ALICE 3 Analysis Cuts + + if (!nameStr.compare("alice3KineSkim")) { + cut->AddCut(VarManager::kPt, 0.05, 1000.0); + cut->AddCut(VarManager::kEta, -4.0, 4.0); + return cut; + } + + if (!nameStr.compare("alice3StandardKine")) { + cut->AddCut(VarManager::kPt, 0.1, 1000.0); + cut->AddCut(VarManager::kEta, -1.75, 1.75); // Value taken from LoI + return cut; + } + + if (!nameStr.compare("alice3TrackQuality")) { + cut->AddCut(VarManager::kTrackDCAxy, -1.0, 1.0); + cut->AddCut(VarManager::kTrackDCAz, -1.0, 1.0); + return cut; + } + + if (!nameStr.compare("alice3OTPIDEl")) { + cut->AddCut(VarManager::kOTnSigmaEl, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3OTPIDPi")) { + cut->AddCut(VarManager::kOTnSigmaPi, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3OTPIDKa")) { + cut->AddCut(VarManager::kOTnSigmaKa, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3OTPIDPr")) { + cut->AddCut(VarManager::kOTnSigmaPr, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDEl")) { + cut->AddCut(VarManager::kInnerTOFnSigmaEl, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDPi")) { + cut->AddCut(VarManager::kInnerTOFnSigmaPi, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDKa")) { + cut->AddCut(VarManager::kInnerTOFnSigmaKa, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3iTOFPIDPr")) { + cut->AddCut(VarManager::kInnerTOFnSigmaPr, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDEl")) { + cut->AddCut(VarManager::kOuterTOFnSigmaEl, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDEl")) { + cut->AddCut(VarManager::kOuterTOFnSigmaEl, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDPi")) { + cut->AddCut(VarManager::kOuterTOFnSigmaPi, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDKa")) { + cut->AddCut(VarManager::kOuterTOFnSigmaKa, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3oTOFPIDPr")) { + cut->AddCut(VarManager::kOuterTOFnSigmaPr, -3.0, 3.0); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDEl")) { + cut->AddCut(VarManager::kRICHnSigmaEl, -3.0, 3.0); + cut->AddCut(VarManager::kHasRICHSigEl, 0.5, 1.5); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDPi")) { + cut->AddCut(VarManager::kRICHnSigmaPi, -3.0, 3.0); + cut->AddCut(VarManager::kHasRICHSigPi, 0.5, 1.5); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDKa")) { + cut->AddCut(VarManager::kRICHnSigmaKa, -3.0, 3.0); + cut->AddCut(VarManager::kHasRICHSigKa, 0.5, 1.5); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDPr")) { + cut->AddCut(VarManager::kRICHnSigmaPr, -3.0, 3.0); + cut->AddCut(VarManager::kHasRICHSigPr, 0.5, 1.5); + return cut; + } + + if (!nameStr.compare("alice3RICHPIDPiPrRejection")) { + cut->AddCut(VarManager::kRICHnSigmaPi, -3.0, 3.0, true); + cut->AddCut(VarManager::kRICHnSigmaPr, -3.0, 3.0, true); + return cut; + } + delete cut; LOGF(fatal, Form("Did not find cut %s", cutName)); return nullptr; diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index 57972176bdc..86d6767ebb3 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -1413,6 +1413,118 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kBBFDDCpf] = ""; fgVariableNames[kBGFDDCpf] = "FDDC BG pileup flag"; fgVariableUnits[kBGFDDCpf] = ""; + fgVariableNames[kMultDensity] = "dNdeta ALICE3"; + fgVariableUnits[kMultDensity] = ""; + fgVariableNames[kMultMCNParticlesEta40] = "Multiplicity_eta40"; + fgVariableUnits[kMultMCNParticlesEta40] = ""; + fgVariableNames[kMultMCNParticlesEta20] = "Multiplicity_eta20"; + fgVariableUnits[kMultMCNParticlesEta20] = ""; + fgVariableNames[kIsReconstructed] = "is track reconstructed"; + fgVariableUnits[kIsReconstructed] = ""; + fgVariableNames[kNSiliconHits] = "Number of hits in silicon layers"; + fgVariableUnits[kNSiliconHits] = ""; + fgVariableNames[kNTPCHits] = "Number of TPC hits"; + fgVariableUnits[kNTPCHits] = ""; + fgVariableNames[kOTTOTSignal] = "time over threshold signal in OT"; + fgVariableUnits[kOTTOTSignal] = ""; + fgVariableNames[kOTnSigmaEl] = "n #sigma_{e}^{OT}"; + fgVariableUnits[kOTnSigmaEl] = ""; + fgVariableNames[kOTnSigmaMu] = "n #sigma_{Mu}^{OT}"; + fgVariableUnits[kOTnSigmaMu] = ""; + fgVariableNames[kOTnSigmaPi] = "n #sigma_{Pi}^{OT}"; + fgVariableUnits[kOTnSigmaPi] = ""; + fgVariableNames[kOTnSigmaKa] = "n #sigma_{Ka}^{OT}"; + fgVariableUnits[kOTnSigmaKa] = ""; + fgVariableNames[kOTnSigmaPr] = "n #sigma_{Pr}^{OT}"; + fgVariableUnits[kOTnSigmaPr] = ""; + fgVariableNames[kOTnSigmaDe] = "n #sigma_{De}^{OT}"; + fgVariableUnits[kOTnSigmaDe] = ""; + fgVariableNames[kOTnSigmaTr] = "n #sigma_{Tr}^{OT}"; + fgVariableUnits[kOTnSigmaTr] = ""; + fgVariableNames[kOTnSigmaHe3] = "n #sigma_{He3}^{OT}"; + fgVariableUnits[kOTnSigmaHe3] = ""; + fgVariableNames[kOTnSigmaAl] = "n #sigma_{Al}^{OT}"; + fgVariableUnits[kOTnSigmaAl] = ""; + fgVariableNames[kHasRICHSig] = "Has signal in RICH barrel"; + fgVariableUnits[kHasRICHSig] = ""; + fgVariableNames[kHasRICHSigInGas] = "Has signal in RICH gas radiator"; + fgVariableUnits[kHasRICHSigInGas] = ""; + fgVariableNames[kHasRICHSigEl] = "Has El signal in RICH"; + fgVariableUnits[kHasRICHSigEl] = ""; + fgVariableNames[kHasRICHSigMu] = "Has Mu signal in RICH"; + fgVariableUnits[kHasRICHSigMu] = ""; + fgVariableNames[kHasRICHSigPi] = "Has Pi signal in RICH"; + fgVariableUnits[kHasRICHSigPi] = ""; + fgVariableNames[kHasRICHSigKa] = "Has Ka signal in RICH"; + fgVariableUnits[kHasRICHSigKa] = ""; + fgVariableNames[kHasRICHSigPr] = "Has Pr signal in RICH"; + fgVariableUnits[kHasRICHSigPr] = ""; + fgVariableNames[kHasRICHSigDe] = "Has De signal in RICH"; + fgVariableUnits[kHasRICHSigDe] = ""; + fgVariableNames[kHasRICHSigTr] = "Has Tr signal in RICH"; + fgVariableUnits[kHasRICHSigTr] = ""; + fgVariableNames[kHasRICHSigHe3] = "Has He3 signal in RICH"; + fgVariableUnits[kHasRICHSigHe3] = ""; + fgVariableNames[kHasRICHSigAl] = "Has Al signal in RICH"; + fgVariableUnits[kHasRICHSigAl] = ""; + fgVariableNames[kRICHnSigmaEl] = "n #sigma_{El}^{RHICH}"; + fgVariableUnits[kRICHnSigmaEl] = ""; + fgVariableNames[kRICHnSigmaMu] = "n #sigma_{Mu}^{RHICH}"; + fgVariableUnits[kRICHnSigmaMu] = ""; + fgVariableNames[kRICHnSigmaPi] = "n #sigma_{Pi}^{RHICH}"; + fgVariableUnits[kRICHnSigmaPi] = ""; + fgVariableNames[kRICHnSigmaKa] = "n #sigma_{Ka}^{RHICH}"; + fgVariableUnits[kRICHnSigmaKa] = ""; + fgVariableNames[kRICHnSigmaPr] = "n #sigma_{Pr}^{RHICH}"; + fgVariableUnits[kRICHnSigmaPr] = ""; + fgVariableNames[kRICHnSigmaDe] = "n #sigma_{De}^{RHICH}"; + fgVariableUnits[kRICHnSigmaDe] = ""; + fgVariableNames[kRICHnSigmaTr] = "n #sigma_{Tr}^{RHICH}"; + fgVariableUnits[kRICHnSigmaTr] = ""; + fgVariableNames[kRICHnSigmaHe3] = "n #sigma_{He3}^{RHICH}"; + fgVariableUnits[kRICHnSigmaHe3] = ""; + fgVariableNames[kRICHnSigmaAl] = "n #sigma_{Al}^{RHICH}"; + fgVariableUnits[kRICHnSigmaAl] = ""; + fgVariableNames[kTOFEventTime] = "Event time reconstructed with ALICE3 TOF"; + fgVariableUnits[kTOFEventTime] = "ns"; + fgVariableNames[kTOFEventTimeErr] = "Event time error reconstructed with ALICE3 TOF"; + fgVariableUnits[kTOFEventTimeErr] = "ns"; + fgVariableNames[kOuterTOFnSigmaEl] = "n #sigma_{El}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaEl] = ""; + fgVariableNames[kOuterTOFnSigmaMu] = "n #sigma_{Mu}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaMu] = ""; + fgVariableNames[kOuterTOFnSigmaPi] = "n #sigma_{Pi}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaPi] = ""; + fgVariableNames[kOuterTOFnSigmaKa] = "n #sigma_{Ka}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaKa] = ""; + fgVariableNames[kOuterTOFnSigmaPr] = "n #sigma_{Pr}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaPr] = ""; + fgVariableNames[kOuterTOFnSigmaDe] = "n #sigma_{De}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaDe] = ""; + fgVariableNames[kOuterTOFnSigmaTr] = "n #sigma_{Tr}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaTr] = ""; + fgVariableNames[kOuterTOFnSigmaHe3] = "n #sigma_{He3}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaHe3] = ""; + fgVariableNames[kOuterTOFnSigmaAl] = "n #sigma_{Al}^{oTOF}"; + fgVariableUnits[kOuterTOFnSigmaAl] = ""; + fgVariableNames[kInnerTOFnSigmaEl] = "n #sigma_{El}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaEl] = ""; + fgVariableNames[kInnerTOFnSigmaMu] = "n #sigma_{Mu}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaMu] = ""; + fgVariableNames[kInnerTOFnSigmaPi] = "n #sigma_{Pi}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaPi] = ""; + fgVariableNames[kInnerTOFnSigmaKa] = "n #sigma_{Ka}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaKa] = ""; + fgVariableNames[kInnerTOFnSigmaPr] = "n #sigma_{Pr}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaPr] = ""; + fgVariableNames[kInnerTOFnSigmaDe] = "n #sigma_{De}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaDe] = ""; + fgVariableNames[kInnerTOFnSigmaTr] = "n #sigma_{Tr}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaTr] = ""; + fgVariableNames[kInnerTOFnSigmaHe3] = "n #sigma_{He3}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaHe3] = ""; + fgVariableNames[kInnerTOFnSigmaAl] = "n #sigma_{Al}^{iTOF}"; + fgVariableUnits[kInnerTOFnSigmaAl] = ""; // Set the variables short names map. This is needed for dynamic configuration via JSON files fgVarNamesMap["kNothing"] = kNothing; @@ -2139,4 +2251,58 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kBGFDDApf"] = kBGFDDApf; fgVarNamesMap["kBBFDDCpf"] = kBBFDDCpf; fgVarNamesMap["kBGFDDCpf"] = kBGFDDCpf; + fgVarNamesMap["kMultDensity"] = kMultDensity; + fgVarNamesMap["kMultMCNParticlesEta40"] = kMultMCNParticlesEta40; + fgVarNamesMap["kMultMCNParticlesEta20"] = kMultMCNParticlesEta20; + fgVarNamesMap["kIsReconstructed"] = kIsReconstructed; + fgVarNamesMap["kNSiliconHits"] = kNSiliconHits; + fgVarNamesMap["kNTPCHits"] = kNTPCHits; + fgVarNamesMap["kOTTOTSignal"] = kOTTOTSignal; + fgVarNamesMap["kOTnSigmaEl"] = kOTnSigmaEl; + fgVarNamesMap["kOTnSigmaMu"] = kOTnSigmaMu; + fgVarNamesMap["kOTnSigmaPi"] = kOTnSigmaPi; + fgVarNamesMap["kOTnSigmaKa"] = kOTnSigmaKa; + fgVarNamesMap["kOTnSigmaPr"] = kOTnSigmaPr; + fgVarNamesMap["kOTnSigmaDe"] = kOTnSigmaDe; + fgVarNamesMap["kOTnSigmaTr"] = kOTnSigmaTr; + fgVarNamesMap["kOTnSigmaHe3"] = kOTnSigmaHe3; + fgVarNamesMap["kOTnSigmaAl"] = kOTnSigmaAl; + fgVarNamesMap["kHasRICHSig"] = kHasRICHSig; + fgVarNamesMap["kHasRICHSigInGas"] = kHasRICHSigInGas; + fgVarNamesMap["kHasRICHSigEl"] = kHasRICHSigEl; + fgVarNamesMap["kHasRICHSigMu"] = kHasRICHSigMu; + fgVarNamesMap["kHasRICHSigPi"] = kHasRICHSigPi; + fgVarNamesMap["kHasRICHSigKa"] = kHasRICHSigKa; + fgVarNamesMap["kHasRICHSigPr"] = kHasRICHSigPr; + fgVarNamesMap["kHasRICHSigDe"] = kHasRICHSigDe; + fgVarNamesMap["kHasRICHSigTr"] = kHasRICHSigTr; + fgVarNamesMap["kHasRICHSigHe3"] = kHasRICHSigHe3; + fgVarNamesMap["kHasRICHSigAl"] = kHasRICHSigAl; + fgVarNamesMap["kRICHnSigmaEl"] = kRICHnSigmaEl; + fgVarNamesMap["kRICHnSigmaMu"] = kRICHnSigmaMu; + fgVarNamesMap["kRICHnSigmaPi"] = kRICHnSigmaPi; + fgVarNamesMap["kRICHnSigmaKa"] = kRICHnSigmaKa; + fgVarNamesMap["kRICHnSigmaPr"] = kRICHnSigmaPr; + fgVarNamesMap["kRICHnSigmaDe"] = kRICHnSigmaDe; + fgVarNamesMap["kRICHnSigmaTr"] = kRICHnSigmaTr; + fgVarNamesMap["kRICHnSigmaHe3"] = kRICHnSigmaHe3; + fgVarNamesMap["kRICHnSigmaAl"] = kRICHnSigmaAl; + fgVarNamesMap["kOuterTOFnSigmaEl"] = kOuterTOFnSigmaEl; + fgVarNamesMap["kOuterTOFnSigmaMu"] = kOuterTOFnSigmaMu; + fgVarNamesMap["kOuterTOFnSigmaPi"] = kOuterTOFnSigmaPi; + fgVarNamesMap["kOuterTOFnSigmaKa"] = kOuterTOFnSigmaKa; + fgVarNamesMap["kOuterTOFnSigmaPr"] = kOuterTOFnSigmaPr; + fgVarNamesMap["kOuterTOFnSigmaDe"] = kOuterTOFnSigmaDe; + fgVarNamesMap["kOuterTOFnSigmaTr"] = kOuterTOFnSigmaTr; + fgVarNamesMap["kOuterTOFnSigmaHe3"] = kOuterTOFnSigmaHe3; + fgVarNamesMap["kOuterTOFnSigmaAl"] = kOuterTOFnSigmaAl; + fgVarNamesMap["kInnerTOFnSigmaEl"] = kInnerTOFnSigmaEl; + fgVarNamesMap["kInnerTOFnSigmaMu"] = kInnerTOFnSigmaMu; + fgVarNamesMap["kInnerTOFnSigmaPi"] = kInnerTOFnSigmaPi; + fgVarNamesMap["kInnerTOFnSigmaKa"] = kInnerTOFnSigmaKa; + fgVarNamesMap["kInnerTOFnSigmaPr"] = kInnerTOFnSigmaPr; + fgVarNamesMap["kInnerTOFnSigmaDe"] = kInnerTOFnSigmaDe; + fgVarNamesMap["kInnerTOFnSigmaTr"] = kInnerTOFnSigmaTr; + fgVarNamesMap["kInnerTOFnSigmaHe3"] = kInnerTOFnSigmaHe3; + fgVarNamesMap["kInnerTOFnSigmaAl"] = kInnerTOFnSigmaAl; } diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index 3688d0ada02..bef6f37a4bb 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -972,6 +972,65 @@ class VarManager : public TObject kNFiredChannelsFT0C, kNFiredChannelsFV0A, + // ALICE 3 Variables + kMultDensity, + kMultMCNParticlesEta40, + kMultMCNParticlesEta20, + kIsReconstructed, + kNSiliconHits, + kNTPCHits, + kOTTOTSignal, + kOTnSigmaEl, + kOTnSigmaMu, + kOTnSigmaPi, + kOTnSigmaKa, + kOTnSigmaPr, + kOTnSigmaDe, + kOTnSigmaTr, + kOTnSigmaHe3, + kOTnSigmaAl, + kHasRICHSig, + kHasRICHSigInGas, + kHasRICHSigEl, + kHasRICHSigMu, + kHasRICHSigPi, + kHasRICHSigKa, + kHasRICHSigPr, + kHasRICHSigDe, + kHasRICHSigTr, + kHasRICHSigHe3, + kHasRICHSigAl, + kRICHnSigmaEl, + kRICHnSigmaMu, + kRICHnSigmaPi, + kRICHnSigmaKa, + kRICHnSigmaPr, + kRICHnSigmaDe, + kRICHnSigmaTr, + kRICHnSigmaHe3, + kRICHnSigmaAl, + kTOFEventTime, + kTOFEventTimeErr, + kOuterTOFnSigmaEl, + kOuterTOFnSigmaMu, + kOuterTOFnSigmaPi, + kOuterTOFnSigmaKa, + kOuterTOFnSigmaPr, + kOuterTOFnSigmaDe, + kOuterTOFnSigmaTr, + kOuterTOFnSigmaHe3, + kOuterTOFnSigmaAl, + kInnerTOFnSigmaEl, + kInnerTOFnSigmaMu, + kInnerTOFnSigmaPi, + kInnerTOFnSigmaKa, + kInnerTOFnSigmaPr, + kInnerTOFnSigmaDe, + kInnerTOFnSigmaTr, + kInnerTOFnSigmaHe3, + kInnerTOFnSigmaAl, + kA3Variables, + kNVars }; // end of Variables enumeration @@ -1284,6 +1343,12 @@ class VarManager : public TObject static void FillBdtScore(const T& bdtScore, float* values = nullptr); template static void FillFIT(const T1& bc, const T2& bcs, const T3& ft0s, const T4& fv0as, const T5& fdds, float* values = nullptr); + template + static void FillPairAlice3(T1 const& t1, T2 const& t2, float* values = nullptr); + template + static void FillEventAlice3(T const& event, float* values = nullptr); + template + static void FillTrackAlice3(T const& track, float* values = nullptr); static void SetCalibrationObject(CalibObjects calib, TObject* obj) { @@ -6129,4 +6194,488 @@ void VarManager::FillFIT(T1 const& bc, T2 const& bcs, T3 const& ft0s, T4 const& values[kBBFDDCpf] = static_cast(fitInfo.BBFDDCpf); values[kBGFDDCpf] = static_cast(fitInfo.BGFDDCpf); } + +template +void VarManager::FillEventAlice3(T const& event, float* values) +{ + if (!values) { + values = fgValues; + } + if constexpr ((fillMap & CollisionTimestamp) > 0) { + values[kTimestamp] = event.timestamp(); + } + + if constexpr ((fillMap & Collision) > 0) { + values[kVtxX] = event.posX(); + values[kVtxY] = event.posY(); + values[kVtxZ] = event.posZ(); + values[kVtxNcontrib] = event.numContrib(); + values[kVtxCovXX] = event.covXX(); + values[kVtxCovXY] = event.covXY(); + values[kVtxCovXZ] = event.covXZ(); + values[kVtxCovYY] = event.covYY(); + values[kVtxCovYZ] = event.covYZ(); + values[kVtxCovZZ] = event.covZZ(); + values[kVtxChi2] = event.chi2(); + values[kCollisionTime] = event.collisionTime(); + values[kCollisionTimeRes] = event.collisionTimeRes(); + } + + if constexpr ((fillMap & ReducedEvent) > 0) { + values[kRunNo] = -1; + values[kVtxX] = event.posX(); + values[kVtxY] = event.posY(); + values[kVtxZ] = event.posZ(); + values[kVtxNcontrib] = event.numContrib(); + values[kCollisionTime] = event.collisionTime(); + values[kCollisionTimeRes] = event.collisionTimeRes(); + } + if constexpr ((fillMap & ReducedEventVtxCov) > 0) { + values[kVtxCovXX] = event.covXX(); + values[kVtxCovXY] = event.covXY(); + values[kVtxCovXZ] = event.covXZ(); + values[kVtxCovYY] = event.covYY(); + values[kVtxCovYZ] = event.covYZ(); + values[kVtxCovZZ] = event.covZZ(); + values[kVtxChi2] = event.chi2(); + } + + if constexpr ((fillMap & CollisionMC) > 0) { + values[kMCEventGeneratorId] = event.generatorsID(); + values[kMCEventSubGeneratorId] = event.getSubGeneratorId(); + values[kMCVtxX] = event.posX(); + values[kMCVtxY] = event.posY(); + values[kMCVtxZ] = event.posZ(); + values[kMCEventTime] = event.t(); + values[kMCEventWeight] = event.weight(); + values[kMCEventImpParam] = event.impactParameter(); + } + + if constexpr ((fillMap & ReducedEventMC) > 0) { + values[kMCEventGeneratorId] = event.generatorsID(); + values[kMCEventGeneratorId] = -999; // to be added in reduced events + values[kMCVtxX] = event.mcPosX(); + values[kMCVtxY] = event.mcPosY(); + values[kMCVtxZ] = event.mcPosZ(); + values[kMCEventTime] = event.t(); + values[kMCEventWeight] = event.weight(); + values[kMCEventImpParam] = event.impactParameter(); + } +} + +template +void VarManager::FillTrackAlice3(T const& track, float* values) +{ + if (!values) { + values = fgValues; + } + + if constexpr ((fillMap & Track) > 0 || (fillMap & ReducedTrack) > 0) { + values[kPt] = track.pt(); + values[kSignedPt] = track.pt() * track.sign(); + if (fgUsedVars[kP]) { + values[kP] = track.p(); + } + if (fgUsedVars[kPx]) { + values[kPx] = track.px(); + } + if (fgUsedVars[kPy]) { + values[kPy] = track.py(); + } + if (fgUsedVars[kPz]) { + values[kPz] = track.pz(); + } + if (fgUsedVars[kInvPt]) { + values[kInvPt] = 1. / track.pt(); + } + values[kEta] = track.eta(); + values[kPhi] = track.phi(); + values[kCharge] = track.sign(); + + if (fgUsedVars[kPVContributor]) { + values[kPVContributor] = (track.flags() & o2::aod::track::PVContributor) > 0; + } + + if (fgUsedVars[kITSClusterMap]) { + values[kITSClusterMap] = track.itsClusterMap(); + } + + values[kITSchi2] = track.itsChi2NCl(); + } + + // Quantities based on the barrel tables + if constexpr ((fillMap & TrackExtra) > 0 || (fillMap & ReducedTrackBarrel) > 0) { + + values[kTrackLength] = track.length(); + + if constexpr ((fillMap & ReducedTrackBarrel) > 0) { + values[kTrackDCAxy] = track.dcaXY(); + values[kTrackDCAz] = track.dcaZ(); + if constexpr ((fillMap & ReducedTrackBarrelCov) > 0) { + if (fgUsedVars[kTrackDCAsigXY]) { + values[kTrackDCAsigXY] = track.dcaXY() / std::sqrt(track.cYY()); + } + if (fgUsedVars[kTrackDCAsigZ]) { + values[kTrackDCAsigZ] = track.dcaZ() / std::sqrt(track.cZZ()); + } + if (fgUsedVars[kTrackDCAresXY]) { + values[kTrackDCAresXY] = std::sqrt(track.cYY()); + } + if (fgUsedVars[kTrackDCAresZ]) { + values[kTrackDCAresZ] = std::sqrt(track.cZZ()); + } + } + } + } + + // Quantities based on the barrel track selection table + if constexpr ((fillMap & TrackDCA) > 0) { + values[kTrackDCAxy] = track.dcaXY(); + values[kTrackDCAz] = track.dcaZ(); + if constexpr ((fillMap & TrackCov) > 0) { + if (fgUsedVars[kTrackDCAsigXY]) { + values[kTrackDCAsigXY] = track.dcaXY() / std::sqrt(track.cYY()); + } + if (fgUsedVars[kTrackDCAsigZ]) { + values[kTrackDCAsigZ] = track.dcaZ() / std::sqrt(track.cZZ()); + } + if (fgUsedVars[kTrackDCAresXY]) { + values[kTrackDCAresXY] = std::sqrt(track.cYY()); + } + if (fgUsedVars[kTrackDCAresZ]) { + values[kTrackDCAresZ] = std::sqrt(track.cZZ()); + } + } + } + + // Quantities based on the barrel covariance tables + if constexpr ((fillMap & TrackCov) > 0 || (fillMap & ReducedTrackBarrelCov) > 0) { + values[kTrackCYY] = track.cYY(); + values[kTrackCZZ] = track.cZZ(); + values[kTrackCSnpSnp] = track.cSnpSnp(); + values[kTrackCTglTgl] = track.cTglTgl(); + values[kTrackC1Pt21Pt2] = track.c1Pt21Pt2(); + } + + if constexpr ((fillMap & TrackPID) > 0 || (fillMap & ReducedTrackBarrelPID) > 0) { + + values[kOTTOTSignal] = track.timeOverThresholdBarrel(); + values[kOTnSigmaEl] = track.nSigmaTrkEl(); + values[kOTnSigmaMu] = track.nSigmaTrkMu(); + values[kOTnSigmaPi] = track.nSigmaTrkPi(); + values[kOTnSigmaKa] = track.nSigmaTrkKa(); + values[kOTnSigmaPr] = track.nSigmaTrkPr(); + values[kOTnSigmaDe] = track.nSigmaTrkDe(); + values[kOTnSigmaTr] = track.nSigmaTrkTr(); + values[kOTnSigmaHe3] = track.nSigmaTrkHe(); + values[kOTnSigmaAl] = track.nSigmaTrkAl(); + values[kHasRICHSig] = track.hasSig(); + values[kHasRICHSigInGas] = track.hasSigInGas(); + values[kHasRICHSigEl] = track.hasSigEl(); + values[kHasRICHSigMu] = track.hasSigMu(); + values[kHasRICHSigPi] = track.hasSigPi(); + values[kHasRICHSigKa] = track.hasSigKa(); + values[kHasRICHSigPr] = track.hasSigPr(); + values[kHasRICHSigDe] = track.hasSigDe(); + values[kHasRICHSigTr] = track.hasSigTr(); + values[kHasRICHSigHe3] = track.hasSigHe3(); + values[kHasRICHSigAl] = track.hasSigAl(); + values[kRICHnSigmaEl] = track.nSigmaElectronRich(); + values[kRICHnSigmaMu] = track.nSigmaMuonRich(); + values[kRICHnSigmaPi] = track.nSigmaPionRich(); + values[kRICHnSigmaKa] = track.nSigmaKaonRich(); + values[kRICHnSigmaPr] = track.nSigmaProtonRich(); + values[kRICHnSigmaDe] = track.nSigmaDeuteronRich(); + values[kRICHnSigmaTr] = track.nSigmaTritonRich(); + values[kRICHnSigmaHe3] = track.nSigmaHelium3Rich(); + values[kRICHnSigmaAl] = track.nSigmaAlphaRich(); + values[kTOFEventTime] = track.tofEventTime(); + values[kTOFEventTimeErr] = track.tofEventTimeErr(); + values[kOuterTOFnSigmaEl] = track.nSigmaElectronOuterTOF(); + values[kOuterTOFnSigmaMu] = track.nSigmaMuonOuterTOF(); + values[kOuterTOFnSigmaPi] = track.nSigmaPionOuterTOF(); + values[kOuterTOFnSigmaKa] = track.nSigmaKaonOuterTOF(); + values[kOuterTOFnSigmaPr] = track.nSigmaProtonOuterTOF(); + values[kOuterTOFnSigmaDe] = track.nSigmaDeuteronOuterTOF(); + values[kOuterTOFnSigmaTr] = track.nSigmaTritonOuterTOF(); + values[kOuterTOFnSigmaHe3] = track.nSigmaHelium3OuterTOF(); + values[kOuterTOFnSigmaAl] = track.nSigmaAlphaOuterTOF(); + values[kInnerTOFnSigmaEl] = track.nSigmaElectronInnerTOF(); + values[kInnerTOFnSigmaMu] = track.nSigmaMuonInnerTOF(); + values[kInnerTOFnSigmaPi] = track.nSigmaPionInnerTOF(); + values[kInnerTOFnSigmaKa] = track.nSigmaKaonInnerTOF(); + values[kInnerTOFnSigmaPr] = track.nSigmaProtonInnerTOF(); + values[kInnerTOFnSigmaDe] = track.nSigmaDeuteronInnerTOF(); + values[kInnerTOFnSigmaTr] = track.nSigmaTritonInnerTOF(); + values[kInnerTOFnSigmaHe3] = track.nSigmaHelium3InnerTOF(); + values[kInnerTOFnSigmaAl] = track.nSigmaAlphaInnerTOF(); + } + + // Quantities based on the pair table(s) + if constexpr ((fillMap & Pair) > 0) { + values[kMass] = track.mass(); + ROOT::Math::PtEtaPhiMVector vpair(track.pt(), track.eta(), track.phi(), track.mass()); + values[kRap] = vpair.Rapidity(); + } + + // Derived quantities which can be computed based on already filled variables + FillTrackDerived(values); +} + +template +void VarManager::FillPairAlice3(T1 const& t1, T2 const& t2, float* values) +{ + if (!values) { + values = fgValues; + } + + float m1 = o2::constants::physics::MassElectron; + float m2 = o2::constants::physics::MassElectron; + if constexpr (pairType == kDecayToMuMu) { + m1 = o2::constants::physics::MassMuon; + m2 = o2::constants::physics::MassMuon; + } + + if constexpr (pairType == kDecayToPiPi) { + m1 = o2::constants::physics::MassPionCharged; + m2 = o2::constants::physics::MassPionCharged; + } + + if constexpr (pairType == kDecayToKPi) { + m1 = o2::constants::physics::MassKaonCharged; + m2 = o2::constants::physics::MassPionCharged; + } + + if constexpr (pairType == kElectronMuon) { + m2 = o2::constants::physics::MassMuon; + } + + values[kCharge] = t1.sign() + t2.sign(); + values[kCharge1] = t1.sign(); + values[kCharge2] = t2.sign(); + 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(); + values[kEta] = v12.Eta(); + // values[kPhi] = v12.Phi(); + values[kPhi] = v12.Phi() > 0 ? v12.Phi() : v12.Phi() + 2. * M_PI; + values[kRap] = -v12.Rapidity(); + double Ptot1 = TMath::Sqrt(v1.Px() * v1.Px() + v1.Py() * v1.Py() + v1.Pz() * v1.Pz()); + double Ptot2 = TMath::Sqrt(v2.Px() * v2.Px() + v2.Py() * v2.Py() + v2.Pz() * v2.Pz()); + values[kDeltaPtotTracks] = Ptot1 - Ptot2; + + values[kPt1] = t1.pt(); + values[kEta1] = t1.eta(); + values[kPhi1] = t1.phi(); + values[kPt2] = t2.pt(); + values[kEta2] = t2.eta(); + values[kPhi2] = t2.phi(); + + if (fgUsedVars[kDeltaPhiPair2]) { + double phipair2 = v1.Phi() - v2.Phi(); + if (phipair2 > 3 * TMath::Pi() / 2) { + values[kDeltaPhiPair2] = phipair2 - 2 * TMath::Pi(); + } else if (phipair2 < -TMath::Pi() / 2) { + values[kDeltaPhiPair2] = phipair2 + 2 * TMath::Pi(); + } else { + values[kDeltaPhiPair2] = phipair2; + } + } + + if (fgUsedVars[kDeltaEtaPair2]) { + values[kDeltaEtaPair2] = v1.Eta() - v2.Eta(); + } + + if (fgUsedVars[kPsiPair]) { + values[kDeltaPhiPair] = (t1.sign() * fgMagField > 0.) ? (v1.Phi() - v2.Phi()) : (v2.Phi() - v1.Phi()); + double xipair = TMath::ACos((v1.Px() * v2.Px() + v1.Py() * v2.Py() + v1.Pz() * v2.Pz()) / v1.P() / v2.P()); + values[kPsiPair] = (t1.sign() * fgMagField > 0.) ? TMath::ASin((v1.Theta() - v2.Theta()) / xipair) : TMath::ASin((v2.Theta() - v1.Theta()) / xipair); + } + + if (fgUsedVars[kOpeningAngle]) { + double scalar = v1.Px() * v2.Px() + v1.Py() * v2.Py() + v1.Pz() * v2.Pz(); + double Ptot12 = Ptot1 * Ptot2; + if (Ptot12 <= 0) { + values[kOpeningAngle] = 0.; + } else { + double arg = scalar / Ptot12; + if (arg > 1.) + arg = 1.; + if (arg < -1) + arg = -1; + values[kOpeningAngle] = TMath::ACos(arg); + } + } + + // polarization parameters + bool useHE = fgUsedVars[kCosThetaHE] || fgUsedVars[kPhiHE]; // helicity frame + bool useCS = fgUsedVars[kCosThetaCS] || fgUsedVars[kPhiCS]; // Collins-Soper frame + bool usePP = fgUsedVars[kCosThetaPP]; // production plane frame + bool useRM = fgUsedVars[kCosThetaRM]; // Random frame + + if (useHE || useCS || usePP || useRM) { + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; + ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam1_CM{(boostv12(fgBeamA).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam2_CM{(boostv12(fgBeamC).Vect()).Unit()}; + + // using positive sign convention for the first track + ROOT::Math::XYZVectorF v_CM = (t1.sign() > 0 ? v1_CM : v2_CM); + + if (useHE) { + ROOT::Math::XYZVectorF zaxis_HE{(v12.Vect()).Unit()}; + ROOT::Math::XYZVectorF yaxis_HE{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_HE{(yaxis_HE.Cross(zaxis_HE)).Unit()}; + if (fgUsedVars[kCosThetaHE]) + values[kCosThetaHE] = zaxis_HE.Dot(v_CM); + if (fgUsedVars[kPhiHE]) { + values[kPhiHE] = TMath::ATan2(yaxis_HE.Dot(v_CM), xaxis_HE.Dot(v_CM)); + if (values[kPhiHE] < 0) { + values[kPhiHE] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildeHE]) { + if (fgUsedVars[kCosThetaHE] && fgUsedVars[kPhiHE]) { + if (values[kCosThetaHE] > 0) { + values[kPhiTildeHE] = values[kPhiHE] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildeHE] < 0) { + values[kPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildeHE] = values[kPhiHE] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildeHE] < 0) { + values[kPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildeHE] = -999; // not computable + } + } + } + + if (useCS) { + ROOT::Math::XYZVectorF zaxis_CS{(Beam1_CM - Beam2_CM).Unit()}; + ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; + if (fgUsedVars[kCosThetaCS]) + values[kCosThetaCS] = zaxis_CS.Dot(v_CM); + if (fgUsedVars[kPhiCS]) { + values[kPhiCS] = TMath::ATan2(yaxis_CS.Dot(v_CM), xaxis_CS.Dot(v_CM)); + if (values[kPhiCS] < 0) { + values[kPhiCS] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildeCS]) { + if (fgUsedVars[kCosThetaCS] && fgUsedVars[kPhiCS]) { + if (values[kCosThetaCS] > 0) { + values[kPhiTildeCS] = values[kPhiCS] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildeCS] < 0) { + values[kPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildeCS] = values[kPhiCS] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildeCS] < 0) { + values[kPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildeCS] = -999; // not computable + } + } + } + + if (usePP) { + ROOT::Math::XYZVector zaxis_PP = ROOT::Math::XYZVector(v12.Py(), -v12.Px(), 0.f); + ROOT::Math::XYZVector yaxis_PP{(v12.Vect()).Unit()}; + ROOT::Math::XYZVector xaxis_PP{(yaxis_PP.Cross(zaxis_PP)).Unit()}; + if (fgUsedVars[kCosThetaPP]) { + values[kCosThetaPP] = zaxis_PP.Dot(v_CM) / std::sqrt(zaxis_PP.Mag2()); + } + if (fgUsedVars[kPhiPP]) { + values[kPhiPP] = TMath::ATan2(yaxis_PP.Dot(v_CM), xaxis_PP.Dot(v_CM)); + if (values[kPhiPP] < 0) { + values[kPhiPP] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildePP]) { + if (fgUsedVars[kCosThetaPP] && fgUsedVars[kPhiPP]) { + if (values[kCosThetaPP] > 0) { + values[kPhiTildePP] = values[kPhiPP] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildePP] < 0) { + values[kPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildePP] = values[kPhiPP] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildePP] < 0) { + values[kPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildePP] = -999; // not computable + } + } + } + + if (useRM) { + double randomCostheta = gRandom->Uniform(-1., 1.); + double randomPhi = gRandom->Uniform(0., 2. * TMath::Pi()); + ROOT::Math::XYZVectorF zaxis_RM(randomCostheta, std::sqrt(1 - randomCostheta * randomCostheta) * std::cos(randomPhi), std::sqrt(1 - randomCostheta * randomCostheta) * std::sin(randomPhi)); + if (fgUsedVars[kCosThetaRM]) + values[kCosThetaRM] = zaxis_RM.Dot(v_CM); + } + } + + if constexpr ((pairType == kDecayToEE) && ((fillMap & TrackCov) > 0 || (fillMap & ReducedTrackBarrelCov) > 0)) { + + if (fgUsedVars[kQuadDCAabsXY] || fgUsedVars[kQuadDCAsigXY] || fgUsedVars[kQuadDCAabsZ] || fgUsedVars[kQuadDCAsigZ] || fgUsedVars[kQuadDCAsigXYZ] || fgUsedVars[kSignQuadDCAsigXY]) { + // Quantities based on the barrel tables + double dca1XY = t1.dcaXY(); + double dca2XY = t2.dcaXY(); + double dca1Z = t1.dcaZ(); + double dca2Z = t2.dcaZ(); + double dca1sigXY = dca1XY / std::sqrt(t1.cYY()); + double dca2sigXY = dca2XY / std::sqrt(t2.cYY()); + double dca1sigZ = dca1Z / std::sqrt(t1.cZZ()); + double dca2sigZ = dca2Z / std::sqrt(t2.cZZ()); + + values[kQuadDCAabsXY] = std::sqrt((dca1XY * dca1XY + dca2XY * dca2XY) / 2); + values[kQuadDCAsigXY] = std::sqrt((dca1sigXY * dca1sigXY + dca2sigXY * dca2sigXY) / 2); + values[kQuadDCAabsZ] = std::sqrt((dca1Z * dca1Z + dca2Z * dca2Z) / 2); + values[kQuadDCAsigZ] = std::sqrt((dca1sigZ * dca1sigZ + dca2sigZ * dca2sigZ) / 2); + values[kSignQuadDCAsigXY] = t1.sign() * t2.sign() * TMath::Sign(1., dca1sigXY) * TMath::Sign(1., dca2sigXY) * std::sqrt((dca1sigXY * dca1sigXY + dca2sigXY * dca2sigXY) / 2); + + double det1 = t1.cYY() * t1.cZZ() - t1.cZY() * t1.cZY(); + double det2 = t2.cYY() * t2.cZZ() - t2.cZY() * t2.cZY(); + if ((det1 < 0) || (det2 < 0)) { + values[kQuadDCAsigXYZ] = -999; + } else { + double chi2t1 = (dca1XY * dca1XY * t1.cZZ() + dca1Z * dca1Z * t1.cYY() - 2. * dca1XY * dca1Z * t1.cZY()) / det1; + double chi2t2 = (dca2XY * dca2XY * t2.cZZ() + dca2Z * dca2Z * t2.cYY() - 2. * dca2XY * dca2Z * t2.cZY()) / det2; + + double dca1sigXYZ = std::sqrt(std::abs(chi2t1) / 2.); + double dca2sigXYZ = std::sqrt(std::abs(chi2t2) / 2.); + + values[kQuadDCAsigXYZ] = std::sqrt((dca1sigXYZ * dca1sigXYZ + dca2sigXYZ * dca2sigXYZ) / 2); + } + } + } + if constexpr ((pairType == kDecayToMuMu) && ((fillMap & Muon) > 0 || (fillMap & ReducedMuon) > 0)) { + if (fgUsedVars[kQuadDCAabsXY]) { + double dca1X = t1.fwdDcaX(); + double dca1Y = t1.fwdDcaY(); + double dca1XY = std::sqrt(dca1X * dca1X + dca1Y * dca1Y); + double dca2X = t2.fwdDcaX(); + double dca2Y = t2.fwdDcaY(); + double dca2XY = std::sqrt(dca2X * dca2X + dca2Y * dca2Y); + values[kQuadDCAabsXY] = std::sqrt((dca1XY * dca1XY + dca2XY * dca2XY) / 2.); + } + } + if (fgUsedVars[kPairPhiv]) { + values[kPairPhiv] = calculatePhiV(t1, t2); + } +} + #endif // PWGDQ_CORE_VARMANAGER_H_ diff --git a/PWGDQ/DataModel/ReducedTablesAlice3.h b/PWGDQ/DataModel/ReducedTablesAlice3.h new file mode 100644 index 00000000000..e1cad38495b --- /dev/null +++ b/PWGDQ/DataModel/ReducedTablesAlice3.h @@ -0,0 +1,331 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. +// +/// \file ReducedTablesAlice3.h +/// +/// \brief Reduced DQ table definitions for ALICE 3 +/// +/// \author Alexander Tiekoetter (atiekoet@cern.ch) University of Muenster + +#ifndef PWGDQ_DATAMODEL_REDUCEDTABLESALICE3_H_ +#define PWGDQ_DATAMODEL_REDUCEDTABLESALICE3_H_ + +#include "PWGDQ/DataModel/ReducedInfoTables.h" + +#include "ALICE3/DataModel/OTFPIDTrk.h" +#include "ALICE3/DataModel/OTFRICH.h" +#include "ALICE3/DataModel/OTFTOF.h" + +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +namespace reducedeventalice3 +{ +DECLARE_SOA_COLUMN(MultDensity, multDensity, float); +DECLARE_SOA_COLUMN(MCPosX, mcPosX, float); //! MC event position X +DECLARE_SOA_COLUMN(MCPosY, mcPosY, float); //! MC event position Y +DECLARE_SOA_COLUMN(MCPosZ, mcPosZ, float); //! MC event position Z +} // namespace reducedeventalice3 + +namespace reducedeventmcalice3 +{ +DECLARE_SOA_COLUMN(MultMCNParticlesEta05, multMCNParticlesEta05, float); +DECLARE_SOA_COLUMN(MultMCNParticlesEta08, multMCNParticlesEta08, float); +DECLARE_SOA_COLUMN(MultMCNParticlesEta10, multMCNParticlesEta10, float); +DECLARE_SOA_COLUMN(MultMCNParticlesEta20, multMCNParticlesEta20, float); +DECLARE_SOA_COLUMN(MultMCNParticlesEta40, multMCNParticlesEta40, float); +} // namespace reducedeventmcalice3 + +DECLARE_SOA_TABLE_STAGED(ReducedA3Events, "REA3EVENTS", //! Main event information table + o2::soa::Index<>, + collision::PosX, collision::PosY, collision::PosZ, collision::NumContrib, + collision::CollisionTime, collision::CollisionTimeRes, reducedeventalice3::MultDensity); + +DECLARE_SOA_TABLE(ReducedA3EventsVtxCov, "AOD", "REA3VTXCOV", //! Event vertex covariance matrix + collision::CovXX, collision::CovXY, collision::CovXZ, + collision::CovYY, collision::CovYZ, collision::CovZZ, collision::Chi2); + +DECLARE_SOA_TABLE(ReducedA3EventsInfo, "AOD", "REA3EVENTINFO", //! Main event index table + reducedevent::CollisionId); + +DECLARE_SOA_TABLE(ReducedA3MCEvents, "AOD", "REA3MCEVTS", //! Event level MC truth information + o2::soa::Index<>, + mccollision::GeneratorsID, reducedeventalice3::MCPosX, reducedeventalice3::MCPosY, reducedeventalice3::MCPosZ, + mccollision::T, mccollision::Weight, mccollision::ImpactParameter); + +using ReducedA3MCEvent = ReducedA3MCEvents::iterator; +using ReducedA3Event = ReducedA3Events::iterator; + +namespace reducedtrackalice3 +{ +// basic track information +DECLARE_SOA_INDEX_COLUMN(ReducedA3Event, reduceda3event); //! +DECLARE_SOA_INDEX_COLUMN(Track, track); //! +// ---- flags reserved for storing various information during filtering +DECLARE_SOA_BITMAP_COLUMN(FilteringFlags, filteringFlags, 64); //! +// ----------------------------------------------------- + +DECLARE_SOA_COLUMN(IsReconstructed, isReconstructed, bool); +DECLARE_SOA_COLUMN(NSiliconHits, nSiliconHits, int); +DECLARE_SOA_COLUMN(NTPCHits, nTPCHits, int); + +DECLARE_SOA_COLUMN(Pt, pt, float); //! +DECLARE_SOA_COLUMN(Eta, eta, float); //! +DECLARE_SOA_COLUMN(Phi, phi, float); //! +DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(IsAmbiguous, isAmbiguous, int); //! +DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! +DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); //! +DECLARE_SOA_COLUMN(DetectorMap, detectorMap, uint8_t); //! Detector map: see enum DetectorMapEnum +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! +DECLARE_SOA_DYNAMIC_COLUMN(HasITS, hasITS, //! Flag to check if track has a ITS match + [](uint8_t detectorMap) -> bool { return detectorMap & o2::aod::track::ITS; }); +DECLARE_SOA_DYNAMIC_COLUMN(HasTPC, hasTPC, //! Flag to check if track has a TPC match + [](uint8_t detectorMap) -> bool { return detectorMap & o2::aod::track::TPC; }); +DECLARE_SOA_DYNAMIC_COLUMN(HasTRD, hasTRD, //! Flag to check if track has a TRD match + [](uint8_t detectorMap) -> bool { return detectorMap & o2::aod::track::TRD; }); +DECLARE_SOA_DYNAMIC_COLUMN(HasTOF, hasTOF, //! Flag to check if track has a TOF measurement + [](uint8_t detectorMap) -> bool { return detectorMap & o2::aod::track::TOF; }); +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! + [](float pt, float phi) -> float { return pt * std::cos(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! + [](float pt, float phi) -> float { return pt * std::sin(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! + [](float pt, float eta) -> float { return pt * std::sinh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! + [](float pt, float eta) -> float { return pt * std::cosh(eta); }); +} // namespace reducedtrackalice3 + +// basic track information +DECLARE_SOA_TABLE(ReducedA3Tracks, "AOD", "REA3TRACK", //! + o2::soa::Index<>, reducedtrackalice3::ReducedA3EventId, reducedtrackalice3::FilteringFlags, + reducedtrackalice3::Pt, reducedtrackalice3::Eta, reducedtrackalice3::Phi, reducedtrackalice3::Sign, reducedtrackalice3::IsAmbiguous, + reducedtrackalice3::Px, + reducedtrackalice3::Py, + reducedtrackalice3::Pz, + reducedtrackalice3::P); + +DECLARE_SOA_TABLE(ReducedA3TracksBarrelCov, "AOD", "REA3BARRELCOV", //! + track::CYY, track::CZY, track::CZZ, track::CSnpY, track::CSnpZ, + track::CSnpSnp, track::CTglY, track::CTglZ, track::CTglSnp, track::CTglTgl, + track::C1PtY, track::C1PtZ, track::C1PtSnp, track::C1PtTgl, track::C1Pt21Pt2); + +namespace reducedA3trackMC +{ +DECLARE_SOA_INDEX_COLUMN(ReducedA3MCEvent, reducedA3MCEvent); //! +DECLARE_SOA_COLUMN(McReducedFlags, mcReducedFlags, uint16_t); //! Flags to hold compressed MC selection information +DECLARE_SOA_SELF_INDEX_COLUMN_FULL(Mother0, mother0, int, "ReducedA3MCTracks_Mother0"); //! Track index of the first mother +DECLARE_SOA_SELF_INDEX_COLUMN_FULL(Mother1, mother1, int, "ReducedA3MCTracks_Mother1"); //! Track index of the last mother +DECLARE_SOA_SELF_INDEX_COLUMN_FULL(Daughter0, daughter0, int, "ReducedA3MCTracks_Daughter0"); //! Track index of the first daughter +DECLARE_SOA_SELF_INDEX_COLUMN_FULL(Daughter1, daughter1, int, "ReducedA3MCTracks_Daughter1"); //! Track index of the last daughter +DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(Mothers, mothers); //! Mother tracks (possible empty) array. Iterate over mcParticle.mothers_as()) +DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(Daughters, daughters); //! Daughter tracks (possibly empty) slice. Check for non-zero with mcParticle.has_daughters(). Iterate over mcParticle.daughters_as()) +DECLARE_SOA_COLUMN(Pt, pt, float); //! +DECLARE_SOA_COLUMN(Eta, eta, float); //! +DECLARE_SOA_COLUMN(Phi, phi, float); //! +DECLARE_SOA_COLUMN(E, e, float); //! +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! + [](float pt, float phi) -> float { return pt * std::cos(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! + [](float pt, float phi) -> float { return pt * std::sin(phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! + [](float pt, float eta) -> float { return pt * std::sinh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! + [](float pt, float eta) -> float { return pt * std::cosh(eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! Particle rapidity + [](float pt, float eta, float e) -> float { + float pz = pt * std::sinh(eta); + if ((e - pz) > static_cast(1e-7)) { + return 0.5f * std::log((e + pz) / (e - pz)); + } else { + return -999.0f; + } + }); +} // namespace reducedA3trackMC + +// NOTE: This table is nearly identical to the one from Framework (except that it points to the event ID, not the BC id) +// This table contains all MC truth tracks (both barrel and muon) +DECLARE_SOA_TABLE(ReducedA3MCTracks, "AOD", "REA3MCTRACK", //! MC track information (on disk) + o2::soa::Index<>, reducedA3trackMC::ReducedA3MCEventId, + mcparticle::PdgCode, mcparticle::StatusCode, mcparticle::Flags, + reducedA3trackMC::MothersIds, reducedA3trackMC::DaughtersIdSlice, + mcparticle::Weight, + reducedA3trackMC::Pt, reducedA3trackMC::Eta, reducedA3trackMC::Phi, reducedA3trackMC::E, + mcparticle::Vx, mcparticle::Vy, mcparticle::Vz, mcparticle::Vt, + reducedA3trackMC::McReducedFlags, + reducedA3trackMC::Px, + reducedA3trackMC::Py, + reducedA3trackMC::Pz, + reducedA3trackMC::P, + reducedA3trackMC::Y, + mcparticle::ProducedByGenerator, + mcparticle::FromBackgroundEvent, + mcparticle::GetGenStatusCode, + mcparticle::GetProcess, + mcparticle::GetHepMCStatusCode, + mcparticle::IsPhysicalPrimary); + +using ReducedA3MCTrack = ReducedA3MCTracks::iterator; + +namespace reduceda3barreltracklabel +{ +DECLARE_SOA_INDEX_COLUMN(ReducedA3MCTrack, reducedA3MCTrack); //! +DECLARE_SOA_COLUMN(McMask, mcMask, uint16_t); +} // namespace reduceda3barreltracklabel + +// NOTE: MC labels. This table has one entry for each reconstructed track (joinable with the track tables) +// The McParticleId points to the position of the MC truth track from the ReducedTracksMC table +DECLARE_SOA_TABLE(ReducedA3TracksBarrelLabels, "AOD", "REA3BARLA", //! + reduceda3barreltracklabel::ReducedA3MCTrackId, reduceda3barreltracklabel::McMask, reducedA3trackMC::McReducedFlags); + +using ReducedA3TrackBarrelLabel = ReducedA3TracksBarrelLabels::iterator; + +DECLARE_SOA_TABLE(ReducedA3TracksBarrel, "AOD", "REA3BARREL", + track::X, track::Alpha, track::IsWithinBeamPipe, + track::Y, track::Z, track::Snp, track::Tgl, track::Signed1Pt, + track::Flags, track::ITSClusterMap, track::ITSChi2NCl, + reducedtrackalice3::IsReconstructed, reducedtrackalice3::NSiliconHits, + reducedtrackalice3::NTPCHits, track::Length, reducedtrack::DcaXY, reducedtrack::DcaZ, + track::IsPVContributor); + +// barrel collision information (joined with ReducedTracks) allowing to connect different tables (cross PWGs) +DECLARE_SOA_TABLE(ReducedA3TracksBarrelInfo, "AOD", "REA3BARRELINFO", + reducedtrackalice3::CollisionId, collision::PosX, collision::PosY, collision::PosZ, reducedtrackalice3::TrackId); + +using ReducedA3Track = ReducedA3Tracks::iterator; +using ReducedA3TrackBarrel = ReducedA3TracksBarrel::iterator; +using ReducedA3TrackBarrelCov = ReducedA3TracksBarrelCov::iterator; +using ReducedA3TrackBarrelInfo = ReducedA3TracksBarrelInfo::iterator; + +namespace reducedeventlabela3 +{ +DECLARE_SOA_INDEX_COLUMN(ReducedA3MCEvent, reducedA3MCEvent); //! MC collision +DECLARE_SOA_COLUMN(McMask, mcMask, uint16_t); //! Bit mask to indicate collision mismatches (bit ON means mismatch). Bit 15: indicates negative label +} // namespace reducedeventlabela3 + +DECLARE_SOA_TABLE(ReducedA3MCEventLabels, "AOD", "REA3MCCOLLBL", //! Table joined to the ReducedEvents table containing the MC index + reducedeventlabela3::ReducedA3MCEventId, reducedeventlabela3::McMask); + +using ReducedA3MCEventLabel = ReducedA3MCEventLabels::iterator; + +namespace reducedA3track_association +{ +DECLARE_SOA_INDEX_COLUMN(ReducedA3Event, reducedA3event); //! ReducedEvent index +DECLARE_SOA_INDEX_COLUMN(ReducedA3Track, reducedA3track); //! ReducedTrack index +} // namespace reducedA3track_association + +DECLARE_SOA_TABLE(ReducedA3TracksAssoc, "AOD", "REA3ASSOC", //! Table for reducedtrack-to-reducedcollision association + reducedA3track_association::ReducedA3EventId, + reducedA3track_association::ReducedA3TrackId); + +DECLARE_SOA_TABLE(ReducedA3PIDTOF, "AOD", "REA3PIDTOF", + upgrade_tof::TOFEventTime, + upgrade_tof::TOFEventTimeErr, + upgrade_tof::NSigmaElectronInnerTOF, + upgrade_tof::NSigmaMuonInnerTOF, + upgrade_tof::NSigmaPionInnerTOF, + upgrade_tof::NSigmaKaonInnerTOF, + upgrade_tof::NSigmaProtonInnerTOF, + upgrade_tof::NSigmaDeuteronInnerTOF, + upgrade_tof::NSigmaTritonInnerTOF, + upgrade_tof::NSigmaHelium3InnerTOF, + upgrade_tof::NSigmaAlphaInnerTOF, + upgrade_tof::InnerTOFTrackTimeReco, + upgrade_tof::InnerTOFTrackLengthReco, + upgrade_tof::NSigmaElectronOuterTOF, + upgrade_tof::NSigmaMuonOuterTOF, + upgrade_tof::NSigmaPionOuterTOF, + upgrade_tof::NSigmaKaonOuterTOF, + upgrade_tof::NSigmaProtonOuterTOF, + upgrade_tof::NSigmaDeuteronOuterTOF, + upgrade_tof::NSigmaTritonOuterTOF, + upgrade_tof::NSigmaHelium3OuterTOF, + upgrade_tof::NSigmaAlphaOuterTOF, + upgrade_tof::OuterTOFTrackTimeReco, + upgrade_tof::OuterTOFTrackLengthReco, + upgrade_tof::NSigmaInnerTOF, + upgrade_tof::NSigmaOuterTOF); + +DECLARE_SOA_TABLE(ReducedA3PIDRich, "AOD", "REA3PIDRICH", + upgrade_rich::NSigmaElectronRich, + upgrade_rich::NSigmaMuonRich, + upgrade_rich::NSigmaPionRich, + upgrade_rich::NSigmaKaonRich, + upgrade_rich::NSigmaProtonRich, + upgrade_rich::NSigmaDeuteronRich, + upgrade_rich::NSigmaTritonRich, + upgrade_rich::NSigmaHelium3Rich, + upgrade_rich::NSigmaAlphaRich, + upgrade_rich::NSigmaRich); + +DECLARE_SOA_TABLE(ReducedA3PIDRichSignals, "AOD", "REA3PIDRICHSIG", + upgrade_rich::HasSig, + upgrade_rich::HasSigInGas, + upgrade_rich::HasSigEl, + upgrade_rich::HasSigMu, + upgrade_rich::HasSigPi, + upgrade_rich::HasSigKa, + upgrade_rich::HasSigPr, + upgrade_rich::HasSigDe, + upgrade_rich::HasSigTr, + upgrade_rich::HasSigHe3, + upgrade_rich::HasSigAl); + +DECLARE_SOA_TABLE(ReducedA3PIDOT, "AOD", "REA3PIDOT", + upgrade::trk::TimeOverThresholdBarrel, + upgrade::trk::NSigmaTrkEl, + upgrade::trk::NSigmaTrkMu, + upgrade::trk::NSigmaTrkPi, + upgrade::trk::NSigmaTrkKa, + upgrade::trk::NSigmaTrkPr, + upgrade::trk::NSigmaTrkDe, + upgrade::trk::NSigmaTrkTr, + upgrade::trk::NSigmaTrkHe, + upgrade::trk::NSigmaTrkAl, + upgrade::trk::NSigmaTrk); + +} // namespace o2::aod + +#endif // PWGDQ_DATAMODEL_REDUCEDTABLESALICE3_H_ diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index 9b5cdef037c..9ba6c2dd1c0 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -1773,6 +1773,9 @@ struct qaMatching { collisionIds.push_back(collision.globalIndex()); } + if (collisionIds.empty()) + return; + for (size_t cid = 1; cid < collisionIds.size() - 1; cid++) { const auto& collision = collisions.rawIteratorAt(collisionIds[cid]); int64_t collisionIndex = collision.globalIndex(); diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 7156dec925b..1a0fae079de 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -301,8 +301,10 @@ struct SingleTrackQC { fRegistry.add("Track/positive/hDCAxRes_Pt", "DCA_{x} resolution vs. pT;p_{T} (GeV/c);DCA_{x} resolution (#mum)", kTH2F, {{200, 0, 10}, {500, 0, 500}}, false); fRegistry.add("Track/positive/hDCAyRes_Pt", "DCA_{y} resolution vs. pT;p_{T} (GeV/c);DCA_{y} resolution (#mum)", kTH2F, {{200, 0, 10}, {500, 0, 500}}, false); fRegistry.add("Track/positive/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{200, 0, 10}, {500, 0, 500}}, false); - fRegistry.add("Track/positive/hDCAx_PosZ", "DCAx vs. posZ;Z_{vtx} (cm);DCA_{x} (cm)", kTH2F, {{200, -10, +10}, {200, -1, +1}}, false); - fRegistry.add("Track/positive/hDCAy_PosZ", "DCAy vs. posZ;Z_{vtx} (cm);DCA_{y} (cm)", kTH2F, {{200, -10, +10}, {200, -1, +1}}, false); + fRegistry.add("Track/positive/hDCAx_PosZ", "DCAx vs. posZ;Z_{vtx} (cm);DCA_{x} (cm)", kTH2F, {{200, -10, +10}, {400, -0.2, +0.2}}, false); + fRegistry.add("Track/positive/hDCAy_PosZ", "DCAy vs. posZ;Z_{vtx} (cm);DCA_{y} (cm)", kTH2F, {{200, -10, +10}, {400, -0.2, +0.2}}, false); + fRegistry.add("Track/positive/hDCAx_Phi", "DCAx vs. #varphi;#varphi (rad.);DCA_{x} (cm)", kTH2F, {{90, 0, 2 * M_PI}, {400, -0.2, +0.2}}, false); + fRegistry.add("Track/positive/hDCAy_Phi", "DCAy vs. #varphi;#varphi (rad.);DCA_{y} (cm)", kTH2F, {{90, 0, 2 * M_PI}, {400, -0.2, +0.2}}, false); fRegistry.add("Track/positive/hNclsMCH", "number of MCH clusters", kTH1F, {{21, -0.5, 20.5}}, false); fRegistry.add("Track/positive/hNclsMFT", "number of MFT clusters", kTH1F, {{11, -0.5, 10.5}}, false); fRegistry.add("Track/positive/hPDCA", "pDCA;R at absorber end (cm);p #times DCA (GeV/c #upoint cm)", kTH2F, {{100, 0, 100}, {100, 0.0f, 1000}}, false); @@ -637,6 +639,8 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/positive/hDCAxyRes_Pt"), track.pt(), sigmaFwdDcaXY(track) * 1e+4); fRegistry.fill(HIST("Track/positive/hDCAx_PosZ"), collision.posZ(), track.fwdDcaX()); fRegistry.fill(HIST("Track/positive/hDCAy_PosZ"), collision.posZ(), track.fwdDcaY()); + fRegistry.fill(HIST("Track/positive/hDCAx_Phi"), track.phi(), track.fwdDcaX()); + fRegistry.fill(HIST("Track/positive/hDCAy_Phi"), track.phi(), track.fwdDcaY()); fRegistry.fill(HIST("Track/positive/hNclsMCH"), track.nClusters()); fRegistry.fill(HIST("Track/positive/hNclsMFT"), track.nClustersMFT()); fRegistry.fill(HIST("Track/positive/hPDCA"), track.rAtAbsorberEnd(), track.pDca()); @@ -658,6 +662,8 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/negative/hDCAxyRes_Pt"), track.pt(), sigmaFwdDcaXY(track) * 1e+4); fRegistry.fill(HIST("Track/negative/hDCAx_PosZ"), collision.posZ(), track.fwdDcaX()); fRegistry.fill(HIST("Track/negative/hDCAy_PosZ"), collision.posZ(), track.fwdDcaY()); + fRegistry.fill(HIST("Track/negative/hDCAx_Phi"), track.phi(), track.fwdDcaX()); + fRegistry.fill(HIST("Track/negative/hDCAy_Phi"), track.phi(), track.fwdDcaY()); fRegistry.fill(HIST("Track/negative/hNclsMCH"), track.nClusters()); fRegistry.fill(HIST("Track/negative/hNclsMFT"), track.nClustersMFT()); fRegistry.fill(HIST("Track/negative/hPDCA"), track.rAtAbsorberEnd(), track.pDca()); diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index 514e58694aa..78fc3481cf2 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -351,8 +351,10 @@ struct SingleTrackQCMC { fRegistry.add("Track/PromptLF/positive/hDCAxRes_Pt", "DCA_{x} resolution vs. pT;p_{T} (GeV/c);DCA_{x} resolution (#mum)", kTH2F, {{200, 0, 10}, {500, 0, 500}}, false); fRegistry.add("Track/PromptLF/positive/hDCAyRes_Pt", "DCA_{y} resolution vs. pT;p_{T} (GeV/c);DCA_{y} resolution (#mum)", kTH2F, {{200, 0, 10}, {500, 0, 500}}, false); fRegistry.add("Track/PromptLF/positive/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{200, 0, 10}, {500, 0, 500}}, false); - fRegistry.add("Track/PromptLF/positive/hDCAx_PosZ", "DCA_{x} vs. posZ;Z_{vtx} (cm);DCA_{x} (cm)", kTH2F, {{200, -10, 10}, {200, -1, +1}}, false); - fRegistry.add("Track/PromptLF/positive/hDCAy_PosZ", "DCA_{y} vs. posZ;Z_{vtx} (cm);DCA_{y} (cm)", kTH2F, {{200, -10, 10}, {200, -1, +1}}, false); + fRegistry.add("Track/PromptLF/positive/hDCAx_PosZ", "DCA_{x} vs. posZ;Z_{vtx} (cm);DCA_{x} (cm)", kTH2F, {{200, -10, 10}, {400, -0.2, +0.2}}, false); + fRegistry.add("Track/PromptLF/positive/hDCAy_PosZ", "DCA_{y} vs. posZ;Z_{vtx} (cm);DCA_{y} (cm)", kTH2F, {{200, -10, 10}, {400, -0.2, +0.2}}, false); + fRegistry.add("Track/PromptLF/positive/hDCAx_Phi", "DCAx vs. #varphi;#varphi (rad.);DCA_{x} (cm)", kTH2F, {{90, 0, 2 * M_PI}, {400, -0.2, +0.2}}, false); + fRegistry.add("Track/PromptLF/positive/hDCAy_Phi", "DCAy vs. #varphi;#varphi (rad.);DCA_{y} (cm)", kTH2F, {{90, 0, 2 * M_PI}, {400, -0.2, +0.2}}, false); fRegistry.add("Track/PromptLF/positive/hNclsMCH", "number of MCH clusters", kTH1F, {{21, -0.5, 20.5}}, false); fRegistry.add("Track/PromptLF/positive/hNclsMFT", "number of MFT clusters", kTH1F, {{11, -0.5, 10.5}}, false); fRegistry.add("Track/PromptLF/positive/hPDCA", "pDCA;R at absorber (cm);p #times DCA (GeV/c #upoint cm)", kTH2F, {{100, 0, 100}, {100, 0.0f, 1000}}, false); @@ -769,6 +771,8 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAxyRes_Pt"), track.pt(), sigmaFwdDcaXY(track) * 1e+4); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAx_PosZ"), collision.posZ(), track.fwdDcaX()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAy_PosZ"), collision.posZ(), track.fwdDcaY()); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAx_Phi"), track.phi(), track.fwdDcaX()); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAy_Phi"), track.phi(), track.fwdDcaY()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hNclsMCH"), track.nClusters()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hNclsMFT"), track.nClustersMFT()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hPDCA"), track.rAtAbsorberEnd(), track.pDca()); @@ -799,6 +803,8 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAxyRes_Pt"), track.pt(), sigmaFwdDcaXY(track) * 1e+4); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAx_PosZ"), collision.posZ(), track.fwdDcaX()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAy_PosZ"), collision.posZ(), track.fwdDcaY()); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAx_Phi"), track.phi(), track.fwdDcaX()); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAy_Phi"), track.phi(), track.fwdDcaY()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hNclsMCH"), track.nClusters()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hNclsMFT"), track.nClustersMFT()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hPDCA"), track.rAtAbsorberEnd(), track.pDca()); diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx index 79dab61c2c9..018abc465c4 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx @@ -169,6 +169,11 @@ struct skimmerPrimaryMuon { fRegistry.add("MFTMCHMID/hDCAxy", "DCAxy;DCA_{xy} (cm);", kTH1F, {{100, 0, 1}}, false); fRegistry.add("MFTMCHMID/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{100, 0, 1}, {200, -0.1, 0.1}}, false); fRegistry.add("MFTMCHMID/hDCAxyinSigma", "DCAxy in sigma;DCA_{xy} (#sigma);", kTH1F, {{100, 0, 10}}, false); + fRegistry.add("MFTMCHMID/hDCAx_PosZ", "DCAx vs. posZ;Z_{vtx} (cm);DCA_{x} (cm)", kTH2F, {{200, -10, +10}, {400, -0.2, +0.2}}, false); + fRegistry.add("MFTMCHMID/hDCAy_PosZ", "DCAy vs. posZ;Z_{vtx} (cm);DCA_{y} (cm)", kTH2F, {{200, -10, +10}, {400, -0.2, +0.2}}, false); + fRegistry.add("MFTMCHMID/hDCAx_Phi", "DCAx vs. #varphi;#varphi (rad.);DCA_{x} (cm)", kTH2F, {{90, 0, 2 * M_PI}, {400, -0.2, +0.2}}, false); + fRegistry.add("MFTMCHMID/hDCAy_Phi", "DCAy vs. #varphi;#varphi (rad.);DCA_{y} (cm)", kTH2F, {{90, 0, 2 * M_PI}, {400, -0.2, +0.2}}, false); + fRegistry.add("MFTMCHMID/hNmu", "#mu multiplicity;N_{#mu} per collision", kTH1F, {{21, -0.5, 20.5}}, false); fRegistry.addClone("MFTMCHMID/", "MCHMID/"); fRegistry.add("MFTMCHMID/hDCAxResolutionvsPt", "DCA_{x} vs. p_{T};p_{T} (GeV/c);DCA_{x} resolution (#mum);", kTH2F, {{100, 0, 10.f}, {500, 0, 500}}, false); @@ -461,6 +466,10 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MFTMCHMID/hDCAxResolutionvsPt"), pt, std::sqrt(cXX) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/hDCAyResolutionvsPt"), pt, std::sqrt(cYY) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/hDCAxyResolutionvsPt"), pt, sigma_dcaXY * 1e+4); // convert cm to um + fRegistry.fill(HIST("MFTMCHMID/hDCAx_PosZ"), collision.posZ(), dcaX); + fRegistry.fill(HIST("MFTMCHMID/hDCAy_PosZ"), collision.posZ(), dcaY); + fRegistry.fill(HIST("MFTMCHMID/hDCAx_Phi"), phi, dcaX); + fRegistry.fill(HIST("MFTMCHMID/hDCAy_Phi"), phi, dcaY); } else if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { fRegistry.fill(HIST("MCHMID/hPt"), pt); fRegistry.fill(HIST("MCHMID/hEtaPhi"), phi, eta); diff --git a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx index c482eb702f9..1804b766043 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx @@ -85,6 +85,7 @@ struct HfCandidateCreatorSigmac0plusplus { Configurable applyGlobalTrkWoDcaCutsSoftPi{"applyGlobalTrkWoDcaCutsSoftPi", false, "Switch on the application of the global-track w/o dca cuts for soft pion BEFORE ALL OTHER CUSTOM CUTS"}; Configurable softPiEtaMax{"softPiEtaMax", 0.9f, "Soft pion max value for pseudorapidity (abs vale)"}; Configurable softPiChi2Max{"softPiChi2Max", 36.f, "Soft pion max value for chi2 ITS"}; + Configurable softPiApplyCustomITSHitMap{"softPiApplyCustomITSHitMap", true, "Flag to enable/disable the application of the custom ITS hitmap requirement for the candidate soft pion"}; Configurable softPiItsHitMap{"softPiItsHitMap", 127, "Soft pion ITS hitmap"}; Configurable softPiItsHitsMin{"softPiItsHitsMin", 1, "Minimum number of ITS layers crossed by the soft pion among those in \"softPiItsHitMap\""}; Configurable softPiDcaXYMax{"softPiDcaXYMax", 0.065, "Soft pion max dcaXY (cm)"}; @@ -164,22 +165,24 @@ struct HfCandidateCreatorSigmac0plusplus { // ITS chi2 softPiCuts.SetMaxChi2PerClusterITS(softPiChi2Max); // ITS hitmap - std::set setSoftPiItsHitMap; // = {}; - constexpr std::size_t NLayersIts = 7; - for (std::size_t idItsLayer = 0u; idItsLayer < NLayersIts; idItsLayer++) { - if (TESTBIT(softPiItsHitMap, idItsLayer)) { - setSoftPiItsHitMap.insert(static_cast(idItsLayer)); + if (softPiApplyCustomITSHitMap) { + std::set setSoftPiItsHitMap; // = {}; + constexpr std::size_t NLayersIts = 7; + for (std::size_t idItsLayer = 0u; idItsLayer < NLayersIts; idItsLayer++) { + if (TESTBIT(softPiItsHitMap, idItsLayer)) { + setSoftPiItsHitMap.insert(static_cast(idItsLayer)); + } } + LOG(info) << "### ITS hitmap for soft pion"; + LOG(info) << " >>> setSoftPiItsHitMap.size(): " << setSoftPiItsHitMap.size(); + LOG(info) << " >>> Custom ITS hitmap dfchecked: "; + for (const auto& it : setSoftPiItsHitMap) { + LOG(info) << " Layer " << static_cast(it) << " "; + } + LOG(info) << "############"; + softPiCuts.SetRequireITSRefit(); + softPiCuts.SetRequireHitsInITSLayers(softPiItsHitsMin, setSoftPiItsHitMap); } - LOG(info) << "### ITS hitmap for soft pion"; - LOG(info) << " >>> setSoftPiItsHitMap.size(): " << setSoftPiItsHitMap.size(); - LOG(info) << " >>> Custom ITS hitmap dfchecked: "; - for (const auto it : setSoftPiItsHitMap) { - LOG(info) << " Layer " << static_cast(it) << " "; - } - LOG(info) << "############"; - softPiCuts.SetRequireITSRefit(); - softPiCuts.SetRequireHitsInITSLayers(softPiItsHitsMin, setSoftPiItsHitMap); /// CCDB for dcaXY, dcaZ recalculation of soft pions reassigned to another collision ccdb->setURL(ccdbUrl); diff --git a/PWGJE/TableProducer/derivedDataProducer.cxx b/PWGJE/TableProducer/derivedDataProducer.cxx index 4a8b0ca0366..2e2f29bfab8 100644 --- a/PWGJE/TableProducer/derivedDataProducer.cxx +++ b/PWGJE/TableProducer/derivedDataProducer.cxx @@ -161,6 +161,7 @@ struct JetDerivedDataProducerTask { Configurable includeHadronicRate{"includeHadronicRate", true, "fill the collision information with the hadronic rate"}; Configurable includeUpcs{"includeUpcs", true, "include option to identify UPC events"}; Configurable v0ChargedDecaysOnly{"v0ChargedDecaysOnly", true, "store V0s (at particle-level) only if they decay to charged particles"}; + Configurable isMCGenOnly{"isMCGenOnly", false, "analysis is run over mcGen only"}; } config; struct : PresliceGroup { @@ -349,28 +350,44 @@ struct JetDerivedDataProducerTask { void processMcCollisions(soa::Join::iterator const& mcCollision) { - products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), mcCollision.multMCFV0A(), mcCollision.multMCFT0A(), mcCollision.multMCFT0C(), mcCollision.centFT0M(), mcCollision.weight(), mcCollision.accepted(), mcCollision.attempted(), mcCollision.xsectGen(), mcCollision.xsectErr(), mcCollision.ptHard(), bcRctMapping[mcCollision.bcId()], mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); + uint32_t rctDecision = ~uint32_t{0}; + if (!config.isMCGenOnly) { + rctDecision = bcRctMapping[mcCollision.bcId()]; + } + products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), mcCollision.multMCFV0A(), mcCollision.multMCFT0A(), mcCollision.multMCFT0C(), mcCollision.centFT0M(), mcCollision.weight(), mcCollision.accepted(), mcCollision.attempted(), mcCollision.xsectGen(), mcCollision.xsectErr(), mcCollision.ptHard(), rctDecision, mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); products.jMcCollisionsParentIndexTable(mcCollision.globalIndex()); } PROCESS_SWITCH(JetDerivedDataProducerTask, processMcCollisions, "produces derived MC collision table", false); void processMcCollisionsWithoutCentralityAndMultiplicity(soa::Join::iterator const& mcCollision) { - products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), -1.0, -1.0, -1.0, -1.0, mcCollision.weight(), mcCollision.accepted(), mcCollision.attempted(), mcCollision.xsectGen(), mcCollision.xsectErr(), mcCollision.ptHard(), bcRctMapping[mcCollision.bcId()], mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); + uint32_t rctDecision = ~uint32_t{0}; + if (!config.isMCGenOnly) { + rctDecision = bcRctMapping[mcCollision.bcId()]; + } + products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), -1.0, -1.0, -1.0, -1.0, mcCollision.weight(), mcCollision.accepted(), mcCollision.attempted(), mcCollision.xsectGen(), mcCollision.xsectErr(), mcCollision.ptHard(), rctDecision, mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); products.jMcCollisionsParentIndexTable(mcCollision.globalIndex()); } PROCESS_SWITCH(JetDerivedDataProducerTask, processMcCollisionsWithoutCentralityAndMultiplicity, "produces derived MC collision table without centraility and multiplicity", false); void processMcCollisionsWithoutXsection(soa::Join::iterator const& mcCollision) { - products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), mcCollision.multMCFV0A(), mcCollision.multMCFT0A(), mcCollision.multMCFT0C(), mcCollision.centFT0M(), mcCollision.weight(), 1, 1, 1.0, 1.0, 999.0, bcRctMapping[mcCollision.bcId()], mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); + uint32_t rctDecision = ~uint32_t{0}; + if (!config.isMCGenOnly) { + rctDecision = bcRctMapping[mcCollision.bcId()]; + } + products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), mcCollision.multMCFV0A(), mcCollision.multMCFT0A(), mcCollision.multMCFT0C(), mcCollision.centFT0M(), mcCollision.weight(), 1, 1, 1.0, 1.0, 999.0, rctDecision, mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); products.jMcCollisionsParentIndexTable(mcCollision.globalIndex()); } PROCESS_SWITCH(JetDerivedDataProducerTask, processMcCollisionsWithoutXsection, "produces derived MC collision table without cross section information", false); void processMcCollisionsWithoutCentralityAndMultiplicityAndXsection(aod::McCollision const& mcCollision) { - products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), -1.0, -1.0, -1.0, -1.0, mcCollision.weight(), 1, 1, 1.0, 1.0, 999.0, bcRctMapping[mcCollision.bcId()], mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); + uint32_t rctDecision = ~uint32_t{0}; + if (!config.isMCGenOnly) { + rctDecision = bcRctMapping[mcCollision.bcId()]; + } + products.jMcCollisionsTable(mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), -1.0, -1.0, -1.0, -1.0, mcCollision.weight(), 1, 1, 1.0, 1.0, 999.0, rctDecision, mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); products.jMcCollisionsParentIndexTable(mcCollision.globalIndex()); } PROCESS_SWITCH(JetDerivedDataProducerTask, processMcCollisionsWithoutCentralityAndMultiplicityAndXsection, "produces derived MC collision table without centrality, multiplicity and cross section information", false); diff --git a/PWGJE/Tasks/jetFormationTimeReclustering.cxx b/PWGJE/Tasks/jetFormationTimeReclustering.cxx index f3f2348f7d5..5ea8a6e3829 100644 --- a/PWGJE/Tasks/jetFormationTimeReclustering.cxx +++ b/PWGJE/Tasks/jetFormationTimeReclustering.cxx @@ -28,6 +28,7 @@ #include "PWGJE/DataModel/Jet.h" // IWYU pragma: keep #include "PWGJE/DataModel/JetReducedData.h" #include "PWGJE/DataModel/JetReducedDataDQ.h" +#include "PWGJE/DataModel/JetSubstructure.h" // new #include @@ -37,26 +38,8 @@ namespace o2::aod { - -namespace jetcollision -{ //! -DECLARE_SOA_COLUMN(PosZ, posZ, float); //! -DECLARE_SOA_COLUMN(Centrality, centrality, float); //! -DECLARE_SOA_COLUMN(EventSel, eventSel, uint8_t); //! -DECLARE_SOA_COLUMN(EventWeight, eventWeight, float); //! -} // namespace jetcollision - -namespace jetmccollision -{ -DECLARE_SOA_COLUMN(PosZ, posZ, float); //! -DECLARE_SOA_COLUMN(Accepted, accepted, uint64_t); //! -DECLARE_SOA_COLUMN(Attempted, attempted, uint64_t); //! -DECLARE_SOA_COLUMN(XsectGen, xsectGen, float); //! -DECLARE_SOA_COLUMN(XsectErr, xsectErr, float); //! -DECLARE_SOA_COLUMN(EventWeight, eventWeight, float); //! -} // namespace jetmccollision - -namespace jetsubstructure +// new part +namespace jetTFsubstructure { //! DECLARE_SOA_COLUMN(EnergyMother, energyMother, std::vector); //! DECLARE_SOA_COLUMN(PtLeading, ptLeading, std::vector); //! @@ -71,111 +54,13 @@ DECLARE_SOA_COLUMN(Thetag, thetag, std::vector); //! DECLARE_SOA_COLUMN(Zg, zg, std::vector); //! DECLARE_SOA_COLUMN(TauFormg, tauFormg, std::vector); //! //! -} // namespace jetsubstructure - -namespace splitting -{ //! -DECLARE_SOA_COLUMN(Pt, pt, float); //! -DECLARE_SOA_COLUMN(Eta, eta, float); //! -DECLARE_SOA_COLUMN(Phi, phi, float); //! -DECLARE_SOA_COLUMN(R, r, int); //! -DECLARE_SOA_COLUMN(SplittingMatchingGeo, splittingMatchingGeo, std::vector); //! -DECLARE_SOA_COLUMN(SplittingMatchingPt, splittingMatchingPt, std::vector); //! -DECLARE_SOA_COLUMN(SplittingMatchingHF, splittingMatchingHF, std::vector); //! -} // namespace splitting - -// Defines the jet table definition -#define JETSPLITTING_TABLE_DEF(_jet_type_, _jet_description_, _name_, _track_type_, _cand_type_) \ - \ - namespace _name_##splitting \ - { \ - DECLARE_SOA_INDEX_COLUMN(_jet_type_##Jet, jet); \ - } \ - namespace _name_##splittingconstituents \ - { \ - DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(Tracks, tracks, int32_t, _track_type_, "_tracks"); \ - DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(Clusters, clusters, int32_t, JClusters, "_clusters"); \ - DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(Candidates, candidates, int32_t, _cand_type_, "_cand"); \ - } \ - DECLARE_SOA_TABLE(_jet_type_##SPs, "AOD", _jet_description_ "SP", \ - o2::soa::Index<>, \ - _name_##splitting::_jet_type_##JetId, \ - _name_##splittingconstituents::TracksIds, \ - _name_##splittingconstituents::ClustersIds, \ - _name_##splittingconstituents::CandidatesIds, \ - splitting::Pt, \ - splitting::Eta, \ - splitting::Phi, \ - splitting::R); - -namespace jetoutput -{ -DECLARE_SOA_COLUMN(JetPt, jetPt, float); //! -DECLARE_SOA_COLUMN(JetPhi, jetPhi, float); //! -DECLARE_SOA_COLUMN(JetEta, jetEta, float); //! -DECLARE_SOA_COLUMN(JetY, jetY, float); //! -DECLARE_SOA_COLUMN(JetR, jetR, float); //! -DECLARE_SOA_COLUMN(JetArea, jetArea, float); //! -DECLARE_SOA_COLUMN(JetRho, jetRho, float); //! -DECLARE_SOA_COLUMN(JetPerpConeRho, jetPerpConeRho, float); //! -DECLARE_SOA_COLUMN(JetNConstituents, jetNConstituents, int); //! -} // namespace jetoutput - -#define MCCOLL_TABLE_DEF(_jet_type_, _jet_description_, _name_) \ - namespace _name_##mccollisionoutput \ - { \ - DECLARE_SOA_DYNAMIC_COLUMN(Dummy##_jet_type_, dummy##_jet_type_, []() -> int { return 0; }); \ - } \ - DECLARE_SOA_TABLE(_jet_type_##MCCOs, "AOD", _jet_description_ "MCCO", \ - jetmccollision::PosZ, \ - jetmccollision::Accepted, \ - jetmccollision::Attempted, \ - jetmccollision::XsectGen, \ - jetmccollision::XsectErr, \ - jetmccollision::EventWeight, \ - _name_##mccollisionoutput::Dummy##_jet_type_<>); - -// Defines the jet substrcuture table definition -#define JETSUBSTRUCTURE_TABLE_DEF(_jet_type_, _jet_description_, _name_, _cand_type_, _cand_description_) \ - \ - namespace _name_##collisionoutput \ - { \ - DECLARE_SOA_DYNAMIC_COLUMN(Dummy##_jet_type_, dummy##_jet_type_, []() -> int { return 0; }); \ - } \ - \ - DECLARE_SOA_TABLE(_jet_type_##COs, "AOD", _jet_description_ "CO", jetcollision::PosZ, jetcollision::Centrality, jetcollision::EventSel, jetcollision::EventWeight, _name_##collisionoutput::Dummy##_jet_type_<>); \ - using _jet_type_##CO = _jet_type_##COs::iterator; \ - \ - namespace _name_##jetoutput \ - { \ - DECLARE_SOA_INDEX_COLUMN_CUSTOM(_jet_type_##CO, collision, _jet_description_ "COS"); \ - DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(Candidate, candidate, int, _cand_type_, _cand_description_ "S", "_0"); \ - } \ - DECLARE_SOA_TABLE(_jet_type_##Os, "AOD", _jet_description_ "O", _name_##jetoutput::_jet_type_##COId, _name_##jetoutput::CandidateId, jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetoutput::JetY, jetoutput::JetR, jetoutput::JetArea, jetoutput::JetRho, jetoutput::JetPerpConeRho, jetoutput::JetNConstituents); \ - using _jet_type_##O = _jet_type_##Os::iterator; \ - namespace _name_##substructure \ - { \ - DECLARE_SOA_INDEX_COLUMN_CUSTOM(_jet_type_##O, outputTable, _jet_description_ "OS"); \ - DECLARE_SOA_DYNAMIC_COLUMN(Dummy##_jet_type_, dummy##_jet_type_, []() -> int { return 0; }); \ - } \ - DECLARE_SOA_TABLE(_jet_type_##SSs, "AOD", _jet_description_ "SS", jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetsubstructure::EnergyMother, jetsubstructure::PtLeading, jetsubstructure::PtSubLeading, jetsubstructure::Theta, jetsubstructure::PtLeadingConstituent, jetsubstructure::TauForm, jetsubstructure::Z, jetsubstructure::Ptg, jetsubstructure::Thetag, jetsubstructure::Zg, jetsubstructure::TauFormg, _name_##substructure::Dummy##_jet_type_<>); \ - DECLARE_SOA_TABLE(_jet_type_##SSOs, "AOD", _jet_description_ "SSO", _name_##substructure::_jet_type_##OId, jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetsubstructure::EnergyMother, jetsubstructure::PtLeading, jetsubstructure::PtSubLeading, jetsubstructure::Theta, jetsubstructure::PtLeadingConstituent, jetsubstructure::TauForm, jetsubstructure::Z, jetsubstructure::Ptg, jetsubstructure::Thetag, jetsubstructure::Zg, jetsubstructure::TauFormg); \ - \ - using _jet_type_##O = _jet_type_##Os::iterator; \ - using _jet_type_##SSO = _jet_type_##SSOs::iterator; - -#define JETSUBSTRUCTURE_TABLES_DEF(_jet_type_, _jet_description_, _jet_type_full_, _jet_full_description_, _track_type_data_, _cand_type_data_, _cand_description_data_, _track_type_ewsdata_, _cand_type_ewsdata_, _cand_description_ewsdata_, _track_type_mcd_, _cand_type_mcd_, _cand_description_mcd_, _particle_type_, _hfparticle_type_, _hfparticle_description_) \ - JETSUBSTRUCTURE_TABLE_DEF(_jet_type_##Jet, _jet_description_ "JET", _jet_type_##jet, _cand_type_data_, _cand_description_data_) \ - JETSUBSTRUCTURE_TABLE_DEF(_jet_type_##EWSJet, _jet_description_ "EWSJET", _jet_type_##ewsjet, _cand_type_ewsdata_, _cand_description_ewsdata_) \ - JETSPLITTING_TABLE_DEF(_jet_type_full_, _jet_description_, _jet_full_description_, _track_type_data_, _cand_type_data_) \ - JETSPLITTING_TABLE_DEF(_jet_type_full_##EventWiseSubtracted, _jet_description_ "EWS", _jet_full_description_##eventwisesubtracted, _cand_type_ewsdata_, _cand_type_ewsdata_) \ - JETSUBSTRUCTURE_TABLE_DEF(_jet_type_##MCDJet, _jet_description_ "MCDJET", _jet_type_##mcdjet, _cand_type_mcd_, _cand_description_mcd_) \ - JETSUBSTRUCTURE_TABLE_DEF(_jet_type_##MCPJet, _jet_description_ "MCPJET", _jet_type_##mcpjet, _hfparticle_type_, _hfparticle_description_) \ - MCCOLL_TABLE_DEF(_jet_type_##MCPJet, _jet_description_ "MCPJET", _jet_type_##mcpjet) \ - JETSPLITTING_TABLE_DEF(_jet_type_full_##MCDetectorLevel, _jet_description_ "D", _jet_full_description_##mcdetectorlevel, _track_type_mcd_, _cand_type_mcd_) \ - JETSPLITTING_TABLE_DEF(_jet_type_full_##MCParticleLevel, _jet_description_ "P", _jet_full_description_##mcparticlelevel, _particle_type_, _hfparticle_type_) - -JETSUBSTRUCTURE_TABLES_DEF(C, "C", Charged, charged, JTracks, CJetCOs, "CJETCO", JTrackSubs, CEWSJetCOs, "CEWSJETCO", JTracks, CMCDJetCOs, "CMCDJETCO", JMcParticles, CMCPJetCOs, "CMCPJETCO"); +} // namespace jetTFsubstructure + +// all tables have the same content (for now) +DECLARE_SOA_TABLE(CJetTFSSs, "AOD", "CJETTFSS", jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetTFsubstructure::EnergyMother, jetTFsubstructure::PtLeading, jetTFsubstructure::PtSubLeading, jetTFsubstructure::Theta, jetTFsubstructure::PtLeadingConstituent, jetTFsubstructure::TauForm, jetTFsubstructure::Z, jetTFsubstructure::Ptg, jetTFsubstructure::Thetag, jetTFsubstructure::Zg, jetTFsubstructure::TauFormg); +DECLARE_SOA_TABLE(CMCDJetTFSSs, "AOD", "CMCDJETTFSS", jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetTFsubstructure::EnergyMother, jetTFsubstructure::PtLeading, jetTFsubstructure::PtSubLeading, jetTFsubstructure::Theta, jetTFsubstructure::PtLeadingConstituent, jetTFsubstructure::TauForm, jetTFsubstructure::Z, jetTFsubstructure::Ptg, jetTFsubstructure::Thetag, jetTFsubstructure::Zg, jetTFsubstructure::TauFormg); +DECLARE_SOA_TABLE(CMCPJetTFSSs, "AOD", "CMCPJETTFSS", jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetTFsubstructure::EnergyMother, jetTFsubstructure::PtLeading, jetTFsubstructure::PtSubLeading, jetTFsubstructure::Theta, jetTFsubstructure::PtLeadingConstituent, jetTFsubstructure::TauForm, jetTFsubstructure::Z, jetTFsubstructure::Ptg, jetTFsubstructure::Thetag, jetTFsubstructure::Zg, jetTFsubstructure::TauFormg); +DECLARE_SOA_TABLE(CEWSJetTFSSs, "AOD", "CEWSJETTFSS", jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetTFsubstructure::EnergyMother, jetTFsubstructure::PtLeading, jetTFsubstructure::PtSubLeading, jetTFsubstructure::Theta, jetTFsubstructure::PtLeadingConstituent, jetTFsubstructure::TauForm, jetTFsubstructure::Z, jetTFsubstructure::Ptg, jetTFsubstructure::Thetag, jetTFsubstructure::Zg, jetTFsubstructure::TauFormg); } // namespace o2::aod @@ -216,12 +101,12 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -struct FormationTimeReclustering { +struct JetFormationTimeReclustering { - Produces jetSubstructureDataTable; - Produces jetSubstructureMCDTable; - Produces jetSubstructureMCPTable; - Produces jetSubstructureDataSubTable; + Produces jetSubstructureDataTable; + Produces jetSubstructureMCDTable; + Produces jetSubstructureMCPTable; + Produces jetSubstructureDataSubTable; Produces jetSplittingsDataTable; Produces jetSplittingsMCDTable; @@ -320,7 +205,7 @@ struct FormationTimeReclustering { } splittingTable(jet.globalIndex(), tracks, clusters, candidates, parentSubJet2.perp(), parentSubJet2.eta(), parentSubJet2.phi(), 0); auto z = parentSubJet2.perp() / (parentSubJet1.perp() + parentSubJet2.perp()); - auto theta = parentSubJet1.delta_R(parentSubJet2); + auto theta = parentSubJet1.delta_R(parentSubJet2); // this is deltaR - divide by R in postprocessing auto tau = (parentSubJet1.perp() + parentSubJet2.perp()) / (parentSubJet1.perp() * parentSubJet2.perp() * theta * theta); // as in run2 aliphysics energyMotherVec.push_back(daughterSubJet.e()); ptLeadingVec.push_back(parentSubJet1.pt()); @@ -387,28 +272,28 @@ struct FormationTimeReclustering { void processDummy(aod::JetTracks const&) { } - PROCESS_SWITCH(FormationTimeReclustering, processDummy, "Dummy process function turned on by default", true); + PROCESS_SWITCH(JetFormationTimeReclustering, processDummy, "Dummy process function turned on by default", true); void processChargedJetsData(soa::Join::iterator const& jet, aod::JetTracks const& tracks) { analyseCharged(jet, tracks, TracksPerCollision, jetSubstructureDataTable, jetSplittingsDataTable); } - PROCESS_SWITCH(FormationTimeReclustering, processChargedJetsData, "charged jet substructure", false); + PROCESS_SWITCH(JetFormationTimeReclustering, processChargedJetsData, "charged jet substructure", false); void processChargedJetsEventWiseSubData(soa::Join::iterator const& jet, aod::JetTracksSub const& tracks) { analyseCharged(jet, tracks, TracksPerCollisionDataSub, jetSubstructureDataSubTable, jetSplittingsDataSubTable); } - PROCESS_SWITCH(FormationTimeReclustering, processChargedJetsEventWiseSubData, "eventwise-constituent subtracted charged jet substructure", false); + PROCESS_SWITCH(JetFormationTimeReclustering, processChargedJetsEventWiseSubData, "eventwise-constituent subtracted charged jet substructure", false); void processChargedJetsMCD(typename soa::Join::iterator const& jet, aod::JetTracks const& tracks) { analyseCharged(jet, tracks, TracksPerCollision, jetSubstructureMCDTable, jetSplittingsMCDTable); } - PROCESS_SWITCH(FormationTimeReclustering, processChargedJetsMCD, "charged jet substructure", false); + PROCESS_SWITCH(JetFormationTimeReclustering, processChargedJetsMCD, "charged jet substructure", false); void processChargedJetsMCP(typename soa::Join::iterator const& jet) { @@ -422,12 +307,12 @@ struct FormationTimeReclustering { jetReclustering(jet, jetSplittingsMCPTable); jetSubstructureMCPTable(ptJet, phiJet, etaJet, energyMotherVec, ptLeadingVec, ptSubLeadingVec, thetaVec, leadingConstituentPt, tauFormVec, zVec, ptgVec, thetagVec, zgVec, taugVec); } - PROCESS_SWITCH(FormationTimeReclustering, processChargedJetsMCP, "charged jet substructure on MC particle level", false); + PROCESS_SWITCH(JetFormationTimeReclustering, processChargedJetsMCP, "charged jet substructure on MC particle level", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask( - cfgc, TaskName{"jet-formationtimereclustering"})}; + return WorkflowSpec{adaptAnalysisTask( + cfgc, TaskName{"jet-formation-time-reclustering"})}; } diff --git a/PWGLF/DataModel/LFPhiStrangeCorrelationTables.h b/PWGLF/DataModel/LFPhiStrangeCorrelationTables.h index e755053e077..589aebb3960 100644 --- a/PWGLF/DataModel/LFPhiStrangeCorrelationTables.h +++ b/PWGLF/DataModel/LFPhiStrangeCorrelationTables.h @@ -37,7 +37,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(InMassRegion, inMassRegion, }); } // namespace lf_selection_phi_candidate -DECLARE_SOA_TABLE(PhimesonCandidatesData, "AOD", "PHICANDIDATESDATA", +DECLARE_SOA_TABLE(PhimesonCandidatesData, "AOD", "PHICANDDATA", lf_selection_phi_candidate::CollisionId, lf_selection_phi_candidate::M, lf_selection_phi_candidate::Pt, @@ -45,7 +45,7 @@ DECLARE_SOA_TABLE(PhimesonCandidatesData, "AOD", "PHICANDIDATESDATA", lf_selection_phi_candidate::Phi, lf_selection_phi_candidate::InMassRegion); -DECLARE_SOA_TABLE(PhimesonCandidatesMcReco, "AOD", "PHICANDIDATESMCRECO", +DECLARE_SOA_TABLE(PhimesonCandidatesMcReco, "AOD", "PHICANDMCRECO", lf_selection_phi_candidate::CollisionId, lf_selection_phi_candidate::M, lf_selection_phi_candidate::Pt, @@ -53,7 +53,7 @@ DECLARE_SOA_TABLE(PhimesonCandidatesMcReco, "AOD", "PHICANDIDATESMCRECO", lf_selection_phi_candidate::Phi, lf_selection_phi_candidate::InMassRegion); -DECLARE_SOA_TABLE(PhimesonCandidatesMcGen, "AOD", "PHICANDIDATESMCGEN", +DECLARE_SOA_TABLE(PhimesonCandidatesMcGen, "AOD", "PHICANDMCGEN", lf_selection_phi_candidate::CollisionId, lf_selection_phi_candidate::M, lf_selection_phi_candidate::Pt, diff --git a/PWGLF/DataModel/ReducedHeptaQuarkTables.h b/PWGLF/DataModel/ReducedHeptaQuarkTables.h index b547933cb59..76cc71beb09 100644 --- a/PWGLF/DataModel/ReducedHeptaQuarkTables.h +++ b/PWGLF/DataModel/ReducedHeptaQuarkTables.h @@ -38,6 +38,8 @@ DECLARE_SOA_TABLE(RedHQEvents, "AOD", "REDHQEVENT", bc::GlobalBC, bc::RunNumber, timestamp::Timestamp, + collision::PosX, + collision::PosY, collision::PosZ, collision::NumContrib, redhqevent::Centrality, diff --git a/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx b/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx index d2f5bcd6102..c78c137de02 100644 --- a/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/lnnRecoTask.cxx @@ -8,14 +8,13 @@ // 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. -// -// Build \Lambda-n-n candidates from V0s and tracks + +/// \file lnnRecoTask.cxx +/// \brief Reconstruction task for the \Lambda nn candidate +/// \author Maria Paula Palhares // ============================================================================== -#include "PWGLF/DataModel/EPCalibrationTables.h" #include "PWGLF/DataModel/LFLnnTables.h" -#include "Common/Core/PID/PIDTOF.h" -#include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" @@ -29,17 +28,17 @@ #include "DCAFitter/DCAFitterN.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" -#include "MathUtils/BetheBlochAleph.h" #include "DetectorsBase/GeometryManager.h" #include "DetectorsBase/Propagator.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" +#include "MathUtils/BetheBlochAleph.h" +#include "PID/PIDTOF.h" +#include "PID/TPCPIDResponse.h" #include "ReconstructionDataFormats/Track.h" -#include - #include #include #include @@ -57,9 +56,10 @@ using CollisionsFullMC = soa::Join betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; -static const std::vector NucleiName{"3H"}; +static const std::vector nucleiName{"3H"}; +// Histograms for QA lnn-task std::shared_ptr hEvents; std::shared_ptr hZvtx; std::shared_ptr hCentFT0A; @@ -70,15 +70,39 @@ std::shared_ptr hNsigma3HSel; std::shared_ptr hNsigma3HSelTOF; std::shared_ptr hdEdx3HSel; std::shared_ptr hdEdx3HPosTrack; +std::shared_ptr hdEdx3HNegTrack; std::shared_ptr hdEdxTot; std::shared_ptr h3HMassPtTOF; std::shared_ptr h3HSignalPtTOF; -std::shared_ptr hDecayChannel; std::shared_ptr hIsMatterGen; -std::shared_ptr hIsMatterGenTwoBody; -std::shared_ptr hDCAxy3H; std::shared_ptr hLnnCandLoss; -std::shared_ptr hNSigma3HTPC_preselection; +std::shared_ptr hDecayChannel; +// QA histograms before track selections +std::shared_ptr h2FT0CnClusTPCtoTrBfSel; +std::shared_ptr h2FT0CnClusTPCtoPiBfSel; +std::shared_ptr h2FT0Cchi2NClTPCtoTrBfSel; +std::shared_ptr h2FT0Cchi2NClITStoTrBfSel; +// QA ITS-TPC and ITS-TPC-TOF track signals +std::shared_ptr h2FT0CptTrBfSelItsTpc; +std::shared_ptr h2FT0CptTrBfSelItsTpcTof; +std::shared_ptr h2FT0CptPiBfSelItsTpc; +std::shared_ptr h2FT0CptTrSelItsTpc; +std::shared_ptr h2FT0CptTrSelItsTpcTof; +std::shared_ptr h2FT0CptPiSelItsTpc; +// QA generated candidate and daugher particles from secondary vertex +std::shared_ptr h2FT0CptGenCandMC; +std::shared_ptr h2FT0CetaGenCandMC; +std::shared_ptr h2FT0CPtGenTrStrMC; +std::shared_ptr h2FT0CetaGenTrStrMC; +std::shared_ptr h2FT0CPtGenPiStrMC; +std::shared_ptr h2FT0CetaGenPiStrMC; +// QA reconstructed candidate and daugher particles from secondary vertex +std::shared_ptr h2FT0CptRecCandMC; +std::shared_ptr h2FT0CetaRecCandMC; +std::shared_ptr h2FT0CPtRecTrStrMC; +std::shared_ptr h2FT0CetaRecTrStrMC; +std::shared_ptr h2FT0CPtRecPiStrMC; +std::shared_ptr h2FT0CetaRecPiStrMC; float alphaAP(std::array const& momB, std::array const& momC) { @@ -91,18 +115,27 @@ float alphaAP(std::array const& momB, std::array const& momC } // namespace -struct lnnCandidate { +struct LnnCandidate { float recoPt3H() const { return std::hypot(mom3H[0], mom3H[1]); } float recoPhi3H() const { return std::atan2(mom3H[1], mom3H[0]); } float recoEta3H() const { return std::asinh(mom3H[2] / recoPt3H()); } + float recoPtPi() const { return std::hypot(momPi[0], momPi[1]); } float recoPhiPi() const { return std::atan2(momPi[1], momPi[0]); } float recoEtaPi() const { return std::asinh(momPi[2] / recoPtPi()); } + float genPt() const { return std::hypot(gMom[0], gMom[1]); } - float genPt3H() const { return std::hypot(gMom3H[0], gMom3H[1]); } float genPhi() const { return std::atan2(gMom[1], gMom[0]); } float genEta() const { return std::asinh(gMom[2] / genPt()); } + float genPt3H() const { return std::hypot(gMom3H[0], gMom3H[1]); } + float genPhi3H() const { return std::atan2(gMom3H[1], gMom3H[0]); } + float genEta3H() const { return std::asinh(gMom3H[2] / genPt3H()); } + + float genPtPi() const { return std::hypot(gMomPi[0], gMomPi[1]); } + float genPhiPi() const { return std::atan2(gMomPi[1], gMomPi[0]); } + float genEtaPi() const { return std::asinh(gMomPi[2] / genPtPi()); } + int posTrackID; int negTrackID; float dcaV0dau = -10; @@ -113,8 +146,8 @@ struct lnnCandidate { float mom3HTPC = -10.f; float momPiTPC = -10.f; float mass2TrTOF = -10.f; - float DCAPvto3H = -10.f; - float DCAPvtoPi = -10.f; + float dcaPvto3H = -10.f; + float dcaPvtoPi = -10.f; float beta = -10.f; float tpcChi3H = -10.f; std::array mom3H; @@ -122,6 +155,7 @@ struct lnnCandidate { std::array decVtx; std::array gMom; std::array gMom3H; + std::array gMomPi; std::array gDecVtx; uint16_t tpcSignal3H = 0u; uint16_t tpcSignalPi = 0u; @@ -144,23 +178,24 @@ struct lnnRecoTask { Service ccdb; // Selection criteria - Configurable v0cospa{"lnncospa", 0.95, "V0 CosPA"}; - Configurable masswidth{"lnnmasswidth", 0.1, "Mass width (GeV/c^2)"}; - Configurable dcav0dau{"lnndcaDau", 0.6, "DCA V0 Daughters"}; - Configurable Chi2nClusTPCMax{"Chi2NClusTPCMax", 4, "Chi2 / nClusTPC for triton track max"}; - Configurable Chi2nClusTPCMin{"Chi2NClusTPC", 0.5, "Chi2 / nClusTPC for triton track min"}; - Configurable Chi2nClusITS{"Chi2NClusITS", 36., "Chi2 / nClusITS for triton track"}; + Configurable v0cospa{"v0cospa", 0.95, "V0 CosPA"}; + Configurable masswidth{"masswidth", 0.1, "Mass width (GeV/c^2)"}; + Configurable dcav0dau{"dcav0dau", 0.6, "DCA V0 Daughters"}; + Configurable chi2nClusTPCMax{"chi2nClusTPCMax", 4, "Chi2 / nClusTPC for triton track max"}; + Configurable chi2nClusTPCMin{"chi2nClusTPCMin", 0.5, "Chi2 / nClusTPC for triton track min"}; + Configurable chi2nClusITS{"chi2nClusITS", 36., "Chi2 / nClusITS for triton track"}; Configurable ptMin{"ptMin", 0.5, "Minimum pT of the lnncandidate"}; - Configurable etaMax{"eta", 0.8, "eta daughter"}; - Configurable TPCRigidityMin3H{"TPCRigidityMin3H", 0.2, "Minimum rigidity of the triton candidate"}; + Configurable etaMax{"etaMax", 0.8, "eta daughter"}; + Configurable tpcRigidityMin3H{"tpcRigidityMin3H", 0.2, "Minimum rigidity of the triton candidate"}; Configurable nSigmaCutMinTPC{"nSigmaCutMinTPC", -5, "triton dEdx cut (n sigma)"}; Configurable nSigmaCutMaxTPC{"nSigmaCutMaxTPC", 5, "triton dEdx cut (n sigma)"}; Configurable nTPCClusMin3H{"nTPCClusMin3H", 80, "triton NTPC clusters cut"}; Configurable nTPCClusMinPi{"nTPCClusMinPi", 60, "pion NTPC clusters cut"}; Configurable ptMinTOF{"ptMinTOF", 0.8, "minimum pt for TOF cut"}; - Configurable TrTOFMass2Cut{"TrTOFMass2Cut", 5.5, "minimum Triton mass square to TOF"}; - Configurable BetaTrTOF{"BetaTrTOF", 0.4, "minimum beta TOF cut"}; + Configurable trTOFMass2Cut{"trTOFMass2Cut", 5.5, "minimum Triton mass square to TOF"}; + Configurable betaTrTOF{"betaTrTOF", 0.4, "minimum beta TOF cut"}; Configurable mcSignalOnly{"mcSignalOnly", true, "If true, save only signal in MC"}; + Configurable doTrackQA{"doTrackQA", true, "If true, compute the QA studies beased on detectors (ITS-TPC-TOF) signals"}; // Define o2 fitter, 2-prong, active memory (no need to redefine per event) o2::vertexing::DCAFitterN<2> fitter; @@ -170,12 +205,12 @@ struct lnnRecoTask { float piMass = o2::constants::physics::MassPionCharged; // bethe bloch parameters - Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], 1, 6, NucleiName, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for 3H"}; + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {BetheBlochDefault[0], 1, 6, nucleiName, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for 3H"}; Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; // CCDB options - Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable d_bz_input{"d_bz_input", -999., "bz field, -999 is automatic"}; + Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; @@ -184,23 +219,30 @@ struct lnnRecoTask { // PDG codes Configurable h3DauPdg{"h3DauPdg", 1000010030, "PDG Triton"}; // PDG Triton + Configurable piDauPdg{"piDauPdg", 211, "PDG Pi"}; // PDG Pi Configurable lnnPdg{"lnnPdg", 1010000030, "PDG Lnn"}; // PDG Lnn - // histogram axes - ConfigurableAxis rigidityBins{"rigidityBins", {200, -10.f, 10.f}, "Binning for rigidity #it{p}^{TPC}/#it{z}"}; + // Histogram configuration QA lnn-task + ConfigurableAxis rigidityBins{"rigidityBins", {200, -10.f, 10.f}, "Binning for rigidity"}; ConfigurableAxis dEdxBins{"dEdxBins", {5000, 0.f, 1000.f}, "Binning for dE/dx"}; - ConfigurableAxis nSigmaBins{"nSigmaBins", {200, -5.f, 5.f}, "Binning for n sigma"}; - ConfigurableAxis zVtxBins{"zVtxBins", {100, -20.f, 20.f}, "Binning for n sigma"}; + ConfigurableAxis nSigmaBins{"nSigmaBins", {200, -5.f, 5.f}, "Binning for n#sigma_{TPC}"}; + ConfigurableAxis zVtxBins{"zVtxBins", {100, -20.f, 20.f}, "Binning for vtx z"}; ConfigurableAxis centBins{"centBins", {100, 0.f, 100.f}, "Binning for centrality"}; - ConfigurableAxis TritMomBins{"TritMomBins", {100, -5.f, 5.f}, "Binning for Triton momentum"}; - ConfigurableAxis MassTOFBins{"MassTOFBins", {400, 2.0f, 12.f}, "Binning for Triton Mass TOF"}; - ConfigurableAxis PtTritonBins{"PtTritonBins", {200, -5.f, 5.f}, "Binning for Triton p values"}; - ConfigurableAxis PtPosTritonBins{"PtPosTritonBins", {200, 0.f, 5.f}, "Binning for Triton pt positive values"}; - ConfigurableAxis BetaBins{"BetaBins", {550, 0.f, 1.1f}, "Binning for Beta"}; - ConfigurableAxis DCAxyBins{"DCAxyBins", {550, -5.f, 5.f}, "Binning for DCAxy"}; + ConfigurableAxis mTOFBins{"mTOFBins", {400, 2.0f, 12.f}, "Binning for triton mass TOF"}; + ConfigurableAxis tPtBins{"tPtBins", {200, -5.f, 5.f}, "Binning for (anti-)triton pt"}; + ConfigurableAxis tPtPosBins{"tPtPosBins", {100, 0, 5.f}, "Binning for (anti-)triton pt > 0"}; + ConfigurableAxis tPPosBins{"tPPosBins", {200, 0.f, 5.f}, "Binning for triton rigidity (p)"}; + ConfigurableAxis tPNegBins{"tPNegBins", {200, -5.f, 0.f}, "Binning for anti-triton rigidity (p)"}; + ConfigurableAxis betaBins{"betaBins", {550, 0.f, 1.1f}, "Binning for Beta"}; + ConfigurableAxis dcaXYBins{"dcaXYBins", {550, -5.f, 5.f}, "Binning for dcaXY triton"}; + ConfigurableAxis tpcNClusBins{"tpcNClusBins", {260, 30, 165}, "Binning for nClusTPC"}; + ConfigurableAxis tpcChi2NClusBins{"tpcChi2NClusBins", {20, 0.5, 10}, "Binning for chi2NClusTPC"}; + ConfigurableAxis itsChi2NClusBins{"itsChi2NClusBins", {72, 0, 36}, "Binning for chi2NClusTPC"}; + ConfigurableAxis candPtBins{"candPtBins", {100, 0, 10}, "Binning for lnn cand pt"}; + ConfigurableAxis candEtaBins{"candEtaBins", {160, -0.8, 0.8}, "Binning for eta"}; // std vector of candidates - std::vector lnnCandidates; + std::vector lnnCandidates; // vector to keep track of MC mothers already filled std::vector filledMothers; // vector to keep track of the collisions passing the event selection in the MC @@ -241,31 +283,47 @@ struct lnnRecoTask { const AxisSpec dEdxAxis{dEdxBins, "d#it{E}/d#it{x}"}; const AxisSpec nSigma3HAxis{nSigmaBins, "n_{#sigma}({}^{3}H)"}; const AxisSpec zVtxAxis{zVtxBins, "z_{vtx} (cm)"}; - const AxisSpec centAxis{centBins, "Centrality"}; - const AxisSpec TritMomAxis{TritMomBins, "#it{p}({}^{3}H)"}; - const AxisSpec PtTrAxis{PtTritonBins, "#it{p_T}({}^{3}H)"}; - const AxisSpec PtPosTrAxis{PtPosTritonBins, "#it{p_T}({}^{3}H)"}; - const AxisSpec MassTOFAxis{MassTOFBins, "{m}^{2}/{z}^{2}"}; - const AxisSpec BetaAxis{BetaBins, "#beta (TOF)"}; - const AxisSpec DCAxyAxis(DCAxyBins, "DCAxy ({}^{3}H) (cm)"); - - hNsigma3HSel = qaRegistry.add("hNsigma3HSel", "; #it{p}_{TPC}/z (GeV/#it{c}); n_{#sigma} ({}^{3}H)", HistType::kTH2F, {rigidityAxis, nSigma3HAxis}); - hNsigma3HSelTOF = qaRegistry.add("hNsigma3HSelTOF", "; Signed p_{T} ({}^{3}H) (GeV/#it{c^2}); n#sigma_{TOF} ({}^{3}H)", HistType::kTH2F, {PtTrAxis, nSigma3HAxis}); - hdEdx3HSel = qaRegistry.add("hdEdx3HSel", ";#it{p}_{TPC}/z (GeV/#it{c}); dE/dx", HistType::kTH2F, {rigidityAxis, dEdxAxis}); - hdEdx3HPosTrack = qaRegistry.add("hdEdx3HPosTrack", "; #it{p}^{TPC}({}^{3}H); dE/dx", HistType::kTH2F, {TritMomAxis, dEdxAxis}); + const AxisSpec centAxis{centBins, "FT0C (%)"}; + const AxisSpec mTOFAxis{mTOFBins, "#frac{m^{2}}{z^{2}}"}; + const AxisSpec tPtAxis{tPtBins, "#it{p}_{T} (Gev/#it{c})"}; + const AxisSpec tPosRigidityAxis{tPPosBins, "#it{p}^{TPC}/#it{z}"}; + const AxisSpec tPNegRigidityAxis{tPNegBins, "#it{p}^{TPC}/#it{z}"}; + const AxisSpec betaAxis{betaBins, "#beta_{TOF}"}; + const AxisSpec dcaXYAxis(dcaXYBins, "DCA_{xy} ({}^{3}H (cm)"); + const AxisSpec tpcNClusAxis(tpcNClusBins, "N_{clus}^{TPC}"); + const AxisSpec tpcChi2NClusAxis(tpcChi2NClusBins, "{#Chi}^{2}/N_{clus}^{TPC}"); + const AxisSpec itsChi2NClusAxis(itsChi2NClusBins, "{#Chi}^{2}/N_{clus}^{ITS}"); + const AxisSpec candPtAxis(candPtBins, "#it{p}_{T} (Gev/#it{c})"); + const AxisSpec candEtaAxis(candEtaBins, "#eta"); + + hNsigma3HSel = qaRegistry.add("PID/hNsigma3HSel", ";#it{p}^{TPC}/z (GeV/#it{c}); n_{#sigma} ({}^{3}H)", HistType::kTH2F, {rigidityAxis, nSigma3HAxis}); + hNsigma3HSelTOF = qaRegistry.add("PID/hNsigma3HSelTOF", ";#it{p}_{T} (GeV/#it{c}); n_{#sigma} ({}^{3}H)", HistType::kTH2F, {tPtAxis, nSigma3HAxis}); + hdEdx3HSel = qaRegistry.add("hdEdx3HSel", ";#it{p}^{TPC}/z (GeV/#it{c}); dE/dx", HistType::kTH2F, {rigidityAxis, dEdxAxis}); + hdEdx3HPosTrack = qaRegistry.add("PID/hdEdx3HPosTrack", "; #it{p}^{TPC}/z (GeV/#it{c}); dE/dx", HistType::kTH2F, {tPosRigidityAxis, dEdxAxis}); + hdEdx3HNegTrack = qaRegistry.add("PID/hdEdx3HNegTrack", "; #it{p}^{TPC}/z (GeV/#it{c}); dE/dx", HistType::kTH2F, {tPNegRigidityAxis, dEdxAxis}); hdEdxTot = qaRegistry.add("hdEdxTot", ";p_{TPC}/z (GeV/#it{c}); dE/dx", HistType::kTH2F, {rigidityAxis, dEdxAxis}); - h3HMassPtTOF = qaRegistry.add("hTrMassPtTOF", "; #it{p}_{T}({}^{3}H) (#it{GeV}^2/#it{c}^4); m^{2}/z", HistType::kTH2F, {PtTrAxis, MassTOFAxis}); - h3HSignalPtTOF = qaRegistry.add("h3HSignalPtTOF", "; #it{p}_{T}({}^{3}H) (GeV/#it{c}); #beta (TOF)", HistType::kTH2F, {PtTrAxis, BetaAxis}); - hDCAxy3H = qaRegistry.add("hDCAxy3H", "; #it{p}_{T}({}^{3}H) (GeV/#it{c}); #it{DCA}_{xy} 3H", HistType::kTH2F, {PtPosTrAxis, DCAxyAxis}); + h3HMassPtTOF = qaRegistry.add("PID/hTrMassPtTOF", "; #it{p}_{T} ({}^{3}H) (GeV/#it{c}); #frac{m^{2}}{z^{2}} (GeV^{2}/#it{c}^{4})", HistType::kTH2F, {tPtAxis, mTOFAxis}); + h3HSignalPtTOF = qaRegistry.add("PID/h3HSignalPtTOF", "; #it{p}_{T}({}^{3}H) (GeV/#it{c}); #beta_{TOF}", HistType::kTH2F, {tPtAxis, betaAxis}); hEvents = qaRegistry.add("hEvents", ";Events; ", HistType::kTH1D, {{2, -0.5, 1.5}}); - hLnnCandLoss = qaRegistry.add("hLnnCandLoss", ";CandLoss; ", HistType::kTH1D, {{7, -0.5, 6.5}}); - hNSigma3HTPC_preselection = qaRegistry.add("hNSigma3HTPC_preselection", "#it{p}/z (GeV/#it{c}); n#sigma_{TPC}(^{3}H)", HistType::kTH2F, {rigidityAxis, nSigma3HAxis}); + hLnnCandLoss = qaRegistry.add("CandCounts/hLnnCandLoss", ";CandLoss; ", HistType::kTH1D, {{7, -0.5, 6.5}}); + // QA tracks before selection + h2FT0CnClusTPCtoTrBfSel = qaRegistry.add("QATracks/h2FT0CnClusTPCtoTrBfSel", ";FT0C (%);N_{clus}^{TPC}", HistType::kTH2F, {centAxis, tpcNClusAxis}); + h2FT0CnClusTPCtoPiBfSel = qaRegistry.add("QATracks/h2FT0CnClusTPCtoPiBfSel", ";FT0C (%);N_{clus}^{TPC}", HistType::kTH2F, {centAxis, tpcNClusAxis}); + h2FT0Cchi2NClTPCtoTrBfSel = qaRegistry.add("QATracks/h2FT0Cchi2NClTPCtoTrBfSel", ";FT0C (%);{#Chi}^{2}/N_{clus}^{TPC} ", HistType::kTH2F, {centAxis, tpcChi2NClusAxis}); + h2FT0Cchi2NClITStoTrBfSel = qaRegistry.add("QATracks/h2FT0Cchi2NClITStoTrBfSel", ";FT0C (%);{#Chi}^{2}/N_{clus}^{ITS}", HistType::kTH2F, {centAxis, itsChi2NClusAxis}); + // QA its-tpc and its-tpc-tof studies + h2FT0CptTrBfSelItsTpc = qaRegistry.add("QATracks/itstpc/h2FT0CptTrBfSelItsTpc", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, tPtAxis}); + h2FT0CptTrBfSelItsTpcTof = qaRegistry.add("QATracks/itstpctof/h2FT0CptTrBfSelItsTpcTof", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, tPtAxis}); + h2FT0CptPiBfSelItsTpc = qaRegistry.add("QATracks/itstpc/h2FT0CptPiBfSelItsTpc", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, tPtAxis}); + h2FT0CptTrSelItsTpc = qaRegistry.add("QATracks/itstpc/h2FT0CptTrSelItsTpc", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, tPtAxis}); + h2FT0CptTrSelItsTpcTof = qaRegistry.add("QATracks/itstpctof/h2FT0CptTrSelItsTpcTof", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, tPtAxis}); + h2FT0CptPiSelItsTpc = qaRegistry.add("QATracks/itstpc/h2FT0CptPiSelItsTpc", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, tPtAxis}); hEvents->GetXaxis()->SetBinLabel(1, "All"); hEvents->GetXaxis()->SetBinLabel(2, "sel8"); - hLnnCandLoss->GetYaxis()->SetTitle("#it{N}_{candidates}"); + hLnnCandLoss->GetYaxis()->SetTitle("#it{N}_{cand}"); hLnnCandLoss->GetXaxis()->SetTitle("Cuts"); - hLnnCandLoss->GetXaxis()->SetBinLabel(1, "Initial LnnCandidates"); + hLnnCandLoss->GetXaxis()->SetBinLabel(1, "Initial"); hLnnCandLoss->GetXaxis()->SetBinLabel(2, "not 3H"); hLnnCandLoss->GetXaxis()->SetBinLabel(3, "not anti3H"); hLnnCandLoss->GetXaxis()->SetBinLabel(4, "#it{p}_{Tmin}"); @@ -273,14 +331,25 @@ struct lnnRecoTask { hLnnCandLoss->GetXaxis()->SetBinLabel(6, "DCA #it{V}_{0} daughter"); hLnnCandLoss->GetXaxis()->SetBinLabel(7, "cosPA"); if (doprocessMC) { - hDecayChannel = qaRegistry.add("hDecayChannel", ";Decay channel; ", HistType::kTH1D, {{2, -0.5, 1.5}}); + hDecayChannel = qaRegistry.add("MC/hDecayChannel", ";Decay channel; ", HistType::kTH1D, {{2, -0.5, 1.5}}); hDecayChannel->GetXaxis()->SetBinLabel(1, "2-body"); - hIsMatterGen = qaRegistry.add("hIsMatterGen", ";; ", HistType::kTH1D, {{2, -0.5, 1.5}}); + hIsMatterGen = qaRegistry.add("MC/hIsMatterGen", ";; ", HistType::kTH1D, {{2, -0.5, 1.5}}); hIsMatterGen->GetXaxis()->SetBinLabel(1, "Matter"); hIsMatterGen->GetXaxis()->SetBinLabel(2, "Antimatter"); - hIsMatterGenTwoBody = qaRegistry.add("hIsMatterGenTwoBody", ";; ", HistType::kTH1D, {{2, -0.5, 1.5}}); - hIsMatterGenTwoBody->GetXaxis()->SetBinLabel(1, "Matter"); - hIsMatterGenTwoBody->GetXaxis()->SetBinLabel(2, "Antimatter"); + // QA for generated mother candidate and daughter particles + h2FT0CptGenCandMC = qaRegistry.add("MC/QAGenSV/h2FT0CptGenCandMC", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, candPtAxis}); + h2FT0CetaGenCandMC = qaRegistry.add("MC/QAGenSV/h2FT0CetaGenCandMC", ";FT0C (%);#eta", HistType::kTH2F, {centAxis, candEtaAxis}); + h2FT0CPtGenTrStrMC = qaRegistry.add("MC/QAGenSV/h2FT0CPtGenTrStrMC", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, candPtAxis}); + h2FT0CetaGenTrStrMC = qaRegistry.add("MC/QAGenSV/h2FT0CetaGenTrStrMC", ";FT0C (%);#eta", HistType::kTH2F, {centAxis, candEtaAxis}); + h2FT0CPtGenPiStrMC = qaRegistry.add("MC/QAGenSV/h2FT0CPtGenPiStrMC", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, candPtAxis}); + h2FT0CetaGenPiStrMC = qaRegistry.add("MC/QAGenSV/h2FT0CetaGenPiStrMC", ";FT0C (%);#eta", HistType::kTH2F, {centAxis, candEtaAxis}); + // QA for generated mother candidate and daughter particles which were reconstructed + h2FT0CptRecCandMC = qaRegistry.add("MC/QARecSV/h2FT0CptRecCandMC", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, candPtAxis}); + h2FT0CetaRecCandMC = qaRegistry.add("MC/QARecSV/h2FT0CetaRecCandMC", ";FT0C (%);#eta", HistType::kTH2F, {centAxis, candEtaAxis}); + h2FT0CPtRecTrStrMC = qaRegistry.add("MC/QARecSV/h2FT0CPtRecTrStrMC", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, candPtAxis}); + h2FT0CetaRecTrStrMC = qaRegistry.add("MC/QARecSV/h2FT0CetaRecTrStrMC", ";FT0C (%);#eta", HistType::kTH2F, {centAxis, candEtaAxis}); + h2FT0CPtRecPiStrMC = qaRegistry.add("MC/QARecSV/h2FT0CPtRecPiStrMC", ";FT0C (%);#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {centAxis, candPtAxis}); + h2FT0CetaRecPiStrMC = qaRegistry.add("MC/QARecSV/h2FT0CetaRecPiStrMC", ";FT0C (%);#eta", HistType::kTH2F, {centAxis, candEtaAxis}); } hZvtx = qaRegistry.add("hZvtx", ";z_{vtx} (cm); ", HistType::kTH1D, {{100, -20, 20}}); hCentFT0A = qaRegistry.add("hCentFT0A", ";Centrality; ", HistType::kTH1D, {{100, 0, 100}}); @@ -297,11 +366,13 @@ struct lnnRecoTask { } auto run3grp_timestamp = bc.timestamp(); + static const double kBzAutoThreshold = -990.; + o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); o2::parameters::GRPMagField* grpmag = 0x0; if (grpo) { o2::base::Propagator::initFieldFromGRP(grpo); - if (d_bz_input < -990) { + if (d_bz_input < kBzAutoThreshold) { // Fetch magnetic field from ccdb for current collision d_bz = grpo->getNominalL3Field(); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -314,7 +385,7 @@ struct lnnRecoTask { LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; } o2::base::Propagator::initFieldFromGRP(grpmag); - if (d_bz_input < -990) { + if (d_bz_input < kBzAutoThreshold) { // Fetch magnetic field from ccdb for current collision d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -343,7 +414,7 @@ struct lnnRecoTask { LOG(fatal) << "Bethe-Bloch parameters for 3H not set, please check your CCDB and configuration"; } - for (auto& v0 : V0s) { + for (const auto& v0 : V0s) { auto posTrack = v0.posTrack_as(); auto negTrack = v0.negTrack_as(); @@ -378,7 +449,7 @@ struct lnnRecoTask { std::array momPos = std::array{posTrack.px(), posTrack.py(), posTrack.pz()}; std::array momNeg = std::array{negTrack.px(), negTrack.py(), negTrack.pz()}; float alpha = alphaAP(momPos, momNeg); - lnnCandidate lnnCand; + LnnCandidate lnnCand; lnnCand.isMatter = alpha > 0; hLnnCandLoss->Fill(0.); if ((lnnCand.isMatter && !is3H) || (!lnnCand.isMatter && !isAnti3H)) { @@ -394,11 +465,33 @@ struct lnnRecoTask { auto& pitrack = lnnCand.isMatter ? negTrack : posTrack; auto& h3Rigidity = lnnCand.isMatter ? posRigidity : negRigidity; - if (h3Rigidity < TPCRigidityMin3H || + // fill QA track histogram studies before selection + h2FT0CnClusTPCtoTrBfSel->Fill(collision.centFT0C(), h3track.tpcNClsFound()); + h2FT0CnClusTPCtoPiBfSel->Fill(collision.centFT0C(), pitrack.tpcNClsFound()); + h2FT0Cchi2NClTPCtoTrBfSel->Fill(collision.centFT0C(), h3track.tpcChi2NCl()); + h2FT0Cchi2NClITStoTrBfSel->Fill(collision.centFT0C(), h3track.itsChi2NCl()); + + if (doTrackQA) { + bool passedTrTrackITS = h3track.hasITS(); + bool passedTrTrackTOF = h3track.hasTOF(); + bool passedPiTrackITS = pitrack.hasITS(); + + if (passedTrTrackITS) { + h2FT0CptTrBfSelItsTpc->Fill(collision.centFT0C(), h3track.pt()); + } + if (passedTrTrackITS && passedTrTrackTOF) { + h2FT0CptTrBfSelItsTpcTof->Fill(collision.centFT0C(), h3track.pt()); + } + if (passedPiTrackITS) { + h2FT0CptPiBfSelItsTpc->Fill(collision.centFT0C(), pitrack.pt()); + } + } + + if (h3Rigidity < tpcRigidityMin3H || h3track.tpcNClsFound() < nTPCClusMin3H || - h3track.tpcChi2NCl() < Chi2nClusTPCMin || - h3track.tpcChi2NCl() > Chi2nClusTPCMax || - h3track.itsChi2NCl() > Chi2nClusITS || + h3track.tpcChi2NCl() < chi2nClusTPCMin || + h3track.tpcChi2NCl() > chi2nClusTPCMax || + h3track.itsChi2NCl() > chi2nClusITS || pitrack.tpcNClsFound() < nTPCClusMinPi) { continue; } @@ -423,14 +516,13 @@ struct lnnRecoTask { float beta = -1.f; if (h3track.pt() >= ptMinTOF) { - hNSigma3HTPC_preselection->Fill(h3track.tpcInnerParam(), lnnCand.nSigma3H); if (!h3track.hasTOF()) { continue; } beta = h3track.beta(); lnnCand.mass2TrTOF = h3track.mass() * h3track.mass(); - if (lnnCand.mass2TrTOF < TrTOFMass2Cut || beta < BetaTrTOF) { + if (lnnCand.mass2TrTOF < trTOFMass2Cut || beta < betaTrTOF) { continue; } } @@ -459,7 +551,8 @@ struct lnnRecoTask { float h3lE = h3E + piE; // Building the mother particle: lnn - std::array lnnMom; + constexpr std::size_t kMomDim = 3; + std::array lnnMom; const auto& vtx = fitter.getPCACandidate(); for (int i = 0; i < 3; i++) { @@ -472,7 +565,6 @@ struct lnnRecoTask { hLnnCandLoss->Fill(3.); continue; } - // Definition of lnn mass float mLNN_HypHI = 3.00; // , but 2993.7 MeV/c**2 float massLNNL = std::sqrt(h3lE * h3lE - lnnMom[0] * lnnMom[0] - lnnMom[1] * lnnMom[1] - lnnMom[2] * lnnMom[2]); @@ -492,7 +584,8 @@ struct lnnRecoTask { continue; } - std::array primVtx = {collision.posX(), collision.posY(), collision.posZ()}; + constexpr std::size_t kprimVtxDim = 3; + std::array primVtx = {collision.posX(), collision.posY(), collision.posZ()}; double cosPA = RecoDecay::cpa(primVtx, lnnCand.decVtx, lnnMom); if (cosPA < v0cospa) { @@ -519,15 +612,31 @@ struct lnnRecoTask { lnnCandidates.push_back(lnnCand); - // Fill QA histograms + // Fill 2D map after all selections hdEdx3HSel->Fill(chargeFactor * lnnCand.mom3HTPC, h3track.tpcSignal()); + hdEdx3HPosTrack->Fill(lnnCand.mom3HTPC, h3track.tpcSignal()); + hdEdx3HNegTrack->Fill(-lnnCand.mom3HTPC, h3track.tpcSignal()); hNsigma3HSel->Fill(chargeFactor * lnnCand.mom3HTPC, lnnCand.nSigma3H); - hDCAxy3H->Fill(h3track.pt(), h3track.dcaXY()); if (h3track.hasTOF()) { h3HSignalPtTOF->Fill(chargeFactor * h3track.pt(), beta); hNsigma3HSelTOF->Fill(chargeFactor * h3track.p(), h3track.tofNSigmaTr()); h3HMassPtTOF->Fill(chargeFactor * h3track.pt(), lnnCand.mass2TrTOF); } + if (doTrackQA && lnnCand.isReco) { + bool passedTrTrackITS = h3track.hasITS(); + bool passedTrTrackTOF = h3track.hasTOF(); + bool passedPiTrackITS = pitrack.hasITS(); + + if (passedTrTrackITS) { + h2FT0CptTrSelItsTpc->Fill(collision.centFT0C(), h3track.pt()); + } + if (passedTrTrackITS && passedTrTrackTOF) { + h2FT0CptTrSelItsTpcTof->Fill(collision.centFT0C(), h3track.pt()); + } + if (passedPiTrackITS) { + h2FT0CptPiSelItsTpc->Fill(collision.centFT0C(), pitrack.pt()); + } + } } } @@ -548,19 +657,25 @@ struct lnnRecoTask { for (auto& posMother : mcTrackPos.mothers_as()) { if (posMother.globalIndex() != negMother.globalIndex()) continue; - if (!((mcTrackPos.pdgCode() == h3DauPdg && mcTrackNeg.pdgCode() == -211) || (mcTrackPos.pdgCode() == 211 && mcTrackNeg.pdgCode() == -1 * h3DauPdg))) + if (!((mcTrackPos.pdgCode() == h3DauPdg && mcTrackNeg.pdgCode() == -1 * piDauPdg) || (mcTrackPos.pdgCode() == piDauPdg && mcTrackNeg.pdgCode() == -1 * h3DauPdg))) continue; if (std::abs(posMother.pdgCode()) != lnnPdg) continue; // Checking primary and second vertex with MC simulations - std::array posPrimVtx = {posMother.vx(), posMother.vy(), posMother.vz()}; - std::array secVtx = {mcTrackPos.vx(), mcTrackPos.vy(), mcTrackPos.vz()}; + constexpr std::size_t kposVtxDim = 3; + std::array posPrimVtx = {posMother.vx(), posMother.vy(), posMother.vz()}; + constexpr std::size_t ksecVtxDim = 3; + std::array secVtx = {mcTrackPos.vx(), mcTrackPos.vy(), mcTrackPos.vz()}; lnnCand.gMom = posMother.pVector(); - lnnCand.gMom3H = mcTrackPos.pdgCode() == h3DauPdg ? mcTrackPos.pVector() : mcTrackNeg.pVector(); + bool isTrTrack = (mcTrackPos.pdgCode() == h3DauPdg); + + lnnCand.gMom3H = isTrTrack ? mcTrackPos.pVector() : mcTrackNeg.pVector(); + + lnnCand.gMomPi = isTrTrack ? mcTrackNeg.pVector() : mcTrackPos.pVector(); for (int i = 0; i < 3; i++) { lnnCand.gDecVtx[i] = secVtx[i] - posPrimVtx[i]; @@ -601,7 +716,7 @@ struct lnnRecoTask { fillCandidateData(collision, V0Table_thisCollision); - for (auto& lnnCand : lnnCandidates) { + for (const auto& lnnCand : lnnCandidates) { outputDataTable(collision.centFT0A(), collision.centFT0C(), collision.centFT0M(), collision.posX(), collision.posY(), collision.posZ(), lnnCand.isMatter, @@ -635,7 +750,7 @@ struct lnnRecoTask { hEvents->Fill(0.); - if (std::abs(collision.posZ()) > 10) { + if ((!collision.sel8()) || std::abs(collision.posZ()) > 10) { continue; } hEvents->Fill(1.); @@ -657,10 +772,21 @@ struct lnnRecoTask { fillCandidateData(collision, V0Table_thisCollision); fillMCinfo(trackLabelsMC, particlesMC); - for (auto& lnnCand : lnnCandidates) { + for (const auto& lnnCand : lnnCandidates) { if (!lnnCand.isSignal && mcSignalOnly) { continue; } + + // Fill 2D map for generated daughter particles which the mother candidate is reconstructed + if (lnnCand.isReco) { + h2FT0CptRecCandMC->Fill(collision.centFT0C(), lnnCand.genPt()); + h2FT0CetaRecCandMC->Fill(collision.centFT0C(), lnnCand.genEta()); + h2FT0CPtRecTrStrMC->Fill(collision.centFT0C(), lnnCand.genPt3H()); + h2FT0CetaRecTrStrMC->Fill(collision.centFT0C(), lnnCand.genEta3H()); + h2FT0CPtRecPiStrMC->Fill(collision.centFT0C(), lnnCand.genPtPi()); + h2FT0CetaRecPiStrMC->Fill(collision.centFT0C(), lnnCand.genEtaPi()); + } + int chargeFactor = -1 + 2 * (lnnCand.pdgCode > 0); outputMCTable(collision.centFT0A(), collision.centFT0C(), collision.centFT0M(), collision.posX(), collision.posY(), collision.posZ(), @@ -679,48 +805,73 @@ struct lnnRecoTask { } // now we fill only the signal candidates that were not reconstructed - for (auto& mcPart : particlesMC) { + for (const auto& mcPart : particlesMC) { if (std::abs(mcPart.pdgCode()) != lnnPdg) { continue; } - std::array secVtx; - std::array primVtx = {mcPart.vx(), mcPart.vy(), mcPart.vz()}; + float cent = collisionFT0Ccent[mcPart.mcCollisionId()]; + constexpr std::size_t kVtxDim = 3; + std::array secVtx; + std::array primVtx = {mcPart.vx(), mcPart.vy(), mcPart.vz()}; - std::array momMother = mcPart.pVector(); + constexpr std::size_t kArrayDim = 3; + std::array momMother = mcPart.pVector(); - std::array mom3H; + std::array mom3H; + std::array momPi; bool is3HFound = false; - for (auto& mcDaught : mcPart.daughters_as()) { - if (std::abs(mcDaught.pdgCode()) == h3DauPdg) { - secVtx = {mcDaught.vx(), mcDaught.vy(), mcDaught.vz()}; + bool isPiFound = false; + + for (const auto& mcDaught : mcPart.daughters_as()) { + bool motherIsAccepted = true; + if (mcDaught.getProcess() == 4) { + if (mcPart.has_mothers()) { + motherIsAccepted = false; + for (const auto& mother : mcPart.mothers_as()) { + if (std::abs(mother.pdgCode()) != lnnPdg) { + motherIsAccepted = true; + } + } + } + } + if (std::abs(mcDaught.pdgCode()) == h3DauPdg) { mom3H = mcDaught.pVector(); - is3HFound = true; - break; + + if (motherIsAccepted) { + h2FT0CPtGenTrStrMC->Fill(cent, mcDaught.pt()); + h2FT0CetaGenTrStrMC->Fill(cent, mcDaught.eta()); + } + } + + if (std::abs(mcDaught.pdgCode()) == piDauPdg) { + momPi = mcDaught.pVector(); + isPiFound = true; + + if (motherIsAccepted) { + h2FT0CPtGenPiStrMC->Fill(cent, mcDaught.pt()); + h2FT0CetaGenPiStrMC->Fill(cent, mcDaught.eta()); + } } } + if (mcPart.pdgCode() > 0) { hIsMatterGen->Fill(0.); } else { hIsMatterGen->Fill(1.); } - if (!is3HFound) { + if (!is3HFound || !isPiFound) { hDecayChannel->Fill(1.); continue; } hDecayChannel->Fill(0.); - if (mcPart.pdgCode() > 0) { - hIsMatterGenTwoBody->Fill(0.); - } else { - hIsMatterGenTwoBody->Fill(1.); - } if (std::find(filledMothers.begin(), filledMothers.end(), mcPart.globalIndex()) != std::end(filledMothers)) { continue; } - lnnCandidate lnnCand; + LnnCandidate lnnCand; lnnCand.pdgCode = mcPart.pdgCode(); lnnCand.survEvSelection = isGoodCollision[mcPart.mcCollisionId()]; int chargeFactor = -1 + 2 * (lnnCand.pdgCode > 0); @@ -728,10 +879,15 @@ struct lnnRecoTask { lnnCand.gDecVtx[i] = secVtx[i] - primVtx[i]; lnnCand.gMom[i] = momMother[i]; lnnCand.gMom3H[i] = mom3H[i]; + lnnCand.gMomPi[i] = momPi[i]; } + lnnCand.posTrackID = -1; lnnCand.negTrackID = -1; lnnCand.isSignal = true; + // // Fill 2D map for generated daughter particles which the mother candidate has only signal + h2FT0CptGenCandMC->Fill(cent, lnnCand.genPt()); + h2FT0CetaGenCandMC->Fill(cent, lnnCand.genEta()); outputMCTable(-1, collisionFT0Ccent[mcPart.mcCollisionId()], -1, -1, -1, -1, 0, diff --git a/PWGLF/TableProducer/Resonances/HeptaQuarktable.cxx b/PWGLF/TableProducer/Resonances/HeptaQuarktable.cxx index 818c43da234..1d6b20dd6e4 100644 --- a/PWGLF/TableProducer/Resonances/HeptaQuarktable.cxx +++ b/PWGLF/TableProducer/Resonances/HeptaQuarktable.cxx @@ -438,7 +438,7 @@ struct heptaquarktable { if (keepEventDoubleHQ && numberPhi > 1 && numberLambda > 0 && (hqresonance.size() == hqresonanced1.size()) && (hqresonance.size() == hqresonanced2.size())) { histos.fill(HIST("hEventstat"), 2.5); /////////// Fill collision table/////////////// - redHQEvents(bc.globalBC(), currentRunNumber, bc.timestamp(), collision.posZ(), collision.numContrib(), centrality, numberPhi, numberLambda); + redHQEvents(bc.globalBC(), currentRunNumber, bc.timestamp(), collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), centrality, numberPhi, numberLambda); auto indexEvent = redHQEvents.lastIndex(); //// Fill track table for HQ////////////////// for (auto if1 = hqresonance.begin(); if1 != hqresonance.end(); ++if1) { diff --git a/PWGLF/TableProducer/Strangeness/phiStrangeCorrelator.cxx b/PWGLF/TableProducer/Strangeness/phiStrangeCorrelator.cxx index 55e4f024588..bff0b64afd7 100644 --- a/PWGLF/TableProducer/Strangeness/phiStrangeCorrelator.cxx +++ b/PWGLF/TableProducer/Strangeness/phiStrangeCorrelator.cxx @@ -62,7 +62,7 @@ using namespace o2::framework::expressions; struct PhiMesonCandProducer { // Produce the table with the phi candidates information Produces phimesonCandidatesData; - // Produces phimesonCandidatesMcReco; + Produces phimesonCandidatesMcReco; Produces phimesonCandidatesMcGen; HistogramRegistry histos{"phiCandidates", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -196,8 +196,9 @@ struct PhiMesonCandProducer { } } - PROCESS_SWITCH(PhiMesonCandProducer, processData, "Process function to select Phi meson candidates in Data", true); + PROCESS_SWITCH(PhiMesonCandProducer, processData, "Process function to select Phi meson candidates in Data or in McReco (w/o McTruth) analysis", true); + /* void processMCRecoDataLike(SimCollisions::iterator const& collision, FullMCTracks const&) { auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -226,8 +227,9 @@ struct PhiMesonCandProducer { } PROCESS_SWITCH(PhiMesonCandProducer, processMCRecoDataLike, "Process function to select Phi meson candidates in MCReco w/o MC truth", false); + */ - /*void processMCReco(SimCollisions::iterator const& collision, FullMCTracks const&) + void processMCReco(SimCollisions::iterator const& collision, FullMCTracks const&, aod::McParticles const& mcParticles) { auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -235,10 +237,20 @@ struct PhiMesonCandProducer { for (const auto& track1 : posThisColl) { if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; + if (!track1.has_mcParticle()) + continue; + const auto track1McParticle = mcParticles.rawIteratorAt(track1.mcParticleId()); + if (track1McParticle.pdgCode() != PDG_t::kKPlus || !track1McParticle.isPhysicalPrimary()) + continue; for (const auto& track2 : negThisColl) { if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; + if (!track2.has_mcParticle()) + continue; + const auto track2McParticle = mcParticles.rawIteratorAt(track2.mcParticleId()); + if (track2McParticle.pdgCode() != PDG_t::kKMinus || !track2McParticle.isPhysicalPrimary()) + continue; ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); @@ -249,12 +261,34 @@ struct PhiMesonCandProducer { if (std::abs(recPhi.Rapidity()) > phiConfigs.cfgYAcceptance) continue; - phimesonCandidatesMcReco(collision.globalIndex(), recPhi.M(), recPhi.Pt(), recPhi.Rapidity(), recPhi.Phi()); + const auto track1mcPartMotherIndexes = track1McParticle.mothersIds(); + const auto track2mcPartMotherIndexes = track2McParticle.mothersIds(); + + auto genPhiMaybe = [&]() -> std::optional { + for (const auto& mother1Index : track1mcPartMotherIndexes) { + for (const auto& mother2Index : track2mcPartMotherIndexes) { + if (mother1Index != mother2Index) + continue; + + const auto motherMcParticle = mcParticles.rawIteratorAt(mother1Index); + if (std::abs(motherMcParticle.pdgCode()) == o2::constants::physics::Pdg::kPhi) + return motherMcParticle; + } + } + + return std::nullopt; + }(); + + if (!genPhiMaybe) + continue; + const auto genPhi = *genPhiMaybe; + + phimesonCandidatesMcReco(collision.globalIndex(), recPhi.M(), genPhi.pt(), genPhi.y(), genPhi.phi()); } } } - PROCESS_SWITCH(PhiMesonCandProducer, processMCReco, "Process function to select Phi meson candidates in MCReco w MC truth", false);*/ + PROCESS_SWITCH(PhiMesonCandProducer, processMCReco, "Process function to select Phi meson candidates in MCReco w MC truth", false); void processMCGen(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcParticles) { diff --git a/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx b/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx index d5bec464235..971a95c8714 100644 --- a/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx @@ -229,12 +229,18 @@ struct FlattenictyPikp { Configurable cfgFillV0Hist{"cfgFillV0Hist", false, "fill V0 histograms"}; Configurable cfgFillChrgType{"cfgFillChrgType", false, "fill histograms per charge types"}; Configurable cfgFillChrgTypeV0s{"cfgFillChrgTypeV0s", false, "fill V0s histograms per charge types"}; - Configurable> paramsFuncMIPpos{"paramsFuncMIPpos", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncMIPneg{"paramsFuncMIPneg", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncMIPall{"paramsFuncMIPall", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncPlateaUpos{"paramsFuncPlateaUpos", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncPlateaUneg{"paramsFuncPlateaUneg", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncPlateaUall{"paramsFuncPlateaUall", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPposEtaP{"paramsFuncMIPposEtaP", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPnegEtaP{"paramsFuncMIPnegEtaP", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPallEtaP{"paramsFuncMIPallEtaP", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPposEtaN{"paramsFuncMIPposEtaN", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPnegEtaN{"paramsFuncMIPnegEtaN", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPallEtaN{"paramsFuncMIPallEtaN", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncPlateaUposEtaP{"paramsFuncPlateaUposEtaP", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncPlateaUnegEtaP{"paramsFuncPlateaUnegEtaP", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncPlateaUallEtaP{"paramsFuncPlateaUallEtaP", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncPlateaUposEtaN{"paramsFuncPlateaUposEtaN", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncPlateaUnegEtaN{"paramsFuncPlateaUnegEtaN", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncPlateaUallEtaN{"paramsFuncPlateaUallEtaN", std::vector{-1.f}, "parameters of pol2"}; Configurable cfgGainEqCcdbPath{"cfgGainEqCcdbPath", "Users/g/gbencedi/flattenicity/GainEq", "CCDB path for gain equalization constants"}; Configurable cfgVtxEqCcdbPath{"cfgVtxEqCcdbPath", "Users/g/gbencedi/flattenicity/ZvtxEq", "CCDB path for z-vertex equalization constants"}; Configurable cfgDeDxCalibCcdbPath{"cfgDeDxCalibCcdbPath", "Users/g/gbencedi/flattenicity/dEdxCalib", "CCDB path for dEdx calibration"}; @@ -403,25 +409,38 @@ struct FlattenictyPikp { void init(InitContext&) { - auto vecParamsMIPpos = (std::vector)paramsFuncMIPpos; - auto vecParamsMIPneg = (std::vector)paramsFuncMIPneg; - auto vecParamsMIPall = (std::vector)paramsFuncMIPall; - auto vecParamsPLApos = (std::vector)paramsFuncPlateaUpos; - auto vecParamsPLAneg = (std::vector)paramsFuncPlateaUneg; - auto vecParamsPLAall = (std::vector)paramsFuncPlateaUall; + auto vecParamsMIPposEtaP = (std::vector)paramsFuncMIPposEtaP; + auto vecParamsMIPposEtaN = (std::vector)paramsFuncMIPposEtaN; + auto vecParamsMIPnegEtaP = (std::vector)paramsFuncMIPnegEtaP; + auto vecParamsMIPnegEtaN = (std::vector)paramsFuncMIPnegEtaN; + auto vecParamsMIPallEtaP = (std::vector)paramsFuncMIPallEtaP; + auto vecParamsMIPallEtaN = (std::vector)paramsFuncMIPallEtaN; + + auto vecParamsPLAposEtaP = (std::vector)paramsFuncPlateaUposEtaP; + auto vecParamsPLAposEtaN = (std::vector)paramsFuncPlateaUposEtaN; + auto vecParamsPLAnegEtaP = (std::vector)paramsFuncPlateaUnegEtaP; + auto vecParamsPLAnegEtaN = (std::vector)paramsFuncPlateaUnegEtaN; + auto vecParamsPLAallEtaP = (std::vector)paramsFuncPlateaUallEtaP; + auto vecParamsPLAallEtaN = (std::vector)paramsFuncPlateaUallEtaN; auto addVec = [&](std::vector>& targetVec, const std::string& name, bool isMIP) { if (isMIP) { - targetVec.emplace_back(vecParamsMIPpos); - targetVec.emplace_back(vecParamsMIPneg); - targetVec.emplace_back(vecParamsMIPall); + targetVec.emplace_back(vecParamsMIPposEtaP); + targetVec.emplace_back(vecParamsMIPnegEtaP); + targetVec.emplace_back(vecParamsMIPallEtaP); + targetVec.emplace_back(vecParamsMIPposEtaN); + targetVec.emplace_back(vecParamsMIPnegEtaN); + targetVec.emplace_back(vecParamsMIPallEtaN); if (!vecParamsMIP.size()) { LOG(info) << "size of " << name << "is zero."; } } else { - targetVec.emplace_back(vecParamsPLApos); - targetVec.emplace_back(vecParamsPLAneg); - targetVec.emplace_back(vecParamsPLAall); + targetVec.emplace_back(vecParamsPLAposEtaP); + targetVec.emplace_back(vecParamsPLAnegEtaP); + targetVec.emplace_back(vecParamsPLAallEtaP); + targetVec.emplace_back(vecParamsPLAposEtaN); + targetVec.emplace_back(vecParamsPLAnegEtaN); + targetVec.emplace_back(vecParamsPLAallEtaN); if (!vecParamsPLA.size()) { LOG(info) << "size of " << name << "is zero."; } @@ -1144,12 +1163,24 @@ struct FlattenictyPikp { float valCalib = -1.; if constexpr (isChrg) { if (track.sign() * track.tpcInnerParam() > Cnull) { - valCalib = fCalib.at(0)->Eval(track.eta()); + if (track.eta() >= 0) { + valCalib = fCalib.at(0)->Eval(track.eta()); + } else { + valCalib = fCalib.at(3)->Eval(track.eta()); + } } else { - valCalib = fCalib.at(1)->Eval(track.eta()); + if (track.eta() >= 0) { + valCalib = fCalib.at(1)->Eval(track.eta()); + } else { + valCalib = fCalib.at(4)->Eval(track.eta()); + } } } else { - valCalib = fCalib.at(2)->Eval(track.eta()); + if (track.eta() >= 0) { + valCalib = fCalib.at(2)->Eval(track.eta()); + } else { + valCalib = fCalib.at(5)->Eval(track.eta()); + } } return valCalib; } @@ -2233,7 +2264,6 @@ struct FlattenictyPikp { // using Particles = soa::Filtered; // expressions::Filter primaries = (aod::mcparticle::flags & (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary) == (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary; - void processMCclosure(Colls::iterator const& collision, MyPIDTracks const& tracks, MyLabeledTracks const& mcTrackLabels, diff --git a/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx b/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx index d8327d466dd..9c72a266e98 100644 --- a/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx @@ -998,6 +998,7 @@ struct LFNucleiBATask { histos.add("tracks/helium/h2HeliumSpectraTrueVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/h2HeliumSpectraTrueWPIDVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/h2HeliumSpectraTruePrimVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); + histos.add("tracks/helium/h2HeliumSpectraTruePrimGenVsMult_Z2", "#it{p}_{T}(gen) (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/h2HeliumSpectraTrueSecVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); } @@ -1011,6 +1012,7 @@ struct LFNucleiBATask { histos.add("tracks/helium/h2antiHeliumSpectraTrueVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/h2antiHeliumSpectraTrueWPIDVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/h2antiHeliumSpectraTruePrimVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); + histos.add("tracks/helium/h2antiHeliumSpectraTruePrimGenVsMult_Z2", "#it{p}_{T}(gen) (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/h2antiHeliumSpectraTrueSecVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); } @@ -1020,8 +1022,11 @@ struct LFNucleiBATask { if (enableCentrality) { histos.add("tracks/helium/TOF/h2HeliumSpectraTrueWPIDVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/TOF/h2HeliumSpectraTruePrimVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); + histos.add("tracks/helium/TOF/h2HeliumSpectraTruePrimGenVsMult_Z2", "#it{p}_{T}(gen) (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); + histos.add("tracks/helium/TOF/h2antiHeliumSpectraTrueWPIDVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/TOF/h2antiHeliumSpectraTruePrimVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); + histos.add("tracks/helium/TOF/h2antiHeliumSpectraTruePrimGenVsMult_Z2", "#it{p}_{T}(gen) (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); } } if (outFlagOptions.enableEffPlots) { @@ -2150,6 +2155,7 @@ struct LFNucleiBATask { spectraGen.add("helium/histPtGenHe", "PtGenHe", HistType::kTH1F, {{800, 0.f, 8.f}}); spectraGen.add("helium/histPtRecHe", "PtRecHe", HistType::kTH1F, {{800, 0.f, 8.f}}); spectraGen.add("helium/histPtShiftHe", "PtReco-PtGen vs PtReco;#it{p}_{T}(reco); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + spectraGen.add("helium/histPtShiftHeVsGen", "PtReco-PtGen vs PtGen;#it{p}_{T}(gen); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); spectraGen.add("helium/histPtShiftVsEtaHe", "PtReco-PtGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); spectraGen.add("helium/histPGenHe", "PGenHe", HistType::kTH1F, {{800, 0.f, 8.f}}); @@ -2160,8 +2166,16 @@ struct LFNucleiBATask { spectraGen.add("helium/histPtGenantiHe", "PtGenantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); spectraGen.add("helium/histPtRecantiHe", "PtRecantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); spectraGen.add("helium/histPtShiftantiHe", "PtReco-PtGen vs PtReco; #it{p}_{T}(reco); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + spectraGen.add("helium/histPtShiftantiHeVsGen", "PtReco-PtGen vs PtGen; #it{p}_{T}(gen); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); spectraGen.add("helium/histPtShiftVsEtaantiHe", "PtReco-PtGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); + if (outFlagOptions.doTOFplots) { + spectraGen.add("helium/TOF/histPtShiftHe", "PtReco-PtGen vs PtReco;#it{p}_{T}(reco); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + spectraGen.add("helium/TOF/histPtShiftHeVsGen", "PtReco-PtGen vs PtGen;#it{p}_{T}(gen); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + spectraGen.add("helium/TOF/histPtShiftantiHe", "PtReco-PtGen vs PtReco; #it{p}_{T}(reco); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + spectraGen.add("helium/TOF/histPtShiftantiHeVsGen", "PtReco-PtGen vs PtGen; #it{p}_{T}(gen); #it{p}_{T}(reco) - #it{p}_{T}(gen)", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + } + spectraGen.add("helium/histPGenantiHe", "PGenantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); spectraGen.add("helium/histPRecantiHe", "PRecantiHe", HistType::kTH1F, {{800, 0.f, 8.f}}); spectraGen.add("helium/histPShiftantiHe", "PReco-PGen vs PReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); @@ -3707,8 +3721,12 @@ struct LFNucleiBATask { spectraGen.fill(HIST("helium/histPtGenHe"), std::abs(track.mcParticle().pt())); spectraGen.fill(HIST("helium/histPtRecHe"), 2.f * hePt); spectraGen.fill(HIST("helium/histPtShiftHe"), 2.f * hePt, 2.f * hePt - track.mcParticle().pt()); + spectraGen.fill(HIST("helium/histPtShiftHeVsGen"), track.mcParticle().pt(), 2.f * hePt - track.mcParticle().pt()); spectraGen.fill(HIST("helium/histPtShiftVsEtaHe"), track.eta(), 2.f * hePt - track.mcParticle().pt()); - + if (track.hasTOF() && outFlagOptions.doTOFplots) { + spectraGen.fill(HIST("helium/TOF/histPtShiftHe"), 2.f * hePt, 2.f * hePt - track.mcParticle().pt()); + spectraGen.fill(HIST("helium/TOF/histPtShiftHeVsGen"), track.mcParticle().pt(), 2.f * hePt - track.mcParticle().pt()); + } spectraGen.fill(HIST("helium/histPGenHe"), std::abs(track.mcParticle().p())); spectraGen.fill(HIST("helium/histPRecHe"), 2.f * heP); spectraGen.fill(HIST("helium/histPShiftHe"), 2.f * heP, 2.f * heP - track.mcParticle().p()); @@ -3774,21 +3792,23 @@ struct LFNucleiBATask { } } } - if (isHeWoTPCpid) { + if (isAntiHeWoTPCpid) { if (isPhysPrim) { if constexpr (!IsFilteredData) { spectraGen.fill(HIST("helium/histPtGenantiHe"), std::abs(track.mcParticle().pt())); spectraGen.fill(HIST("helium/histPtRecantiHe"), 2.f * antihePt); spectraGen.fill(HIST("helium/histPtShiftantiHe"), 2.f * antihePt, 2.f * antihePt - track.mcParticle().pt()); + spectraGen.fill(HIST("helium/histPtShiftantiHeVsGen"), track.mcParticle().pt(), 2.f * antihePt - track.mcParticle().pt()); spectraGen.fill(HIST("helium/histPtShiftVsEtaantiHe"), track.eta(), 2.f * antihePt - track.mcParticle().pt()); - + if (track.hasTOF() && outFlagOptions.doTOFplots) { + spectraGen.fill(HIST("helium/TOF/histPtShiftantiHe"), 2.f * antihePt, 2.f * antihePt - track.mcParticle().pt()); + spectraGen.fill(HIST("helium/TOF/histPtShiftantiHeVsGen"), track.mcParticle().pt(), 2.f * antihePt - track.mcParticle().pt()); + } spectraGen.fill(HIST("helium/histPGenantiHe"), std::abs(track.mcParticle().p())); spectraGen.fill(HIST("helium/histPRecantiHe"), 2.f * antiheP); spectraGen.fill(HIST("helium/histPShiftantiHe"), 2.f * antiheP, 2.f * antiheP - track.mcParticle().p()); spectraGen.fill(HIST("helium/histPShiftVsEtaantiHe"), track.eta(), 2.f * antiheP - track.mcParticle().p()); } - if (outFlagOptions.makeDCABeforeCutPlots) { - } } } } @@ -5811,13 +5831,19 @@ struct LFNucleiBATask { } if (isPhysPrim) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTruePrim_Z2"), 2 * hePt); - if (enableCentrality) + if (enableCentrality) { histos.fill(HIST("tracks/helium/h2HeliumSpectraTruePrimVsMult_Z2"), 2 * hePt, centFT0M); + if constexpr (!IsFilteredData) + histos.fill(HIST("tracks/helium/h2HeliumSpectraTruePrimGenVsMult_Z2"), track.mcParticle().pt(), centFT0M); + } if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { if (track.hasTOF() && outFlagOptions.doTOFplots) { histos.fill(HIST("tracks/helium/TOF/h1HeliumSpectraTruePrim_Z2"), 2 * hePt); - if (enableCentrality) + if (enableCentrality) { histos.fill(HIST("tracks/helium/TOF/h2HeliumSpectraTruePrimVsMult_Z2"), 2 * hePt, centFT0M); + if constexpr (!IsFilteredData) + histos.fill(HIST("tracks/helium/TOF/h2HeliumSpectraTruePrimGenVsMult_Z2"), track.mcParticle().pt(), centFT0M); + } } } @@ -5886,14 +5912,20 @@ struct LFNucleiBATask { } if (isPhysPrim) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTruePrim_Z2"), 2 * antihePt); - if (enableCentrality) + if (enableCentrality) { histos.fill(HIST("tracks/helium/h2antiHeliumSpectraTruePrimVsMult_Z2"), 2 * antihePt, centFT0M); + if constexpr (!IsFilteredData) + histos.fill(HIST("tracks/helium/h2antiHeliumSpectraTruePrimGenVsMult_Z2"), track.mcParticle().pt(), centFT0M); + } if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { if (track.hasTOF() && outFlagOptions.doTOFplots) { histos.fill(HIST("tracks/helium/TOF/h1antiHeliumSpectraTruePrim_Z2"), 2 * antihePt); - if (enableCentrality) + if (enableCentrality) { histos.fill(HIST("tracks/helium/TOF/h2antiHeliumSpectraTruePrimVsMult_Z2"), 2 * antihePt, centFT0M); + if constexpr (!IsFilteredData) + histos.fill(HIST("tracks/helium/TOF/h2antiHeliumSpectraTruePrimGenVsMult_Z2"), track.mcParticle().pt(), centFT0M); + } } } diff --git a/PWGLF/Tasks/Resonances/heptaquark.cxx b/PWGLF/Tasks/Resonances/heptaquark.cxx index 407c3199073..f7c30a46ddf 100644 --- a/PWGLF/Tasks/Resonances/heptaquark.cxx +++ b/PWGLF/Tasks/Resonances/heptaquark.cxx @@ -12,28 +12,33 @@ /// \brief this is a starting point for the Resonances tutorial /// \author junlee kim +#include "PWGLF/DataModel/ReducedHeptaQuarkTables.h" + +#include "Common/Core/trackUtilities.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include -#include + #include -#include #include +#include +#include #include #include + #include + +#include #include #include #include #include -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/StepTHn.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/ReducedHeptaQuarkTables.h" -#include "CommonConstants/PhysicsConstants.h" - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -47,14 +52,22 @@ struct heptaquark { Configurable cfgPIDStrategy{"cfgPIDStrategy", 3, "PID strategy 1"}; Configurable cfgPIDPrPi{"cfgPIDPrPi", 3, "PID selection for proton and pion"}; - Configurable minPhiMass{"minPhiMass", 1.01, "Minimum phi mass"}; - Configurable maxPhiMass{"maxPhiMass", 1.03, "Maximum phi mass"}; + Configurable cfgMinPhiMass{"cfgMinPhiMass", 1.01, "Minimum phi mass"}; + Configurable cfgMaxPhiMass{"cfgMaxPhiMass", 1.03, "Maximum phi mass"}; - Configurable minLambdaMass{"minLambdaMass", 1.1, "Minimum lambda mass"}; - Configurable maxLambdaMass{"maxLambdaMass", 1.13, "Maximum lambda mass"}; + Configurable cfgMinLambdaMass{"cfgMinLambdaMass", 1.1, "Minimum lambda mass"}; + Configurable cfgMaxLambdaMass{"cfgMaxLambdaMass", 1.13, "Maximum lambda mass"}; - Configurable cutNsigmaTPC{"cutNsigmaTPC", 2.5, "nsigma cut TPC"}; - Configurable cutNsigmaTOF{"cutNsigmaTOF", 3.0, "nsigma cut TOF"}; + Configurable cfgNsigmaTPC{"cfgNsigmaTPC", 2.5, "nsigma cut TPC"}; + Configurable cfgNsigmaTOF{"cfgNsigmaTOF", 3.0, "nsigma cut TOF"}; + + Configurable cfgSelectHQ{"cfgSelectHQ", true, "switch to select HQ"}; + + Configurable cfgMinPhiPt{"cfgMinPhiPt", 0.2, "Minimum phi pt"}; + Configurable cfgMinLambdaPt{"cfgMinLambdaPt", 0.5, "Minimum lambda pt"}; + + Configurable cfgSoftFraction{"cfgSoftFraction", 0.01, "Minimum allowed softest fraction"}; + Configurable cfgCollinear{"cfgCollinear", 0.98, "Maximum allowed collinear selection"}; ConfigurableAxis massAxis{"massAxis", {600, 2.8, 3.4}, "Invariant mass axis"}; ConfigurableAxis ptAxis{"ptAxis", {VARIABLE_WIDTH, 0.2, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.5, 8.0, 10.0, 100.0}, "Transverse momentum bins"}; @@ -95,76 +108,76 @@ struct heptaquark { { if (PIDStrategy == 0) { if (TOFHit != 1) { - if (TMath::Abs(nsigmaTPC) < cutNsigmaTPC) { + if (TMath::Abs(nsigmaTPC) < cfgNsigmaTPC) { return true; } } if (TOFHit == 1) { - if (TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } } } if (PIDStrategy == 1) { if (ptcand < 0.5) { - if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cutNsigmaTPC) { + if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cfgNsigmaTPC) { return true; } - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } } if (ptcand >= 0.5) { - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } } } if (PIDStrategy == 2) { if (ptcand < 0.5) { - if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cutNsigmaTPC) { + if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cfgNsigmaTPC) { return true; } - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } } if (ptcand >= 0.5 && ptcand < 1.2) { - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } - if (TOFHit != 1 && nsigmaTPC > -1.5 && nsigmaTPC < cutNsigmaTPC) { + if (TOFHit != 1 && nsigmaTPC > -1.5 && nsigmaTPC < cfgNsigmaTPC) { return true; } } if (ptcand >= 1.2) { - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } - if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cutNsigmaTPC) { + if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cfgNsigmaTPC) { return true; } } } if (PIDStrategy == 3) { if (ptcand < 0.5) { - if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cutNsigmaTPC) { + if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cfgNsigmaTPC) { return true; } - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } } if (ptcand >= 0.5 && ptcand < 1.2) { - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } } if (ptcand >= 1.2) { - if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TOFHit == 1 && TMath::Abs(nsigmaTOF) < cfgNsigmaTOF) { return true; } - if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cutNsigmaTPC) { + if (TOFHit != 1 && TMath::Abs(nsigmaTPC) < cfgNsigmaTPC) { return true; } } @@ -172,28 +185,38 @@ struct heptaquark { return false; } - template - ROOT::Math::XYZVector getDCAofV0V0(V01 const& v01, V02 const& v02) - { - ROOT::Math::XYZVector v01pos, v02pos, v01mom, v02mom; - v01pos.SetXYZ(v01.x(), v01.y(), v01.z()); - v02pos.SetXYZ(v02.x(), v02.y(), v02.z()); - v01mom.SetXYZ(v01.px(), v01.py(), v01.pz()); - v02mom.SetXYZ(v02.px(), v02.py(), v02.pz()); - - ROOT::Math::XYZVector posdiff = v02pos - v01pos; - ROOT::Math::XYZVector cross = v01mom.Cross(v02mom); - ROOT::Math::XYZVector dcaVec = (posdiff.Dot(cross) / cross.Mag2()) * cross; - return dcaVec; - } - - template - float getCPA(V01 const& v01, V02 const& v02) + template + int selectHQ(HQ1 const& hq1, HQ2 const& hq2, HQ3 const& hq3) { - ROOT::Math::XYZVector v01mom, v02mom; - v01mom.SetXYZ(v01.px() / v01.p(), v01.py() / v01.p(), v01.pz() / v01.p()); - v02mom.SetXYZ(v02.px() / v02.p(), v02.py() / v02.p(), v02.pz() / v02.p()); - return v01mom.Dot(v02mom); + int selection = 0; + if (hq1.Pt() < cfgMinPhiPt || hq2.Pt() < cfgMinPhiPt || hq3.Pt() < cfgMinLambdaPt) + selection += 1; + + double sumE = hq1.E() + hq2.E() + hq3.E(); + double emin = std::min({hq1.E(), hq2.E(), hq3.E()}); + double fmin = emin / std::max(1e-9, sumE); + if (fmin < cfgSoftFraction) + selection += 2; + + auto ex = hq1 + hq2 + hq3; + TVector3 boost = -ex.BoostVector(); + auto hqphipair_boost = hq1 + hq2; + auto hqlambda_boost = hq3; + hqphipair_boost.Boost(boost); + hqlambda_boost.Boost(boost); + double cosHel = hqlambda_boost.Vect().Dot(hqphipair_boost.Vect()) / (hqlambda_boost.Vect().Mag() * hqphipair_boost.Vect().Mag()); + if (std::abs(cosHel) > cfgCollinear) + selection += 4; + /* + ROOT::Math::XYZVector rPV(col.posX(), col.posY(), col.posZ()); + ROOT::Math::XYZVector rSV(hq3.hqx(), hq3.hqy(), hq3.hqz()); + ROOT::Math::XYZVector L = rSV - rPV; + ROOT::Math::XYZVector exMom(ex.Px(), ex.Py(), ex.Pz()); + double cosPoint = L.Dot(exMom) / (L.R() * pEx.R() + 1e-9); + if (cosPoint < cfgCosPoint) + return 8; + */ + return selection; } ROOT::Math::PxPyPzMVector DauVec1, DauVec2; @@ -214,7 +237,7 @@ struct heptaquark { if (hqtrackd1.hqId() != 333) continue; - if (hqtrackd1.hqMass() < minPhiMass || hqtrackd1.hqMass() > maxPhiMass) + if (hqtrackd1.hqMass() < cfgMinPhiMass || hqtrackd1.hqMass() > cfgMaxPhiMass) continue; DauVec1 = ROOT::Math::PxPyPzMVector(hqtrackd1.hqd1Px(), hqtrackd1.hqd1Py(), hqtrackd1.hqd1Pz(), massKa); @@ -246,7 +269,7 @@ struct heptaquark { if (hqtrackd2.hqId() != 333) continue; - if (hqtrackd2.hqMass() < minPhiMass || hqtrackd2.hqMass() > maxPhiMass) + if (hqtrackd2.hqMass() < cfgMinPhiMass || hqtrackd2.hqMass() > cfgMaxPhiMass) continue; DauVec1 = ROOT::Math::PxPyPzMVector(hqtrackd2.hqd1Px(), hqtrackd2.hqd1Py(), hqtrackd2.hqd1Pz(), massKa); @@ -278,7 +301,7 @@ struct heptaquark { if (std::abs(hqtrackd3.hqId()) != 3122) continue; - if (hqtrackd3.hqMass() < minLambdaMass || hqtrackd3.hqMass() > maxLambdaMass) + if (hqtrackd3.hqMass() < cfgMinLambdaMass || hqtrackd3.hqMass() > cfgMaxLambdaMass) continue; int isLambda = static_cast(hqtrackd3.hqId() < 0); @@ -321,6 +344,9 @@ struct heptaquark { HQ12 = HQ1 + HQ2; HQ13 = HQ1 + HQ3; + if (cfgSelectHQ && selectHQ(HQ1, HQ2, HQ3)) + continue; + histos.fill(HIST("h_InvMass_same"), exotic.M(), exotic.Pt(), collision.centrality()); histos.fill(HIST("hDalitz"), HQ12.M2(), HQ13.M2(), exotic.M(), exotic.Pt(), isLambda, collision.centrality()); diff --git a/PWGLF/Tasks/Resonances/kstar892LightIon.cxx b/PWGLF/Tasks/Resonances/kstar892LightIon.cxx index 19c0e261938..f18aad19290 100644 --- a/PWGLF/Tasks/Resonances/kstar892LightIon.cxx +++ b/PWGLF/Tasks/Resonances/kstar892LightIon.cxx @@ -92,6 +92,9 @@ struct Kstar892LightIon { Configurable isVertexITSTPC{"isVertexITSTPC", false, "Vertex ITS TPC"}; Configurable isVertexTOFMatched{"isVertexTOFMatched", false, "Vertex TOF Matched"}; + // check + Configurable isApplyEvSelFactors{"isApplyEvSelFactors", false, "Apply event selection cut in processCorrFactors"}; + // Configurables for track selections Configurable isPVContributor{"isPVContributor", true, "PV contributor track selection"}; // PV Contriuibutor Configurable isPrimaryTrack{"isPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz @@ -129,6 +132,9 @@ struct Kstar892LightIon { Configurable onlyTOFHIT{"onlyTOFHIT", false, "accept only TOF hit tracks at high pt"}; Configurable onlyTPC{"onlyTPC", false, "only TPC tracks"}; Configurable isApplypTdepPID{"isApplypTdepPID", false, "Apply pT dependent PID"}; + Configurable isApplypTdepPIDwTOF{"isApplypTdepPIDwTOF", false, "Apply pT dependent PID with compulsory TOF condition in a pT range"}; + Configurable isApplyMID{"isApplyMID", false, "Apply particle MID"}; + Configurable isApplypTdepMID{"isApplypTdepMID", false, "Apply pT dependent particle MID"}; Configurable nsigmaCutTPCPi{"nsigmaCutTPCPi", 3.0, "TPC Nsigma cut for pions"}; Configurable nsigmaCutTPCKa{"nsigmaCutTPCKa", 3.0, "TPC Nsigma cut for kaons"}; @@ -137,6 +143,9 @@ struct Kstar892LightIon { Configurable nsigmaCutCombinedKa{"nsigmaCutCombinedKa", 3.0, "Combined Nsigma cut for kaon"}; Configurable nsigmaCutCombinedPi{"nsigmaCutCombinedPi", 3.0, "Combined Nsigma cut for pion"}; + Configurable nsigmaCutCombinedMID{"nsigmaCutCombinedMID", 3.0, "Combined Nsigma cut for pion in MID"}; + Configurable nsigmaCutTPCMID{"nsigmaCutTPCMID", 1.0, "MID Nsigma cut for pion in TPC"}; + // Fixed variables float lowPtCutPID = 0.5; } selectionConfig; @@ -152,6 +161,8 @@ struct Kstar892LightIon { Configurable selectCentEstimator{"selectCentEstimator", 0, "Select centrality estimator: 0 - FT0M, 1 - FT0A, 2 - FT0C, 3 - FV0A"}; + Configurable reflectionType{"reflectionType", 0, "Reflection: 0=Rho, 1=Omega, 2=Phi, 3=Kstar (for processRecReflection)"}; + // Configurable for histograms ConfigurableAxis binsCentPlot{"binsCentPlot", {110, 0.0, 110}, "Centrality axis"}; ConfigurableAxis axisdEdx{"axisdEdx", {1, 0.0f, 200.0f}, "dE/dx (a.u.)"}; @@ -161,7 +172,7 @@ struct Kstar892LightIon { ConfigurableAxis binsImpactPar{"binsImpactPar", {100, 0, 25}, "Binning of the impact parameter axis"}; ConfigurableAxis axisNch{"axisNch", {100, 0.0f, 100.0f}, "Number of charged particles in |y| < 0.5"}; - enum MultEstimator { + enum CentEstimator { kFT0M, kFT0A, kFT0C, @@ -177,8 +188,17 @@ struct Kstar892LightIon { kProton }; + enum PartReflection { + kRho, + kOmega, + kPhi, + kKstar + }; + int noOfDaughters = 2; + double pionPIDpTlow = 1, pionPIDpThigh = 2.5, kaonPIDpTlow = 0.7, kaonPIDpThigh = 2.5; + TRandom* rn = new TRandom(); void init(InitContext const&) @@ -318,10 +338,6 @@ struct Kstar892LightIon { hMC.add("CorrFactors/h3dGenKstarVsMultMCVsCentrality", "MC centrality vs centrality vs p_{T}", kTH3D, {axisNch, {101, 0.0f, 101.0f}, ptAxis}); } - if (doprocessRecMisID) { - hMC.add("RecMisID/hMassMisID", "Reconstruction misidentification", kTH3F, {ptAxis, centralityAxis, invmassAxis}); - } - if (doprocessLossMCMultiplicity) { hMC.add("LossMult/hMultMC", "Charged Paticle multiplicity in generated MC before event selection", kTH1F, {axisNch}); hMC.add("LossMult/hCentVsMultMC", "Centrality vs Charged Particle Multiplicity", kTH2F, {centralityAxis, axisNch}); @@ -331,6 +347,14 @@ struct Kstar892LightIon { hMC.add("LossMult/hGenKstar_vs_pt_vs_multMC", "pT vs Charged particle multiplicity", kTH2F, {ptAxis, axisNch}); hMC.add("LossMult/hGenKstarRecoEvt_vs_pt_vs_multMC", "pT vs Charged particle multiplicity with reconstruction", kTH2F, {ptAxis, axisNch}); } + + if (doprocessRecMisID) { + hMC.add("RecMisID/hMassMisID", "Reconstruction misidentification", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + } + + if (doprocessRecReflection) { + hMC.add("Reflections/hReflection", "Refelction template of Rho", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + } } double massPi = o2::constants::physics::MassPiPlus; @@ -552,7 +576,7 @@ struct Kstar892LightIon { } template - bool selectionPIDNew(const T& candidate, int PID) + bool selectionPIDpTdep(const T& candidate, int PID) { if (PID == PIDParticle::kPion) { if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { @@ -578,6 +602,101 @@ struct Kstar892LightIon { return false; } + template + bool selectionPIDpTdepTOF(const T& candidate, int PID) + { + if (PID == PIDParticle::kPion) { + if (candidate.pt() < pionPIDpTlow || candidate.pt() > pionPIDpThigh) { + if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { + return true; + } + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi) { + return true; + } + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && !candidate.hasTOF()) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (selectionConfig.nsigmaCutCombinedPi * selectionConfig.nsigmaCutCombinedPi)) { + return true; + } + } + } else if (PID == PIDParticle::kKaon) { + if (candidate.pt() < kaonPIDpTlow || candidate.pt() > kaonPIDpThigh) { + if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { + return true; + } + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa) { + return true; + } + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && !candidate.hasTOF()) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (selectionConfig.nsigmaCutCombinedKa * selectionConfig.nsigmaCutCombinedKa)) { + return true; + } + } + } + return false; + } + + template + bool selectionMID(const T& candidate, int PID) + { + if (PID == PIDParticle::kPion) { + if (selectionConfig.onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } else if (selectionConfig.onlyTPC) { + if (std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (selectionConfig.nsigmaCutCombinedMID * selectionConfig.nsigmaCutCombinedMID)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } + } else if (PID == PIDParticle::kKaon) { + if (selectionConfig.onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } else if (selectionConfig.onlyTPC) { + if (std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (selectionConfig.nsigmaCutCombinedMID * selectionConfig.nsigmaCutCombinedMID)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } + } + return false; + } + + template + bool selectionMIDpTdep(const T& candidate, int PID) + { + if (PID == PIDParticle::kPion) { + if (candidate.pt() >= pionPIDpTlow && candidate.pt() < pionPIDpThigh && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } else if (PID == PIDParticle::kKaon) { + if (candidate.pt() >= kaonPIDpTlow && candidate.pt() < kaonPIDpThigh && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { + return true; + } + } + return false; + } + //*********Varibles declaration*************** float centrality{-1.0}, theta2; ROOT::Math::PxPyPzMVector daughter1, daughter2, daughterRot, mother, motherRot; @@ -714,14 +833,25 @@ struct Kstar892LightIon { } // since we are using combinations full index policy, so repeated pairs are allowed, so we can check one with Kaon and other with pion - if (!selectionConfig.isApplypTdepPID && !selectionPID(track1, 1)) // Track 1 is checked with Kaon + if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !selectionPID(track1, 1)) // Track 1 is checked with Kaon continue; - if (!selectionConfig.isApplypTdepPID && !selectionPID(track2, 0)) // Track 2 is checked with Pion + if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !selectionPID(track2, 0)) // Track 2 is checked with Pion continue; - if (selectionConfig.isApplypTdepPID && !selectionPIDNew(track1, 1)) // Track 1 is checked with Kaon + if (selectionConfig.isApplypTdepPID && !selectionPIDpTdep(track1, 1)) // Track 1 is checked with Kaon + continue; + if (selectionConfig.isApplypTdepPID && !selectionPIDpTdep(track2, 0)) // Track 2 is checked with Pion continue; - if (selectionConfig.isApplypTdepPID && !selectionPIDNew(track2, 0)) // Track 2 is checked with Pion + + if (selectionConfig.isApplypTdepPIDwTOF && !selectionPIDpTdepTOF(track1, 1)) // Track 1 is checked with Kaon + continue; + if (selectionConfig.isApplypTdepPIDwTOF && !selectionPIDpTdepTOF(track2, 0)) // Track 2 is checked with Pion + continue; + + if (selectionConfig.isApplyMID && (selectionMID(track1, 0) || selectionMID(track2, 1))) + continue; + + if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 0) || selectionMIDpTdep(track2, 1))) continue; if (cQAplots) { @@ -847,10 +977,19 @@ struct Kstar892LightIon { } // since we are using combinations full index policy, so repeated pairs are allowed, so we can check one with Kaon and other with pion - if (!selectionConfig.isApplypTdepPID && (!selectionPID(track1, 1) || !selectionPID(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && (!selectionPID(track1, 1) || !selectionPID(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion continue; - if (selectionConfig.isApplypTdepPID && (!selectionPIDNew(track1, 1) || !selectionPIDNew(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + if (selectionConfig.isApplypTdepPID && (!selectionPIDpTdep(track1, 1) || !selectionPIDpTdep(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + continue; + + if (selectionConfig.isApplypTdepPIDwTOF && (!selectionPIDpTdepTOF(track1, 1) || !selectionPIDpTdepTOF(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + continue; + + if (selectionConfig.isApplyMID && (selectionMID(track1, 0) || selectionMID(track2, 1))) + continue; + + if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 0) || selectionMIDpTdep(track2, 1))) continue; if (cQAplots) { @@ -940,10 +1079,19 @@ struct Kstar892LightIon { continue; } - if (!selectionConfig.isApplypTdepPID && (!selectionPID(t1, 1) || !selectionPID(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && (!selectionPID(t1, 1) || !selectionPID(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + continue; + + if (selectionConfig.isApplypTdepPID && (!selectionPIDpTdep(t1, 1) || !selectionPIDpTdep(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + continue; + + if (selectionConfig.isApplypTdepPIDwTOF && (!selectionPIDpTdepTOF(t1, 1) || !selectionPIDpTdepTOF(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + continue; + + if (selectionConfig.isApplyMID && (selectionMID(t1, 0) || selectionMID(t2, 1))) continue; - if (selectionConfig.isApplypTdepPID && (!selectionPIDNew(t1, 1) || !selectionPIDNew(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(t1, 0) || selectionMIDpTdep(t2, 1))) continue; daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), massKa); @@ -1008,10 +1156,19 @@ struct Kstar892LightIon { continue; } - if (!selectionConfig.isApplypTdepPID && (!selectionPID(t1, 1) || !selectionPID(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && (!selectionPID(t1, 1) || !selectionPID(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion continue; - if (selectionConfig.isApplypTdepPID && (!selectionPIDNew(t1, 1) || !selectionPIDNew(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + if (selectionConfig.isApplypTdepPID && (!selectionPIDpTdep(t1, 1) || !selectionPIDpTdep(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + continue; + + if (selectionConfig.isApplypTdepPIDwTOF && (!selectionPIDpTdepTOF(t1, 1) || !selectionPIDpTdepTOF(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + continue; + + if (selectionConfig.isApplyMID && (selectionMID(t1, 0) || selectionMID(t2, 1))) + continue; + + if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(t1, 0) || selectionMIDpTdep(t2, 1))) continue; if (!t1.has_mcParticle() || !t2.has_mcParticle()) { @@ -1272,12 +1429,20 @@ struct Kstar892LightIon { } if (track1PDG == PDG_t::kPiPlus) { - if (!selectionConfig.isApplypTdepPID && !(selectionPID(track1, 0) && selectionPID(track2, 1))) { // pion and kaon + if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !(selectionPID(track1, 0) && selectionPID(track2, 1))) { // pion and kaon continue; - } else if (selectionConfig.isApplypTdepPID && !(selectionPIDNew(track1, 0) && selectionPIDNew(track2, 1))) { // pion and kaon + } else if (selectionConfig.isApplypTdepPID && !(selectionPIDpTdep(track1, 0) && selectionPIDpTdep(track2, 1))) { // pion and kaon + continue; + } else if (selectionConfig.isApplypTdepPIDwTOF && !(selectionPIDpTdepTOF(track1, 0) && selectionPIDpTdepTOF(track2, 1))) { continue; } + if (selectionConfig.isApplyMID && (selectionMID(track1, 1) || selectionMID(track2, 0))) + continue; + + if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 1) || selectionMIDpTdep(track2, 0))) + continue; + if (cQAplots) { if (track1.sign() < 0 && track2.sign() > 0) { hPID.fill(HIST("After/hTPCnsigPi_Neg_mult_pt"), track1.tpcNSigmaPi(), centrality, track1.pt()); @@ -1293,12 +1458,20 @@ struct Kstar892LightIon { } } else if (track1PDG == PDG_t::kKPlus) { - if (!selectionConfig.isApplypTdepPID && !(selectionPID(track1, 1) && selectionPID(track2, 0))) { // kaon and pion + if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !(selectionPID(track1, 1) && selectionPID(track2, 0))) { // kaon and pion + continue; + } else if (selectionConfig.isApplypTdepPID && !(selectionPIDpTdep(track1, 1) && selectionPIDpTdep(track2, 0))) { // kaon and pion continue; - } else if (selectionConfig.isApplypTdepPID && !(selectionPIDNew(track1, 1) && selectionPIDNew(track2, 0))) { // kaon and pion + } else if (selectionConfig.isApplypTdepPIDwTOF && !(selectionPIDpTdepTOF(track1, 1) && selectionPIDpTdepTOF(track2, 0))) { continue; } + if (selectionConfig.isApplyMID && (selectionMID(track1, 0) || selectionMID(track2, 1))) + continue; + + if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 0) || selectionMIDpTdep(track2, 1))) + continue; + if (cQAplots) { if (track1.sign() < 0 && track2.sign() > 0) { hPID.fill(HIST("After/hTPCnsigKa_Neg_mult_pt"), track1.tpcNSigmaKa(), centrality, track1.pt()); @@ -1415,7 +1588,7 @@ struct Kstar892LightIon { float centrality = 100.5f; for (auto const& collision : collisions) { - if (!selectionEvent(collision, false)) // don't fill event cut histogram + if (selectionConfig.isApplyEvSelFactors && !selectionEvent(collision, false)) continue; if (selectCentEstimator == kFT0M) { @@ -1618,6 +1791,114 @@ struct Kstar892LightIon { } } PROCESS_SWITCH(Kstar892LightIon, processRecMisID, "Process Reconstructed MisID Background", false); + + void processRecReflection(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, EventMCGenerated const&) + { + if (!collision.has_mcCollision()) + return; + + if (!selectionEvent(collision, false)) + return; + + if (selectCentEstimator == kFT0M) { + centrality = collision.centFT0M(); + } else if (selectCentEstimator == kFT0A) { + centrality = collision.centFT0A(); + } else if (selectCentEstimator == kFT0C) { + centrality = collision.centFT0C(); + } else if (selectCentEstimator == kFV0A) { + centrality = collision.centFV0A(); + } else { + centrality = collision.centFT0M(); // default + } + + for (const auto& [track1, track2] : + combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + + if (!selectionTrack(track1) || !selectionTrack(track2)) + continue; + + if (track1.index() >= track2.index()) + continue; + + if (track1.sign() * track2.sign() >= 0) + continue; + + if (!track1.has_mcParticle() || !track2.has_mcParticle()) + continue; + + const auto mc1 = track1.mcParticle(); + const auto mc2 = track2.mcParticle(); + + if (!mc1.isPhysicalPrimary() || !mc2.isPhysicalPrimary()) + continue; + + bool sameMother = false; + int motherPDG = 0; + + for (const auto& m1 : mc1.mothers_as()) { + for (const auto& m2 : mc2.mothers_as()) { + if (m1.globalIndex() == m2.globalIndex()) { + motherPDG = std::abs(m1.pdgCode()); + sameMother = true; + break; + } + } + if (sameMother) + break; + } + + if (!sameMother) + continue; + + ROOT::Math::PxPyPzMVector p1, p2; + + if (reflectionType == kRho) { // Rho0 (770) -> pi pi -> K pi + if (motherPDG != PDG_t::kRho770_0) + continue; + if (std::abs(mc1.pdgCode()) != PDG_t::kPiPlus || std::abs(mc2.pdgCode()) != PDG_t::kPiPlus) + continue; + + p1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + p2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + } else if (reflectionType == kOmega) { // Omega (782) -> pi pi (pi0) -> K pi + if (motherPDG != o2::constants::physics::kOmega) + continue; + if (std::abs(mc1.pdgCode()) != PDG_t::kPiPlus || std::abs(mc2.pdgCode()) != PDG_t::kPiPlus) + continue; + + p1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + p2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + } else if (reflectionType == kPhi) { // Phi (1020) -> K K -> K pi + if (motherPDG != o2::constants::physics::kPhi) + continue; + if (std::abs(mc1.pdgCode()) != PDG_t::kKPlus || std::abs(mc2.pdgCode()) != PDG_t::kKPlus) + continue; + + p1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massPi); + p2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + } else if (reflectionType == kKstar) { // K*0 (892) Self-Reflection (swap) + if (motherPDG != o2::constants::physics::kK0Star892) + continue; + + if (!((std::abs(mc1.pdgCode()) == PDG_t::kPiPlus && std::abs(mc2.pdgCode()) == PDG_t::kKPlus) || (std::abs(mc1.pdgCode()) == PDG_t::kKPlus && std::abs(mc2.pdgCode()) == PDG_t::kPiPlus))) + continue; + + p1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), std::abs(mc1.pdgCode()) == PDG_t::kKPlus ? massPi : massKa); + p2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), std::abs(mc2.pdgCode()) == PDG_t::kKPlus ? massPi : massKa); + } else { + continue; + } + + auto fakeMother = p1 + p2; + + if (fakeMother.Rapidity() < selectionConfig.motherRapidityMin || fakeMother.Rapidity() > selectionConfig.motherRapidityMax) + continue; + + hMC.fill(HIST("Reflections/hReflection"), fakeMother.Pt(), centrality, fakeMother.M()); + } + } + PROCESS_SWITCH(Kstar892LightIon, processRecReflection, "Process particle reflection", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Resonances/kstarInOO.cxx b/PWGLF/Tasks/Resonances/kstarInOO.cxx index 628e2a6fddb..f94d02d49d6 100644 --- a/PWGLF/Tasks/Resonances/kstarInOO.cxx +++ b/PWGLF/Tasks/Resonances/kstarInOO.cxx @@ -33,6 +33,14 @@ #include #include +// jet +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" + +#include + #include #include #include @@ -67,6 +75,7 @@ struct kstarInOO { //================================== // Event Selection + Configurable cfgEventSelections{"cfgEventSelections", "sel8", "Set event selection"}; Configurable cfgEventVtxCut{"cfgEventVtxCut", 10.0, "V_z cut selection"}; ConfigurableAxis cfgCentAxis{"cfgCentAxis", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0}, "Binning of the centrality axis"}; Configurable cfgOccupancySel{"cfgOccupancySel", false, "Occupancy selection"}; @@ -84,13 +93,13 @@ struct kstarInOO { Configurable cfgTrackConnectedToPV{"cfgTrackConnectedToPV", true, "PV contributor track selection"}; // PV Contriuibutor Configurable cfgTrackGlobalWoDCATrack{"cfgTrackGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) // TPC - Configurable cfgTracknFindableTPCClusters{"cfgTrackFindableTPCClusters", 50, "nFindable TPC Clusters"}; - Configurable cfgTracknTPCCrossedRows{"cfgTrackTPCCrossedRows", 70, "nCrossed TPC Rows"}; - Configurable cfgTracknRowsOverFindable{"cfgTrackRowsOverFindable", 1.2, "nRowsOverFindable TPC CLusters"}; - Configurable cfgTracknTPCChi2{"cfgTrackTPCChi2", 4.0, "nTPC Chi2 per Cluster"}; + Configurable cfgTrackFindableTPCClusters{"cfgTrackFindableTPCClusters", 50, "nFindable TPC Clusters"}; + Configurable cfgTrackTPCCrossedRows{"cfgTrackTPCCrossedRows", 70, "nCrossed TPC Rows"}; + Configurable cfgTrackRowsOverFindable{"cfgTrackRowsOverFindable", 1.2, "nRowsOverFindable TPC CLusters"}; + Configurable cfgTrackTPCChi2{"cfgTrackTPCChi2", 4.0, "nTPC Chi2 per Cluster"}; // ITS - Configurable cfgTracknITSChi2{"cfgTrackITSChi2", 36.0, "nITS Chi2 per Cluster"}; + Configurable cfgTrackITSChi2{"cfgTrackITSChi2", 36.0, "nITS Chi2 per Cluster"}; // PID Configurable cfgTrackTPCPID{"cfgTrackTPCPID", true, "Enables TPC PID"}; @@ -123,9 +132,34 @@ struct kstarInOO { ConfigurableAxis binsDCAxy{"binsDCAxy", {40, -0.2, 0.2}, ""}; Configurable cfgEventCutQA{"cfgEventCutsQA", false, "Enable Event QA Hists"}; Configurable cfgTrackCutQA{"cfgTrackCutQA", false, "Enable Track QA Hists"}; + Configurable cfgJetQAHistos{"cfgJetQAHistos", false, "Enable Jet QA Histos"}; + Configurable cfgDataHistos{"cfgDataHistos", false, "Enable Data Hists"}; Configurable cfgMcHistos{"cfgMcHistos", false, "Enable MC Hists"}; + Configurable cfgJetDataHistos{"cfgJetDataHistos", false, "Enable Jet Data Histos"}; + Configurable cfgJetMCHistos{"cfgJetMCHistos", false, "Enable Jet MC Histos"}; + Configurable cfgCutonTrig{"cfgCutonTrig", false, "Enable Jet Cut on Trig"}; + Configurable cfgTestTriggers{"cfgTestTriggers", false, "Enable Jet Test Triggers"}; + + //====================== + //|| + //|| JET + //|| + //====================== + Configurable cfgJetpT{"cfgJetpT", 5.0, "Set Jet pT minimum"}; + Configurable cfgJetR{"cfgJetR", 0.4, "Set Jet radius parameter"}; + Configurable cfgSingleJet{"cfgSingleJet", false, "Enforces strict phi-jet correspondance"}; + Configurable cfgRealTriggerMasks{"cfgRealTriggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"}; + Configurable cfgTriggerMasksTest1{"cfgTriggerMasksTest1", "", "possible JE Trigger masks Test1"}; + Configurable cfgTriggerMasksTest2{"cfgTriggerMasksTest2", "", "possible JE Trigger masks Test2"}; + Configurable cfgTriggerMasksTest3{"cfgTriggerMasksTest3", "", "possible JE Trigger masks Test3"}; + + std::vector eventSelectionBits; + std::vector RealTriggerMaskBits; + std::vector triggerMaskBitsTest1; + std::vector triggerMaskBitsTest2; + std::vector triggerMaskBitsTest3; // Main void init(o2::framework::InitContext&) { @@ -137,10 +171,11 @@ struct kstarInOO { const AxisSpec minvAxis = {cfgMinvNBins, cfgMinvMin, cfgMinvMax}; const AxisSpec axisDCAz{binsDCAz, "DCA_{z}"}; const AxisSpec axisDCAxy{binsDCAxy, "DCA_{XY}"}; + const AxisSpec dRAxis = {100, 0, 100}; if (cfgEventCutQA) { histos.add("hEvent_Cut", "Number of event after cuts", kTH1D, {{12, 0, 12}}); - histos.add("hPosZ_BC", "hPosZ_Bc", kTH1F, {{300, -15.0, 15.0}}); + histos.add("hPosZ_BC", "hPosZ_BC", kTH1F, {{300, -15.0, 15.0}}); histos.add("hPosZ_AC", "hPosZ_AC", kTH1F, {{300, -15.0, 15.0}}); histos.add("hcentFT0C_BC", "centFT0C_BC", kTH1F, {{110, 0.0, 110.0}}); histos.add("hcentFT0C_AC", "centFT0C_AC", kTH1F, {{110, 0.0, 110.0}}); @@ -156,6 +191,7 @@ struct kstarInOO { histos.add("hFindableTPCRows_BC", "hFindableTPCRows_BC", kTH1F, {{200, 0, 200}}); histos.add("hClustersVsRows_BC", "hClustersVsRows_BC", kTH1F, {{200, 0, 2}}); histos.add("hTPCChi2_BC", "hTPCChi2_BC", kTH1F, {{200, 0, 100}}); + histos.add("hITSChi2_BC", "hITSChi2_BC", kTH1F, {{200, 0, 100}}); histos.add("QA_nSigma_pion_TPC_BC", "QA_nSigma_pion_TPC_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_nSigma_pion_TOF_BC", "QA_nSigma_pion_TOF_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_pion_TPC_TOF_BC", "QA_pion_TPC_TOF_BC", {HistType::kTH2F, {pidAxis, pidAxis}}); @@ -173,6 +209,7 @@ struct kstarInOO { histos.add("hFindableTPCRows_AC", "hFindableTPCRows_AC", kTH1F, {{200, 0, 200}}); histos.add("hClustersVsRows_AC", "hClustersVsRows_AC", kTH1F, {{200, 0, 2}}); histos.add("hTPCChi2_AC", "hTPCChi2_AC", kTH1F, {{200, 0, 100}}); + histos.add("hITSChi2_AC", "hITSChi2_AC", kTH1F, {{200, 0, 100}}); histos.add("QA_nSigma_pion_TPC_AC", "QA_nSigma_pion_TPC_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_nSigma_pion_TOF_AC", "QA_nSigma_pion_TOF_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); histos.add("QA_pion_TPC_TOF_AC", "QA_pion_TPC_TOF_AC", {HistType::kTH2F, {pidAxis, pidAxis}}); @@ -210,6 +247,36 @@ struct kstarInOO { histos.add("hMC_USS_PiK_True", "hMC_USS_PiK_True", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); } + if (cfgJetQAHistos) { + histos.add("JetpT", "Jet pT (GeV/c)", kTH1F, {{4000, 0., 200.}}); + histos.add("JetEta", "Jet Eta", kTH1F, {{100, -1.0, 1.0}}); + histos.add("JetPhi", "Jet Phi", kTH1F, {{80, -1.0, 7.0}}); + + histos.add("rawDimpT", "rawDimpT", kTH2F, {{1000, 0.0, 10.0}, {100, -0.5, 0.5}}); + histos.add("jetTrackEta", "Jet Track Eta", kTH1F, {{100, -1.0, 1.0}}); + histos.add("jetTrackPhi", "Jet Track Phi", kTH1F, {{80, -1.0, 7.0}}); + + histos.add("nJetsPerEvent", "nJetsPerEvent", kTH1I, {{4, -0.5, 3.5}}); + histos.add("nGoodjets", "nGoodjets", kTH1I, {{4, -0.5, 3.5}}); + } + if (cfgJetDataHistos) { + histos.add("nJetEvents", "nJetEvents", kTH1F, {{7, 0.0, 7.0}}); + histos.add("nTriggerQA", "nTriggerQA", kTH1F, {{7, 0.0, 7.0}}); + + histos.add("hMB_USS_KPi", "hMB_USS_KPi", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMB_USS_PiK", "hMB_USS_PiK", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMB_LSS_KPi", "hMB_LSS_KPi", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMB_LSS_PiK", "hMB_LSS_PiK", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + + histos.add("hUSS_INSIDE_KPi", "hUSS_INSIDE_KPi", kTHnSparseF, {cfgCentAxis, dRAxis, ptAxis, minvAxis}); + histos.add("hUSS_INSIDE_PiK", "hUSS_INSIDE_PiK", kTHnSparseF, {cfgCentAxis, dRAxis, ptAxis, minvAxis}); + histos.add("hLSS_INSIDE_KPi", "hLSS_INSIDE_KPi", kTHnSparseF, {cfgCentAxis, dRAxis, ptAxis, minvAxis}); + histos.add("hLSS_INSIDE_PiK", "hLSS_INSIDE_PiK", kTHnSparseF, {cfgCentAxis, dRAxis, ptAxis, minvAxis}); + } + if (cfgJetMCHistos) { + histos.add("nJetMCEvents", "nJetMCEvents", kTH1F, {{7, -.0, 7.0}}); + } + std::shared_ptr hCutFlow = histos.get(HIST("hEvent_Cut")); std::vector eventCutLabels = { "All Events", @@ -227,14 +294,39 @@ struct kstarInOO { hCutFlow->GetXaxis()->SetBinLabel(i + 1, eventCutLabels[i].c_str()); } + // Jet + eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(cfgEventSelections)); + RealTriggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(cfgRealTriggerMasks); + triggerMaskBitsTest1 = jetderiveddatautilities::initialiseTriggerMaskBits(cfgTriggerMasksTest1); + triggerMaskBitsTest2 = jetderiveddatautilities::initialiseTriggerMaskBits(cfgTriggerMasksTest2); + triggerMaskBitsTest3 = jetderiveddatautilities::initialiseTriggerMaskBits(cfgTriggerMasksTest3); } // end of init + //====================== + //|| For LF Analysis + //====================== using EventCandidates = soa::Join; //, aod::CentFT0Ms, aod::CentFT0As using EventCandidatesTrue = aod::McCollisions; using TrackCandidates = soa::Join; using TrackCandidatesMC = soa::Join; + + //============== + //|| For jets + //============== + Filter JEPosZFilter = nabs(aod::jcollision::posZ) < cfgEventVtxCut; + Filter JEMCPosZFilter = nabs(aod::jmccollision::posZ) < cfgEventVtxCut; + Filter jetCuts = aod::jet::pt > cfgJetpT&& aod::jet::r == nround(cfgJetR.node() * 100.0f); + + using JetSelectedMCCollisions = soa::Join; + using JetSelectedDataCollisions = soa::Join; + using JetTrackCandidates = soa::Join; + + using JetFilteredMCCollisions = soa::Filtered; + using JetFilteredDataCollisions = soa::Filtered; + using JetFilteredJets = soa::Filtered>; + // For Mixed Event using BinningType = ColumnBinningPolicy; @@ -325,6 +417,7 @@ struct kstarInOO { histos.fill(HIST("hFindableTPCRows_BC"), track.tpcNClsCrossedRows()); histos.fill(HIST("hClustersVsRows_BC"), track.tpcCrossedRowsOverFindableCls()); histos.fill(HIST("hTPCChi2_BC"), track.tpcChi2NCl()); + histos.fill(HIST("hITSChi2_BC"), track.itsChi2NCl()); histos.fill(HIST("QA_track_pT_BC"), track.pt()); } if (cfgTrackGlobalSel && !track.isGlobalTrack()) @@ -341,15 +434,15 @@ struct kstarInOO { return false; if (cfgTrackGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) return false; - if (cfgTracknFindableTPCClusters > 0 && track.tpcNClsFindable() < cfgTracknFindableTPCClusters) + if (cfgTrackFindableTPCClusters > 0 && track.tpcNClsFindable() < cfgTrackFindableTPCClusters) return false; - if (track.tpcNClsCrossedRows() < cfgTracknTPCCrossedRows) + if (track.tpcNClsCrossedRows() < cfgTrackTPCCrossedRows) return false; - if (cfgTracknRowsOverFindable > 0 && track.tpcCrossedRowsOverFindableCls() > cfgTracknRowsOverFindable) + if (cfgTrackRowsOverFindable > 0 && track.tpcCrossedRowsOverFindableCls() > cfgTrackRowsOverFindable) return false; - if (track.tpcChi2NCl() > cfgTracknTPCChi2) + if (track.tpcChi2NCl() > cfgTrackTPCChi2) return false; - if (track.itsChi2NCl() > cfgTracknITSChi2) + if (track.itsChi2NCl() > cfgTrackITSChi2) return false; if (cfgTrackConnectedToPV && !track.isPVContributor()) return false; @@ -364,6 +457,7 @@ struct kstarInOO { histos.fill(HIST("hFindableTPCRows_AC"), track.tpcNClsCrossedRows()); histos.fill(HIST("hClustersVsRows_AC"), track.tpcCrossedRowsOverFindableCls()); histos.fill(HIST("hTPCChi2_AC"), track.tpcChi2NCl()); + histos.fill(HIST("hITSChi2_AC"), track.itsChi2NCl()); histos.fill(HIST("QA_track_pT_AC"), track.pt()); } return true; @@ -664,6 +758,253 @@ struct kstarInOO { return {lResonance.Pt(), lResonance.M()}; } + template + double DistinguishJets(const JetType& jets, const TLorentzVector lResonance) + { + if (cDebugLevel > 0) + std::cout << "Finded multiple jets to the same phi." << std::endl; + + double bestR = 0; + double bestJetpT = 0; + for (auto const& jet : jets) { + double phidiff = TVector2::Phi_mpi_pi(jet.phi() - lResonance.Phi()); + double etadiff = jet.eta() - lResonance.Eta(); + double R = TMath::Sqrt((phidiff * phidiff) + (etadiff * etadiff)); + if (R < cfgJetR && bestR == 0) { + bestR = R; + bestJetpT = jet.pt(); + } else if (R < bestR) { + bestR = R; + bestJetpT = jet.pt(); + } + } // jet + return bestJetpT; + } + + template + std::pair JetminvReconstruction(aod::JetCollision const& collision, const TracksType& trk1, const TracksType& trk2, const JetType& jets, const bool QA, const bool flip) + { + if (!trackSelection(trk1, false) || !trackSelection(trk2, false)) + return {-1.0, -1.0}; + + if (!trackPIDKaon(trk1, QA) || !trackPIDPion(trk2, QA)) + return {-1.0, -1.0}; + + if (trk1.globalIndex() >= trk2.globalIndex()) + return {-1.0, -1.0}; + + TLorentzVector lDecayDaughter1, lDecayDaughter2, lResonance; + if (!flip) { + lDecayDaughter1.SetXYZM(trk1.px(), trk1.py(), trk1.pz(), massKa); + lDecayDaughter2.SetXYZM(trk2.px(), trk2.py(), trk2.pz(), massPi); + } else { + lDecayDaughter1.SetXYZM(trk1.px(), trk1.py(), trk1.pz(), massPi); + lDecayDaughter2.SetXYZM(trk2.px(), trk2.py(), trk2.pz(), massKa); + } + lResonance = lDecayDaughter1 + lDecayDaughter2; + + if (std::abs(lResonance.Eta()) > cfgTrackMaxEta) + return {-1.0, -1.0}; + + //====================== + //| MinBias Event M_inv + //====================== + auto mult = collision.centFT0C(); + double conjugate = trk1.sign() * trk2.sign(); + if (cfgJetDataHistos) { + if (!flip) { + if (conjugate < 0) { + histos.fill(HIST("hMB_USS_KPi"), mult, lResonance.Pt(), lResonance.M()); + } else if (conjugate > 0) { + histos.fill(HIST("hMB_LSS_KPi"), mult, lResonance.Pt(), lResonance.M()); + } + } else { + if (conjugate < 0) { + histos.fill(HIST("hMB_USS_PiK"), mult, lResonance.Pt(), lResonance.M()); + } else if (conjugate > 0) { + histos.fill(HIST("hMB_LSS_PiK"), mult, lResonance.Pt(), lResonance.M()); + } + } + } // cfgJetDataHistos + + //====================== + //| Inside jets M_inv + //====================== + bool jetFlag = false; + int goodjets = 0; + double jetpt = 0; + for (auto const& jet : jets) { + double phidiff = TVector2::Phi_mpi_pi(jet.phi() - lResonance.Phi()); + double etadiff = jet.eta() - lResonance.Eta(); + double R = TMath::Sqrt((etadiff * etadiff) + (phidiff * phidiff)); + if (R < cfgJetR) { + jetFlag = true; + jetpt = jet.pt(); + goodjets++; + } + } + if (cfgJetQAHistos) { + histos.fill(HIST("nGoodjets"), goodjets); + } + if (!cfgSingleJet) { + if (goodjets > 1) { + jetpt = DistinguishJets(jets, lResonance); + } + } + + if (jetFlag) { + if (cfgJetDataHistos) { + if (!flip) { + if (conjugate < 0) { + histos.fill(HIST("hUSS_INSIDE_KPi"), mult, jetpt, lResonance.Pt(), lResonance.M()); + } else if (conjugate > 0) { + histos.fill(HIST("hLSS_INSIDE_KPi"), mult, jetpt, lResonance.Pt(), lResonance.M()); + } + } else { + if (conjugate < 0) { + histos.fill(HIST("hUSS_INSIDE_PiK"), mult, jetpt, lResonance.Pt(), lResonance.M()); + } else if (conjugate > 0) { + histos.fill(HIST("hLSS_INSIDE_PiK"), mult, jetpt, lResonance.Pt(), lResonance.M()); + } + } + } // cfgJetDataHistos + } // jetFlag + + if (lResonance.M() > 0.85 && lResonance.M() < 0.95) { + if (jetFlag) + return {3.0, 3.0}; + if (goodjets > 0) + return {2.0, 2.0}; + return {1.0, 1.0}; + } else { + return {-1.0, -1.0}; + } + } // JetminvReconstruction + + //======================================================= + //| + //| JET DATA STUFF + //| + //======================================================= + int nJetEvents = 0; + void processDataJets(aod::JetCollision const& collision, soa::Filtered> const& chargedjets, soa::Join const& jetTracks, TrackCandidates const&) + { + if (cDebugLevel > 0) { + nJetEvents++; + if ((nJetEvents + 1) % 10000 == 0) { + std::cout << "Processed Jet Data Events: " << nJetEvents << std::endl; + } + } + if (cfgJetDataHistos) { + histos.fill(HIST("nJetEvents"), 0.5); // Raw event + } + + if (std::abs(collision.posZ()) > cfgEventVtxCut) + return; + + // Trigger before we start jet finding + if (cfgCutonTrig) { + bool RT = false; + bool VTtest1 = false; + bool VTtest2 = false; + bool VTtest3 = false; + if (jetderiveddatautilities::selectTrigger(collision, RealTriggerMaskBits)) { + RT = true; + if (cfgJetDataHistos) { + histos.fill(HIST("nTriggerQA"), 0.5); + } + } + if (jetderiveddatautilities::selectTrigger(collision, triggerMaskBitsTest1)) { + VTtest1 = true; + if (cfgJetDataHistos) { + histos.fill(HIST("nTriggerQA"), 1.5); + } + } + if (jetderiveddatautilities::selectTrigger(collision, triggerMaskBitsTest2)) { + VTtest2 = true; + if (cfgJetDataHistos) { + histos.fill(HIST("nTriggerQA"), 2.5); + } + } + if (jetderiveddatautilities::selectTrigger(collision, triggerMaskBitsTest3)) { + VTtest3 = true; + if (cfgJetDataHistos) { + histos.fill(HIST("nTriggerQA"), 3.5); + } + } + if (!RT) { + return; + } else if (RT && (VTtest1 || VTtest2 || VTtest3)) { + return; + } + } // Trigger cut + + if (cfgJetDataHistos) { + histos.fill(HIST("nJetEvents"), 1.5); // Before passing the condition + } + + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + return; + } + + if (cfgJetDataHistos) { + histos.fill(HIST("nJetEvents"), 2.5); // Events after event quality selection for Inclusive + } + + std::vector jetpT{}; + std::vector jetEta{}; + std::vector jetPhi{}; + bool HasJets = false; + int nJets = 0; + for (auto chargedjet : chargedjets) { + jetpT.push_back(chargedjet.pt()); + jetEta.push_back(chargedjet.eta()); + jetPhi.push_back(chargedjet.phi()); + nJets++; + if (cfgJetQAHistos) { + histos.fill(HIST("JetpT"), chargedjet.pt()); + histos.fill(HIST("JetEta"), chargedjet.eta()); + histos.fill(HIST("JetPhi"), chargedjet.phi()); + } + if (chargedjet.pt() > cfgJetpT) + HasJets = true; + } + if (cfgJetQAHistos) { + histos.fill(HIST("nJetsPerEvent"), nJets); + } + + if (!HasJets) + return; + if (cfgJetDataHistos) { + histos.fill(HIST("nJetEvents"), 3.5); // Has jets + } + + for (auto& [track1, track2] : combinations(o2::soa::CombinationsFullIndexPolicy(jetTracks, jetTracks))) { + auto trk1 = track1.track_as>(); + auto trk2 = track2.track_as>(); + + JetminvReconstruction(collision, trk1, trk2, chargedjets, true, false); + JetminvReconstruction(collision, trk1, trk2, chargedjets, true, true); + } // track loop + + bool INELgt0 = false; + for (auto& jetTrack : jetTracks) { + auto originTrack = jetTrack.track_as>(); + if (!trackSelection(originTrack, true)) + continue; + INELgt0 = true; + + if (cfgJetQAHistos) { + histos.fill(HIST("rawDimpT"), jetTrack.pt(), jetTrack.pt() - originTrack.pt()); + histos.fill(HIST("jetTrackEta"), jetTrack.eta()); + histos.fill(HIST("jetTrackPhi"), jetTrack.phi()); + } + } // jetTrack loop + if (!INELgt0) + return; + } // ProcessDataJets + PROCESS_SWITCH(kstarInOO, processDataJets, "process Data Jets", false); + //======================================================= //| //| DATA STUFF (SE) diff --git a/PWGLF/Tasks/Resonances/phianalysisTHnSparse.cxx b/PWGLF/Tasks/Resonances/phianalysisTHnSparse.cxx index 27d4ed55de3..b8a921c29c6 100644 --- a/PWGLF/Tasks/Resonances/phianalysisTHnSparse.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisTHnSparse.cxx @@ -108,9 +108,10 @@ struct PhianalysisTHnSparse { // other axes ConfigurableAxis axisNch{"axisNch", {1000, 0.0f, +1000.0f}, "Number of charged particles."}; ConfigurableAxis axisResolutionPt{"axisResolutionPt", {1001, -1.0f, +1.0f}, "Resolution of Pt."}; - ConfigurableAxis axisResolutionPtPhi{"axisResolutionPtPhi", {1001, -0.0001f, +0.0001f}, "Resolution of Pt and Phi."}; - ConfigurableAxis axisResolutionMass{"axisResolutionMass", {1001, -0.05f, +0.05f}, "Resolution of Mass."}; + ConfigurableAxis axisResolutionPtPhi{"axisResolutionPtPhi", {1001, -0.01f, +0.01f}, "Resolution of Pt and Phi."}; + ConfigurableAxis axisResolutionMass{"axisResolutionMass", {1001, -0.01f, +0.01f}, "Resolution of Mass."}; ConfigurableAxis axisResolutionVz{"axisResolutionVz", {1001, -3.0f, +3.0f}, "Resolution of Vz."}; + ConfigurableAxis massShiftAxis{"massShiftAxis", {1001, -0.02f, 0.02f}, "Mass correction axis."}; // Axes specifications AxisSpec posZaxis = {400, -20., 20., "V_{z} (cm)"}; @@ -118,6 +119,7 @@ struct PhianalysisTHnSparse { AxisSpec dcaZaxis = {1000, -1.0, 1.0, "DCA_{z} (cm)"}; AxisSpec etaQAaxis = {1000, -1.0, 1.0, "#eta"}; AxisSpec tpcNClsFoundQAaxis = {110, 50., 160., "tpcNClsFound"}; + AxisSpec massShiftRelAxis = {101, -0.03f, 0.03f, ""}; HistogramRegistry registry{"registry"}; o2::analysis::rsn::Output* rsnOutput = nullptr; @@ -127,9 +129,12 @@ struct PhianalysisTHnSparse { int n = 0; float massPos = o2::track::PID::getMass(3); float massNeg = o2::track::PID::getMass(3); + int pion = 2; + int kaon = 3; + int proton = 4; double* pointPair = nullptr; double* pointSys = nullptr; - ROOT::Math::PxPyPzMVector d1, d2, mother; + ROOT::Math::PxPyPzMVector d1, d2, mother, motherGen; bool produceTrue, produceLikesign, produceQA, produceStats, produceRotational, dataQA, MCTruthQA, globalTrack, inelGrater0, tpcPidOnly = false; float tpcnSigmaPos = 100.0f; float tpcnSigmaNeg = 100.0f; @@ -145,7 +150,7 @@ struct PhianalysisTHnSparse { using EventCandidates = soa::Join; using EventCandidate = EventCandidates::iterator; - using TrackCandidates = soa::Join; + using TrackCandidates = soa::Join; using EventCandidatesMC = soa::Join; using TrackCandidatesMC = soa::Join; @@ -417,17 +422,28 @@ struct PhianalysisTHnSparse { hResVz->GetYaxis()->SetTitle("#DeltaV_{z} = V_{z}^{rec} - V_{z}^{gen} (cm)"); registry.add("Factors/h2ResolutionPt", "Resolution of charged particles p_{T}", kTH2F, {ptaxis, axisResolutionPt}); auto hResPt = registry.get(HIST("Factors/h2ResolutionPt")); - ; + hResPt->GetXaxis()->SetTitle("p_{T}^{rec} (GeV/c)"); hResPt->GetYaxis()->SetTitle("#Deltap_{T} = p_{T}^{rec} - p_{T}^{gen} (GeV/c)"); - registry.add("Factors/h2ResolutionPtPhi", "Resolution of Phi p_{T}", kTH2F, {ptaxis, axisResolutionPtPhi}); + registry.add("Factors/h2ResolutionPtPhi", "p_{T} resolution vs p_{T}^{rec}", kTH2F, {ptaxis, axisResolutionPtPhi}); auto hResPtPhi = registry.get(HIST("Factors/h2ResolutionPtPhi")); hResPtPhi->GetXaxis()->SetTitle("p_{T}^{rec} (GeV/c)"); hResPtPhi->GetYaxis()->SetTitle("#Deltap_{T} = p_{T}^{rec} - p_{T}^{gen} (GeV/c)"); - registry.add("Factors/h2ResolutionMass", "Resolution of mass vs p_{T}^{rec}", kTH2F, {ptaxis, axisResolutionMass}); - auto hResMass = registry.get(HIST("Factors/h2ResolutionMass")); + + registry.add("Factors/h2MassResolution", "Mass resolution vs p_{T}^{rec}", kTH2F, {ptaxis, axisResolutionMass}); + auto hResMass = registry.get(HIST("Factors/h2MassResolution")); hResMass->GetXaxis()->SetTitle("p_{T}^{rec} (GeV/c)"); - hResMass->GetYaxis()->SetTitle("#Deltam = m^{rec} - m^{gen} (GeV/c^{2})"); + hResMass->GetYaxis()->SetTitle("#Deltam = m^{gen}_{KK} - m^{rec}_{KK} (GeV/c^{2})"); + + registry.add("Factors/h2MassShift", "Mass shift vs p_{T}^{rec}", kTH2F, {ptaxis, massShiftAxis}); + auto hResMassGen = registry.get(HIST("Factors/h2MassShift")); + hResMassGen->GetXaxis()->SetTitle("p_{T}^{rec} (GeV/c)"); + hResMassGen->GetYaxis()->SetTitle("#Deltam = m^{gen}_{#phi} - m^{gen}_{KK} (GeV/c^{2})"); + + registry.add("Factors/h2MassShiftRel", "Relative mass shift vs p_{T}^{rec}", kTH2F, {ptaxis, massShiftRelAxis}); + auto hMassCorr = registry.get(HIST("Factors/h2MassShiftRel")); + hMassCorr->GetXaxis()->SetTitle("p_{T}^{rec} (GeV/c)"); + hMassCorr->GetYaxis()->SetTitle("m^{gen}_{#phi} - m^{gen}_{KK}/m^{gen}_{#phi}"); } } // Factors @@ -445,6 +461,34 @@ struct PhianalysisTHnSparse { registry.add("Factors/h3dGenPhiVsMultMCVsCentrality", "MC multiplicity vs centrality vs p_{T}", kTH3D, {axisNch, {101, 0.0f, 101.0f}, ptaxis}); } + template + float tpcNsigma(const T& track) + { + float tpcNsigma = 0.0f; + int particleType = (track.sign() > 0) ? static_cast(daughterPos) : static_cast(daughterNeg); + + if (particleType == pion) + tpcNsigma = track.tpcNSigmaPi(); + else if (particleType == kaon) + tpcNsigma = track.tpcNSigmaKa(); + else if (particleType == proton) + tpcNsigma = track.tpcNSigmaPr(); + return tpcNsigma; + } + template + float tofNsigma(const T& track) + { + float tofNsigma = 0.0f; + int particleType = (track.sign() > 0) ? static_cast(daughterPos) : static_cast(daughterNeg); + + if (particleType == pion) + tofNsigma = track.tofNSigmaPi(); + else if (particleType == kaon) + tofNsigma = track.tofNSigmaKa(); + else if (particleType == proton) + tofNsigma = track.tofNSigmaPr(); + return tofNsigma; + } template bool selectedTrack(const T& track, bool isPositive) { @@ -473,10 +517,10 @@ struct PhianalysisTHnSparse { // PID selection: TPC-only for pt < threshold value, TPC+TOF for pt >= threshold value and have TOF, else TPC-only float nSigmaCut = isPositive ? tpcnSigmaPos : tpcnSigmaNeg; if (track.pt() < ptTOFThreshold || !track.hasTOF() || tpcPidOnly) { - if (std::abs(track.tpcNSigmaKa()) >= nSigmaCut) + if (std::abs(tpcNsigma(track)) >= nSigmaCut) return false; } else { - if (std::sqrt(track.tpcNSigmaKa() * track.tpcNSigmaKa() + track.tofNSigmaKa() * track.tofNSigmaKa()) >= combinedNSigma) + if (std::sqrt(tpcNsigma(track) * tpcNsigma(track) + tofNsigma(track) * tofNsigma(track)) >= combinedNSigma) return false; } if (produceQA && dataQA) @@ -512,15 +556,16 @@ struct PhianalysisTHnSparse { return true; } template - bool selectedPair(ROOT::Math::PxPyPzMVector& mother, const T& track1, const T& track2) + ROOT::Math::PxPyPzMVector calculateMother(const T& track1, const T& track2) { d1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massPos); d2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massNeg); - mother = d1 + d2; - + return d1 + d2; + } + bool seletectedMother(const ROOT::Math::PxPyPzMVector& mother) + { if (std::abs(mother.Rapidity()) > static_cast(cut.rapidity)) return false; - return true; } template @@ -613,24 +658,25 @@ struct PhianalysisTHnSparse { if (!selectedTrack(track2, false)) // track2 is negative continue; - if (!selectedPair(mother, track1, track2)) + mother = calculateMother(track1, track2); + if (!seletectedMother(mother)) continue; if (produceQA) { - registry.fill(HIST("QAPID/h2TPCnSigma"), track1.tpcNSigmaKa(), track2.tpcNSigmaKa()); - registry.fill(HIST("QAPID/h2TPCnSigmaPt"), track1.pt(), track1.tpcNSigmaKa()); - registry.fill(HIST("QAPID/h2TPCnSigmaPt"), track2.pt(), track2.tpcNSigmaKa()); + registry.fill(HIST("QAPID/h2TPCnSigma"), tpcNsigma(track1), tpcNsigma(track2)); + registry.fill(HIST("QAPID/h2TPCnSigmaPt"), track1.pt(), tpcNsigma(track1)); + registry.fill(HIST("QAPID/h2TPCnSigmaPt"), track2.pt(), tpcNsigma(track2)); - registry.fill(HIST("QAPID/h2TOFnSigma"), track1.tofNSigmaKa(), track2.tofNSigmaKa()); - registry.fill(HIST("QAPID/h2TOFnSigmaPt"), track1.pt(), track1.tofNSigmaKa()); - registry.fill(HIST("QAPID/h2TOFnSigmaPt"), track2.pt(), track2.tofNSigmaKa()); + registry.fill(HIST("QAPID/h2TOFnSigma"), tofNsigma(track1), tofNsigma(track2)); + registry.fill(HIST("QAPID/h2TOFnSigmaPt"), track1.pt(), tofNsigma(track1)); + registry.fill(HIST("QAPID/h2TOFnSigmaPt"), track2.pt(), tofNsigma(track2)); - registry.fill(HIST("QAPID/hTPCnSigma"), track1.tpcNSigmaKa()); - registry.fill(HIST("QAPID/hTPCnSigma"), track2.tpcNSigmaKa()); + registry.fill(HIST("QAPID/hTPCnSigma"), tpcNsigma(track1)); + registry.fill(HIST("QAPID/hTPCnSigma"), tpcNsigma(track2)); if (track1.hasTOF()) - registry.fill(HIST("QAPID/hTOFnSigma"), track1.tofNSigmaKa()); + registry.fill(HIST("QAPID/hTOFnSigma"), tofNsigma(track1)); if (track2.hasTOF()) - registry.fill(HIST("QAPID/hTOFnSigma"), track2.tofNSigmaKa()); + registry.fill(HIST("QAPID/hTOFnSigma"), tofNsigma(track2)); registry.fill(HIST("QATrack/hEta"), track1.eta()); registry.fill(HIST("QATrack/hEta"), track2.eta()); @@ -657,8 +703,8 @@ struct PhianalysisTHnSparse { mother.Pt(), getMultiplicity(collision), getCentrality(collision), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), collision.posZ(), @@ -688,8 +734,8 @@ struct PhianalysisTHnSparse { mother.Pt(), getMultiplicity(collision), getCentrality(collision), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), collision.posZ(), @@ -710,7 +756,8 @@ struct PhianalysisTHnSparse { if (!selectedTrack(track2, true)) // both positive continue; - if (!selectedPair(mother, track1, track2)) + mother = calculateMother(track1, track2); + if (!seletectedMother(mother)) continue; if (static_cast(verbose.verboselevel) > 1) @@ -720,8 +767,8 @@ struct PhianalysisTHnSparse { mother.Pt(), getMultiplicity(collision), getCentrality(collision), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), collision.posZ(), @@ -738,7 +785,8 @@ struct PhianalysisTHnSparse { if (!selectedTrack(track2, false)) // both negative continue; - if (!selectedPair(mother, track1, track2)) + mother = calculateMother(track1, track2); + if (!seletectedMother(mother)) continue; if (static_cast(verbose.verboselevel) > 1) @@ -748,8 +796,8 @@ struct PhianalysisTHnSparse { mother.Pt(), getMultiplicity(collision), getCentrality(collision), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), collision.posZ(), @@ -849,12 +897,9 @@ struct PhianalysisTHnSparse { if (std::abs(mothertrack1.pdgCode()) != motherPDG) continue; - if (static_cast(verbose.verboselevel) > 1) { - LOGF(info, "True: %d, d1=%d (%ld), d2=%d (%ld), mother=%d (%ld)", n, mctrack1.pdgCode(), mctrack1.globalIndex(), mctrack2.pdgCode(), mctrack2.globalIndex(), mothertrack1.pdgCode(), mothertrack1.globalIndex()); - LOGF(info, "%d px: %f, py=%f, pz=%f, px: %f, py=%f, pz=%f", n, mctrack1.px(), mctrack1.py(), mctrack1.pz(), mctrack2.px(), mctrack2.py(), mctrack2.pz()); - } - - if (!selectedPair(mother, mctrack1, mctrack2)) + mother = calculateMother(track1, track2); + motherGen = calculateMother(mctrack1, mctrack2); + if (!seletectedMother(mother)) continue; if (n > 0) { @@ -863,12 +908,18 @@ struct PhianalysisTHnSparse { continue; } + if (static_cast(verbose.verboselevel) > 1) { + LOGF(info, "Collision: %ld True: %d, d1=%d (%ld), d2=%d (%ld), mother=%d (%ld)", collision.globalIndex(), n, mctrack1.pdgCode(), mctrack1.globalIndex(), mctrack2.pdgCode(), mctrack2.globalIndex(), mothertrack1.pdgCode(), mothertrack1.globalIndex()); + LOGF(info, "Track %d px: %f, py=%f, pz=%f, px: %f, py=%f, pz=%f", n, track1.px(), track1.py(), track1.pz(), track2.px(), track2.py(), track2.pz()); + LOGF(info, "mcTrack %d px: %f, py=%f, pz=%f, px: %f, py=%f, pz=%f", n, mctrack1.px(), mctrack1.py(), mctrack1.pz(), mctrack2.px(), mctrack2.py(), mctrack2.pz()); + } + pointPair = fillPointPair(mother.M(), mother.Pt(), getMultiplicity(collision), getCentrality(collision), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), collision.posZ(), @@ -881,12 +932,33 @@ struct PhianalysisTHnSparse { auto phiP = mothertrack1.p(); auto phiE = mothertrack1.e(); - auto phiMass = std::sqrt(phiE * phiE - phiP * phiP); + auto massGen = std::sqrt(phiE * phiE - phiP * phiP); + + registry.fill(HIST("Factors/h2ResolutionPtPhi"), mother.Pt(), (mother.Pt() - mothertrack1.pt())); + registry.fill(HIST("Factors/h2MassResolution"), mother.Pt(), (motherGen.M() - mother.M())); + registry.fill(HIST("Factors/h2MassShift"), mother.Pt(), (massGen - motherGen.M())); + registry.fill(HIST("Factors/h2MassShiftRel"), mother.Pt(), (massGen - motherGen.M()) / massGen); - registry.fill(HIST("Factors/h2ResolutionPtPhi"), mother.pt(), (mother.pt() - mothertrack1.pt())); - registry.fill(HIST("Factors/h2ResolutionMass"), mother.Pt(), (mother.M() - phiMass)); + if (static_cast(verbose.verboselevel) > 1) + LOGF(info, "mother.M()=%f, motherGen.M()=%f, massGen =%f", mother.M(), motherGen.M(), massGen); rsnOutput->fillUnliketrue(pointPair); + + pointPair = fillPointPair(motherGen.M(), + motherGen.Pt(), + getMultiplicity(collision), + getCentrality(collision), + tpcNsigma(track1), + tpcNsigma(track2), + motherGen.Eta(), + motherGen.Rapidity(), + collision.posZ(), + 0, + 0, + 0); + + rsnOutput->fillUnlikegenOld(pointPair); + n++; } } @@ -1007,15 +1079,16 @@ struct PhianalysisTHnSparse { if (!selectedTrack(track2, false)) // track2 is negative continue; - if (!selectedPair(mother, track1, track2)) + mother = calculateMother(track1, track2); + if (!seletectedMother(mother)) continue; pointPair = fillPointPair(mother.M(), mother.Pt(), getMultiplicity(c1), getCentrality(c1), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), c1.posZ(), @@ -1033,15 +1106,16 @@ struct PhianalysisTHnSparse { if (!selectedTrack(track2, false)) // track2 is negative continue; - if (!selectedPair(mother, track1, track2)) + mother = calculateMother(track1, track2); + if (!seletectedMother(mother)) continue; pointPair = fillPointPair(mother.M(), mother.Pt(), getMultiplicity(c1), getCentrality(c1), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), c1.posZ(), @@ -1077,15 +1151,16 @@ struct PhianalysisTHnSparse { if (!selectedTrack(track2, false)) // track2 is negative continue; - if (!selectedPair(mother, track1, track2)) + mother = calculateMother(track1, track2); + if (!seletectedMother(mother)) continue; pointPair = fillPointPair(mother.M(), mother.Pt(), getMultiplicity(c1), getCentrality(c1), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), c1.posZ(), @@ -1104,15 +1179,16 @@ struct PhianalysisTHnSparse { if (!selectedTrack(track2, false)) continue; - if (!selectedPair(mother, track1, track2)) + mother = calculateMother(track1, track2); + if (!seletectedMother(mother)) continue; pointPair = fillPointPair(mother.M(), mother.Pt(), getMultiplicity(c1), getCentrality(c1), - track1.tpcNSigmaKa(), - track2.tpcNSigmaKa(), + tpcNsigma(track1), + tpcNsigma(track2), mother.Eta(), mother.Rapidity(), c1.posZ(), diff --git a/PWGLF/Tasks/Strangeness/phiStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/phiStrangeCorrelation.cxx index a8c51642ec3..2524b6e55ea 100644 --- a/PWGLF/Tasks/Strangeness/phiStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/phiStrangeCorrelation.cxx @@ -18,6 +18,7 @@ #include "PWGLF/DataModel/mcCentrality.h" #include "PWGLF/Utils/inelGt.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TableHelper.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" @@ -282,7 +283,8 @@ struct PhiStrangenessCorrelation { Preslice collPerMCCollision = aod::mccollisionlabel::mcCollisionId; Preslice v0PerCollision = aod::v0::collisionId; Preslice trackPerCollision = aod::track::collisionId; - PresliceUnsorted phiCandPerCollision = aod::lf_selection_phi_candidate::collisionId; + // Preslice phiCandDataPerCollision = aod::lf_selection_phi_candidate::collisionId; + PresliceUnsorted phiCandPerCollision = aod::lf_selection_phi_candidate::collisionId; // Preslice mcPartPerMCCollision = aod::mcparticle::mcCollisionId; } preslices; @@ -316,8 +318,11 @@ struct PhiStrangenessCorrelation { histos.add("phi/h3PhiData", "Invariant mass of Phi in Data", kTH3F, {binnedmultAxis, binnedpTPhiAxis, massPhiAxis}); for (const auto& label : phiMassRegionLabels) { - histos.add(fmt::format("phiK0S/h5PhiK0SData2PartCorr{}", label).c_str(), "Deltay vs deltaphi for Phi and K0Short in Data", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTK0SAxis, deltayAxis, deltaphiAxis}); - histos.add(fmt::format("phiPi/h5PhiPiData2PartCorr{}", label).c_str(), "Deltay vs deltaphi for Phi and Pion in Data", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTPiAxis, deltayAxis, deltaphiAxis}); + histos.add(fmt::format("phiK0S/h5PhiK0SData{}", label).c_str(), "Deltay vs deltaphi for Phi and K0Short in Data", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTK0SAxis, deltayAxis, deltaphiAxis}); + histos.add(fmt::format("phiPi/h5PhiPiData{}", label).c_str(), "Deltay vs deltaphi for Phi and Pion in Data", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTPiAxis, deltayAxis, deltaphiAxis}); + + histos.add(fmt::format("phiK0S/h5PhiK0SDataME{}", label).c_str(), "Deltay vs deltaphi for Phi and K0Short in Data ME", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTK0SAxis, deltayAxis, deltaphiAxis}); + histos.add(fmt::format("phiPi/h5PhiPiDataME{}", label).c_str(), "Deltay vs deltaphi for Phi and Pion in Data ME", kTHnSparseF, {binnedmultAxis, binnedpTPhiAxis, binnedpTPiAxis, deltayAxis, deltaphiAxis}); } // histos.add("phiK0S/h5PhiK0SDataNewProc", "2D Invariant mass of Phi and K0Short in Data", kTHnSparseF, {deltayAxis, binnedmultAxis, binnedpTK0SAxis, massK0SAxis, massPhiAxis}); @@ -380,6 +385,11 @@ struct PhiStrangenessCorrelation { return totalEfficiency <= 0.0f ? 1.0f : 1.0f / totalEfficiency; } + float getDeltaPhi(float phiTrigger, float phiAssociated) + { + return RecoDecay::constrainAngle(phiTrigger - phiAssociated, -o2::constants::math::PIHalf); + } + // Single track selection for strangeness sector template bool selectionTrackStrangeness(const T& track) @@ -522,7 +532,7 @@ struct PhiStrangenessCorrelation { return true; } - void processPhiK0SPionDeltayDeltaphiData2D(SelCollisions::iterator const& collision, aod::PhimesonCandidatesData const& phiCandidates, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) + void processPhiK0SPionData(SelCollisions::iterator const& collision, aod::PhimesonCandidatesData const& phiCandidates, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) { float multiplicity = collision.centFT0M(); @@ -555,7 +565,7 @@ struct PhiStrangenessCorrelation { /*float weightPhiK0S = computeWeight(BoundEfficiencyMap(effMapPhi, multiplicity, phiCand.pt(), phiCand.y()), BoundEfficiencyMap(effMapK0S, multiplicity, v0.pt(), v0.yK0Short()));*/ - histos.fill(HIST("phiK0S/h5PhiK0SData2PartCorr") + HIST(phiMassRegionLabels[i]), multiplicity, phiCand.pt(), v0.pt(), phiCand.y() - v0.yK0Short(), phiCand.phi() - v0.phi(), weightPhiK0S); + histos.fill(HIST("phiK0S/h5PhiK0SData") + HIST(phiMassRegionLabels[i]), multiplicity, phiCand.pt(), v0.pt(), phiCand.y() - v0.yK0Short(), getDeltaPhi(phiCand.phi(), v0.phi()), weightPhiK0S); } // Loop over all primary pion candidates @@ -573,15 +583,62 @@ struct PhiStrangenessCorrelation { float weightPhiPion = computeWeight(BoundEfficiencyMap(effMapPhi, multiplicity, phiCand.pt(), phiCand.y()), BoundEfficiencyMap(effMapPion, multiplicity, track.pt(), track.rapidity(massPi)));*/ - histos.fill(HIST("phiPi/h5PhiPiData2PartCorr") + HIST(phiMassRegionLabels[i]), multiplicity, phiCand.pt(), track.pt(), phiCand.y() - track.rapidity(massPi), phiCand.phi() - track.phi(), weightPhiPion); + histos.fill(HIST("phiPi/h5PhiPiData") + HIST(phiMassRegionLabels[i]), multiplicity, phiCand.pt(), track.pt(), phiCand.y() - track.rapidity(massPi), getDeltaPhi(phiCand.phi(), track.phi()), weightPhiPion); + } + }); + } + } + + PROCESS_SWITCH(PhiStrangenessCorrelation, processPhiK0SPionData, "Process function for Phi-K0S and Phi-Pion Deltay and Deltaphi 2D Correlations in Data", true); + + /* + void processPhiK0SPionDataME(SelCollisions::iterator const& collision, aod::PhimesonCandidatesData const& phiCandidates, FullTracks const& fullTracks, FullV0s const& V0s, V0DauTracks const&) + { + Pair pairPhiK0S{binningOnVertexAndCent, cfgNoMixedEvents, -1, collisions, tracksV0sTuple, &cache}; + Triple triple{binningOnPositions, 5, -1, &cache}; + float multiplicity = collision.centFT0M(); + + const std::array, 2> phiMassRegions = {phiConfigs.rangeMPhiSignal, phiConfigs.rangeMPhiSideband}; + + // Loop over all positive tracks + for (const auto& phiCand : phiCandidates) { + static_for<0, phiMassRegionLabels.size() - 1>([&](auto i_idx) { + constexpr unsigned int i = i_idx.value; + + const auto& [minMass, maxMass] = phiMassRegions[i]; + if (!phiCand.inMassRegion(minMass, maxMass)) + return; + + // V0 already reconstructed by the builder + for (const auto& v0 : V0s) { + // Cut on V0 dynamic columns + if (!selectionV0(v0, collision)) + continue; + + float weightPhiK0S = computeWeight(BoundEfficiencyMap(effMaps[Phi], multiplicity, phiCand.pt(), phiCand.y()), + BoundEfficiencyMap(effMaps[K0S], multiplicity, v0.pt(), v0.yK0Short())); + + histos.fill(HIST("phiK0S/h5PhiK0SDataME") + HIST(phiMassRegionLabels[i]), multiplicity, phiCand.pt(), v0.pt(), phiCand.y() - v0.yK0Short(), getDeltaPhi(phiCand.phi(), v0.phi()), weightPhiK0S); + } + + // Loop over all primary pion candidates + for (const auto& track : fullTracks) { + if (!selectionPion(track)) + continue; + + float weightPhiPion = computeWeight(BoundEfficiencyMap(effMaps[Phi], multiplicity, phiCand.pt(), phiCand.y()), + BoundEfficiencyMap(effMaps[Pion], multiplicity, track.pt(), track.rapidity(massPi))); + + histos.fill(HIST("phiPi/h5PhiPiDataME") + HIST(phiMassRegionLabels[i]), multiplicity, phiCand.pt(), track.pt(), phiCand.y() - track.rapidity(massPi), getDeltaPhi(phiCand.phi(), track.phi()), weightPhiPion); } }); } } - PROCESS_SWITCH(PhiStrangenessCorrelation, processPhiK0SPionDeltayDeltaphiData2D, "Process function for Phi-K0S and Phi-Pion Deltay and Deltaphi 2D Correlations in Data", true); + PROCESS_SWITCH(PhiStrangenessCorrelation, processPhiK0SPionDataME, "Process function for Phi-K0S and Phi-Pion Deltay and Deltaphi 2D Correlations in Data ME", true); + */ - void processParticleEfficiency(MCCollisions::iterator const& mcCollision, SimCollisions const& collisions, FullMCTracks const& fullMCTracks, FullMCV0s const& V0s, V0DauMCTracks const&, aod::McParticles const& mcParticles, aod::PhimesonCandidatesData const& phiCandidates) + void processParticleEfficiency(MCCollisions::iterator const& mcCollision, SimCollisions const& collisions, FullMCTracks const& fullMCTracks, FullMCV0s const& V0s, V0DauMCTracks const&, aod::McParticles const& mcParticles, aod::PhimesonCandidatesMcReco const& phiCandidatesMcReco) { uint16_t numberAssocColls{0}; std::vector zVtxs; @@ -595,7 +652,7 @@ struct PhiStrangenessCorrelation { zVtxs.push_back(collision.posZ()); if (selectionType == 0) { - const auto phiCandidatesThisColl = phiCandidates.sliceBy(preslices.phiCandPerCollision, collision.globalIndex()); + const auto phiCandidatesThisColl = phiCandidatesMcReco.sliceBy(preslices.phiCandPerCollision, collision.globalIndex()); for (const auto& phiCand : phiCandidatesThisColl) { histos.fill(HIST("phi/h4PhiMCReco"), collision.posZ(), mcCollision.centFT0M(), phiCand.pt(), phiCand.y()); } diff --git a/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx b/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx index 64855058bcb..458c51bab5e 100644 --- a/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx +++ b/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx @@ -487,8 +487,8 @@ struct V0PtInvMassPlots { // Cut Plots rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlotK0sh"), v0.alpha(), v0.qtarm()); - //rPtAnalysis.fill(HIST("hNSigmaPosPionFromK0s"), posDaughterTrack.tpcNSigmaPi(), posDaughterTrack.tpcInnerParam()); - //rPtAnalysis.fill(HIST("hNSigmaNegPionFromK0s"), negDaughterTrack.tpcNSigmaPi(), negDaughterTrack.tpcInnerParam()); + // rPtAnalysis.fill(HIST("hNSigmaPosPionFromK0s"), posDaughterTrack.tpcNSigmaPi(), posDaughterTrack.tpcInnerParam()); + // rPtAnalysis.fill(HIST("hNSigmaNegPionFromK0s"), negDaughterTrack.tpcNSigmaPi(), negDaughterTrack.tpcInnerParam()); rPtAnalysis.fill(HIST("hK0shcosPA"), v0.v0cosPA()); rPtAnalysis.fill(HIST("hK0shV0radius"), v0.v0radius()); rPtAnalysis.fill(HIST("hK0shDCAV0Daughters"), v0.dcaV0daughters()); @@ -569,8 +569,8 @@ struct V0PtInvMassPlots { // Cut Plots rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlotLambda"), v0.alpha(), v0.qtarm()); - //rPtAnalysis.fill(HIST("hNSigmaPosProtonFromLambdas"), posDaughterTrack.tpcNSigmaPr(), posDaughterTrack.tpcInnerParam()); - //rPtAnalysis.fill(HIST("hNSigmaNegPionFromLambdas"), negDaughterTrack.tpcNSigmaPi(), negDaughterTrack.tpcInnerParam()); + // rPtAnalysis.fill(HIST("hNSigmaPosProtonFromLambdas"), posDaughterTrack.tpcNSigmaPr(), posDaughterTrack.tpcInnerParam()); + // rPtAnalysis.fill(HIST("hNSigmaNegPionFromLambdas"), negDaughterTrack.tpcNSigmaPi(), negDaughterTrack.tpcInnerParam()); rPtAnalysis.fill(HIST("hLambdacosPA"), v0.v0cosPA()); rPtAnalysis.fill(HIST("hLambdaV0radius"), v0.v0radius()); rPtAnalysis.fill(HIST("hLambdaDCAV0Daughters"), v0.dcaV0daughters()); @@ -651,8 +651,8 @@ struct V0PtInvMassPlots { // Cut plots rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlotAntilambda"), v0.alpha(), v0.qtarm()); - //rPtAnalysis.fill(HIST("hNSigmaPosPionFromAntilambdas"), posDaughterTrack.tpcNSigmaPr(), posDaughterTrack.tpcInnerParam()); - //rPtAnalysis.fill(HIST("hNSigmaNegProtonFromAntilambdas"), negDaughterTrack.tpcNSigmaPi(), negDaughterTrack.tpcInnerParam()); + // rPtAnalysis.fill(HIST("hNSigmaPosPionFromAntilambdas"), posDaughterTrack.tpcNSigmaPr(), posDaughterTrack.tpcInnerParam()); + // rPtAnalysis.fill(HIST("hNSigmaNegProtonFromAntilambdas"), negDaughterTrack.tpcNSigmaPi(), negDaughterTrack.tpcInnerParam()); rPtAnalysis.fill(HIST("hAntilambdacosPA"), v0.v0cosPA()); rPtAnalysis.fill(HIST("hAntilambdaV0radius"), v0.v0radius()); rPtAnalysis.fill(HIST("hAntilambdaDCAV0Daughters"), v0.dcaV0daughters()); @@ -1020,7 +1020,7 @@ struct V0PtInvMassPlots { } } } - // This is the process for Real Derived Data + // This is the process for Real Derived Data void dataProcessDerived(soa::Join::iterator const& collision, soa::Join const& V0s, DaughterTracksDerived const&) @@ -1255,4 +1255,5 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ adaptAnalysisTask(cfgc)}; -} \ No newline at end of file +} + \ No newline at end of file diff --git a/PWGMM/Lumi/Tasks/lumiStabilityPP.cxx b/PWGMM/Lumi/Tasks/lumiStabilityPP.cxx index d1426c6c162..37ca264a34e 100644 --- a/PWGMM/Lumi/Tasks/lumiStabilityPP.cxx +++ b/PWGMM/Lumi/Tasks/lumiStabilityPP.cxx @@ -127,6 +127,7 @@ struct LumiStabilityPP { std::map> histBcHasFT0; std::map> histBcHasFDD; std::map> histFillingScheme; + std::map> histFillTime; static constexpr std::string_view NBCsVsTimeHistNames[NTriggerAliases][NBCCategories] = {{"AllBCs/BC_A/nBCsVsTime", "AllBCs/BC_B/nBCsVsTime", "AllBCs/BC_C/nBCsVsTime", "AllBCs/BC_E/nBCsVsTime", "AllBCs/BC_L/nBCsVsTime", "AllBCs/BC_SL/nBCsVsTime"}, @@ -158,6 +159,7 @@ struct LumiStabilityPP { histNBcsVsBcId[runNumber] = registry.add(Form("%d/nBCsVsBCID", runNumber), "Time of TVX triggered BCs since the start of fill;#bf{t-t_{SOF} (min)};#bf{#it{N}_{BC}}", HistType::kTH1D, {bcIDAxis}); histTfPerMin[runNumber] = registry.add(Form("%d/TFsPerMinute", runNumber), "TFs seen in this minute (to account for failed jobs);#bf{t-t_{SOF} (min)};#bf{#it{N}_{TFs}}", HistType::kTH1D, {timeAxis}); histFillingScheme[runNumber] = registry.add(Form("%d/FillingScheme", runNumber), "Filling Scheme;Filling Scheme;", HistType::kTH1D, {{1, 0, 1}}); + histFillTime[runNumber] = registry.add(Form("%d/FillTime", runNumber), "Fill time;Fill time;", HistType::kTH1D, {{1, 0, 1}}); histBcHasFT0[runNumber] = registry.add(Form("%d/FITQA/BCHasFT0", runNumber), "Does the BC have FT0?;BC has FT0;TVX triggered according to CTP;#bf{#it{N}_{BC}}", HistType::kTH2D, {{2, -0.5, 1.5}, {2, -0.5, 1.5}}); histBcHasFT0[runNumber]->GetYaxis()->SetBinLabel(1, "No CTP trigger"); @@ -200,6 +202,7 @@ struct LumiStabilityPP { createHistograms(); histFillingScheme[runNumber]->Fill(mLHCIFdata->getInjectionScheme().c_str(), 0); + histFillTime[runNumber]->Fill(0.5, mLHCIFdata->getFillNumberTime()); beamPatternA = mLHCIFdata->getBunchFilling().getBeamPattern(0); beamPatternC = mLHCIFdata->getBunchFilling().getBeamPattern(1); @@ -302,8 +305,8 @@ struct LumiStabilityPP { histBcHasFDD[runNumber]->Fill(bc.has_fdd(), ctpInputMask.test(15)); for (int iTrigger{0}; iTrigger < NTriggerAliases; ++iTrigger) { - for (int iBCCategory{0}; iBCCategory < NBCCategories; ++iBCCategory) { // Don't do SL BCs here - if ((iBCCategory == BCA && doBCA) || (iBCCategory == BCB && doBCB) || (iBCCategory == BCC && doBCC) || (iBCCategory == BCE && doBCE) || (iBCCategory == BCL && doBCL)) { + for (int iBCCategory{0}; iBCCategory < NBCCategories; ++iBCCategory) { + if ((iBCCategory == BCA && doBCA) || (iBCCategory == BCB && doBCB) || (iBCCategory == BCC && doBCC) || (iBCCategory == BCE && doBCE) || (iBCCategory == BCL && doBCL) || (iBCCategory == BCSL && doBCSL)) { if (iTrigger == AllBCs) { if (iBCCategory == BCA && bcPatternA[localBC]) fillHistograms(timeSinceSOF, localBC); @@ -343,6 +346,8 @@ struct LumiStabilityPP { fillHistograms(timeSinceSOF, localBC); if (iBCCategory == BCL && bcPatternL[localBC]) fillHistograms(timeSinceSOF, localBC); + if (iBCCategory == BCSL && isSuperLeadingBc) + fillHistograms(timeSinceSOF, localBC); } if (iTrigger == FDD && ctpInputMask.test(15)) { if (iBCCategory == BCA && bcPatternA[localBC]) diff --git a/PWGMM/UE/Tasks/dedx_analysys.cxx b/PWGMM/UE/Tasks/dedx_analysys.cxx deleted file mode 100644 index 3a4bb9a2843..00000000000 --- a/PWGMM/UE/Tasks/dedx_analysys.cxx +++ /dev/null @@ -1,569 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// 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. -/// -/// \author Paola Vargas -/// \since January 8, 2025 - -#include "PWGLF/DataModel/LFStrangenessTables.h" - -#include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -using namespace o2; -using namespace o2::framework; - -using PIDTracks = soa::Join< - aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::pidTOFbeta, - aod::pidTOFmass, aod::TrackSelection, aod::TrackSelectionExtension, - aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTPCFullDe, - aod::pidTPCFullTr, aod::pidTPCFullHe, aod::pidTOFFullPi, aod::pidTOFFullKa, - aod::pidTOFFullPr, aod::pidTOFFullDe, aod::pidTOFFullTr, aod::pidTOFFullHe, aod::pidTOFFullEl>; - -using SelectedCollisions = soa::Join; - -struct dedx_analysys { - - // dE/dx for all charged particles - HistogramRegistry registryDeDx{ - "registryDeDx", - {}, - OutputObjHandlingPolicy::AnalysisObject, - true, - true}; - - // Corrections - // constexpr double Correc[8]{54.3344, 55.1277, 56.0811, 56.7974, 56.9533, 56.4622, 55.8873, 55.1449}; - // constexpr double Correc[9]{-0.8, -0.6, -0.4, -0.2, 0., 0.2, 0.4, 0.6, 0.8}; - - // Configurable Parameters - Configurable minTPCnClsFound{"minTPCnClsFound", 70.0f, - "min number of found TPC clusters"}; - Configurable minNCrossedRowsTPC{ - "minNCrossedRowsTPC", 70.0f, "min number of found TPC crossed rows"}; - Configurable minNClsTPCdEdx{ - "minNClsTPCdEdx", 50.0f, "min number of TPC clusters for PID"}; - Configurable maxChi2TPC{"maxChi2TPC", 4.0f, - "max chi2 per cluster TPC"}; - Configurable maxChi2ITS{"maxChi2ITS", 36.0f, - "max chi2 per cluster ITS"}; - Configurable etaMin{"etaMin", -0.8f, "etaMin"}; - Configurable etaMax{"etaMax", +0.8f, "etaMax"}; - Configurable v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"}; - Configurable minimumV0Radius{"minimumV0Radius", 0.5f, - "Minimum V0 Radius"}; - Configurable maximumV0Radius{"maximumV0Radius", 100.0f, - "Maximum V0 Radius"}; - Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, - "Maximum DCA Daughters"}; - Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; - Configurable minMassK0s{"minMassK0s", 0.4f, "Minimum Mass K0s"}; - Configurable maxMassK0s{"maxMassK0s", 0.6f, "Maximum Mass K0s"}; - Configurable minMassLambda{"minMassLambda", 1.1f, - "Minimum Mass Lambda"}; - Configurable maxMassLambda{"maxMassLambda", 1.2f, - "Maximum Mass Lambda"}; - Configurable minMassGamma{"minMassGamma", 0.000922f, - "Minimum Mass Gamma"}; - Configurable maxMassGamma{"maxMassGamma", 0.002022f, - "Maximum Mass Gamma"}; - Configurable minReqClusterITS{ - "minReqClusterITS", 4.0f, "min number of clusters required in ITS"}; - Configurable maxDCAxy{"maxDCAxy", 0.1f, "maxDCAxy"}; - Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; - Configurable eventSelection{"eventSelection", true, "event selection"}; - // Histograms names - static constexpr std::string_view Armenteros[5] = {"Armenteros", "Armenteros_K0S", "Armenteros_Lambda", "Armenteros_AntiLambda", "Armenteros_Gamma"}; - static constexpr std::string_view Qt_vs_alpha[5] = {"Qt_vs_alpha", "Qt_vs_alpha_K0S", "Qt_vs_alpha_Lambda", "Qt_vs_alpha_AntiLambda", "Qt_vs_alpha_Gamma"}; - static constexpr std::string_view dEdx_vs_Momentum[5] = {"dEdx_vs_Momentum_all", "dEdx_vs_Momentum_02", "dEdx_vs_Momentum_0204", "dEdx_vs_Momentum_0406", "dEdx_vs_Momentum_0608"}; - static constexpr std::string_view dEdx_vs_Momentum_neg[4] = {"dEdx_vs_Momentum_02neg", "dEdx_vs_Momentum_0204neg", "dEdx_vs_Momentum_0406neg", "dEdx_vs_Momentum_0608neg"}; - static constexpr std::string_view dEdx_vs_Momentum_pos[4] = {"dEdx_vs_Momentum_02pos", "dEdx_vs_Momentum_0204pos", "dEdx_vs_Momentum_0406pos", "dEdx_vs_Momentum_0608pos"}; - static constexpr std::string_view dEdx_vs_Momentum_v0[3] = {"dEdx_vs_Momentum_Pi_v0", "dEdx_vs_Momentum_Pr_v0", "dEdx_vs_Momentum_El_v0"}; - static constexpr std::string_view hInvMass[4] = {"InvMass_K0S", "InvMass_Lambda", "InvMass_AntiLambda", "InvMass_Gamma"}; - static constexpr double EtaCut[9] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; - static constexpr double Correction[8] = {54.3344, 55.1277, 56.0811, 56.7974, 56.9533, 56.4622, 55.8873, 55.1449}; - - void init(InitContext const&) - { - - // MIP for pions - registryDeDx.add( - "dEdxMIP_vs_eta", "dE/dx", HistType::kTH2F, - {{100, -0.8, 0.8, "#eta"}, {100, 0.0, 600.0, "dE/dx MIP (a. u.)"}}); - - registryDeDx.add( - "dEdxMIP_vs_phi", "dE/dx", HistType::kTH2F, - {{100, 0.0, 6.4, "#phi"}, {100, 0.0, 600.0, "dE/dx MIP (a. u.)"}}); - - registryDeDx.add( - "dEdxMIP_vs_eta_AfterCorr", "dE/dx", HistType::kTH2F, - {{100, -0.8, 0.8, "#eta"}, {100, 0.0, 600.0, "dE/dx MIP (a. u.)"}}); - - //////////////////////////////// - registryDeDx.add(hInvMass[0].data(), "mass", HistType::kTH1F, - {{100, 400, 600, "m (MeV/c)"}}); - registryDeDx.add(hInvMass[1].data(), "mass", HistType::kTH1F, - {{100, 1.08, 1.25, "m (GeV/c)"}}); - registryDeDx.add(hInvMass[2].data(), "mass", HistType::kTH1F, - {{100, 1.08, 1.25, "m (GeV/c)"}}); - registryDeDx.add(hInvMass[3].data(), "mass", HistType::kTH1F, - {{100, 0, 2, "m (MeV/c)"}}); - // Armenteros plot and De/Dx for eta cut inclusive - for (int i = 0; i < 5; ++i) { - registryDeDx.add(Armenteros[i].data(), Qt_vs_alpha[i].data(), HistType::kTH2F, - {{100, -1., 1., "#alpha (a. u.)"}, {100, 0.0, 0.3, "q_T (GeV/c)"}}); - registryDeDx.add(dEdx_vs_Momentum[i].data(), "dE/dx", HistType::kTH2F, - {{100, -20.0, 20.0, "#it{p}/Z (GeV/c)"}, {100, 0.0, 600.0, "dE/dx (a. u.)"}}); - } - // De/Dx for eta cut negative and positive - for (int i = 0; i < 4; ++i) { - - registryDeDx.add(dEdx_vs_Momentum_neg[i].data(), "dE/dx", HistType::kTH2F, - {{100, -20.0, 20.0, "#it{p}/Z (GeV/c)"}, {100, 0.0, 600.0, "dE/dx (a. u.)"}}); - - registryDeDx.add(dEdx_vs_Momentum_pos[i].data(), "dE/dx", HistType::kTH2F, - {{100, -20.0, 20.0, "#it{p}/Z (GeV/c)"}, {100, 0.0, 600.0, "dE/dx (a. u.)"}}); - } - - // De/Dx for v0 particles - for (int i = 0; i < 3; ++i) { - - registryDeDx.add(dEdx_vs_Momentum_v0[i].data(), "dE/dx", HistType::kTH2F, - {{100, -20.0, 20.0, "#it{p}/Z (GeV/c)"}, {100, 0.0, 600.0, "dE/dx (a. u.)"}}); - } - - // Event Counter - registryDeDx.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{100, -20.0, +20.0, "z_{vtx} (cm)"}}); - } - - // Single-Track Selection - template - bool passedSingleTrackSelection(const T1& track, const C& /*collision*/) - { - // Single-Track Selections - if (!track.hasTPC()) - return false; - if (track.tpcNClsFound() < minTPCnClsFound) - return false; - if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) - return false; - if (track.tpcChi2NCl() > maxChi2TPC) - return false; - if (track.eta() < etaMin || track.eta() > etaMax) - return false; - - return true; - } - - // General V0 Selections - template - bool passedV0Selection(const T1& v0, const C& /*collision*/) - { - if (v0.v0cosPA() < v0cospaMin) - return false; - if (v0.v0radius() < minimumV0Radius || v0.v0radius() > maximumV0Radius) - return false; - - return true; - } - - // K0s Selections - template - bool passedK0Selection(const T1& v0, const T2& ntrack, const T2& ptrack, - const C& collision) - { - // Single-Track Selections - if (!passedSingleTrackSelection(ptrack, collision)) - return false; - if (!passedSingleTrackSelection(ntrack, collision)) - return false; - - if (ptrack.tpcInnerParam() > 0.6) { - if (!ptrack.hasTOF()) - return false; - if (TMath::Abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) - return false; - } - - if (ntrack.tpcInnerParam() > 0.6) { - if (!ntrack.hasTOF()) - return false; - if (TMath::Abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) - return false; - } - - // Invariant-Mass Selection - if (v0.mK0Short() < minMassK0s || v0.mK0Short() > maxMassK0s) - return false; - - return true; - } - - // Lambda Selections - template - bool passedLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, - const C& collision) - { - // Single-Track Selections - if (!passedSingleTrackSelection(ptrack, collision)) - return false; - if (!passedSingleTrackSelection(ntrack, collision)) - return false; - - if (ptrack.tpcInnerParam() > 0.6) { - if (!ptrack.hasTOF()) - return false; - if (TMath::Abs(ptrack.tofNSigmaPr()) > nsigmaTOFmax) - return false; - } - - if (ntrack.tpcInnerParam() > 0.6) { - if (!ntrack.hasTOF()) - return false; - if (TMath::Abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) - return false; - } - - // Invariant-Mass Selection - if (v0.mLambda() < minMassLambda || v0.mLambda() > maxMassLambda) - return false; - - return true; - } - - // AntiLambda Selections - template - bool passedAntiLambdaSelection(const T1& v0, const T2& ntrack, - const T2& ptrack, const C& collision) - { - - // Single-Track Selections - if (!passedSingleTrackSelection(ptrack, collision)) - return false; - if (!passedSingleTrackSelection(ntrack, collision)) - return false; - - if (ptrack.tpcInnerParam() > 0.6) { - if (!ptrack.hasTOF()) - return false; - if (TMath::Abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) - return false; - } - - if (ntrack.tpcInnerParam() > 0.6) { - if (!ntrack.hasTOF()) - return false; - if (TMath::Abs(ntrack.tofNSigmaPr()) > nsigmaTOFmax) - return false; - } - - // Invariant-Mass Selection - if (v0.mAntiLambda() < minMassLambda || v0.mAntiLambda() > maxMassLambda) - return false; - - return true; - } - - // Gamma Selections - template - bool passedGammaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, - const C& collision) - { - // Single-Track Selections - if (!passedSingleTrackSelection(ptrack, collision)) - return false; - if (!passedSingleTrackSelection(ntrack, collision)) - return false; - - if (ptrack.tpcInnerParam() > 0.6) { - if (!ptrack.hasTOF()) - return false; - if (TMath::Abs(ptrack.tofNSigmaEl()) > nsigmaTOFmax) - return false; - } - - if (ntrack.tpcInnerParam() > 0.6) { - if (!ntrack.hasTOF()) - return false; - if (TMath::Abs(ntrack.tofNSigmaEl()) > nsigmaTOFmax) - return false; - } - - // Invariant-Mass Selection - if (v0.mGamma() < minMassGamma || v0.mGamma() > maxMassGamma) - return false; - - return true; - } - - // Process Data - void process(SelectedCollisions::iterator const& collision, - aod::V0Datas const& fullV0s, PIDTracks const& tracks) - { - // Event Selection - if (!collision.sel8()) - return; - - // Event Counter - registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); - - // Centrality - float centrality = collision.centFT0C(); - if (centrality < 0.0 || centrality > 100.0) - centrality = 1.0; - - // Kaons - for (auto& trk : tracks) { - - if (!passedSingleTrackSelection(trk, collision)) - continue; - if (!trk.passedTPCRefit()) - continue; - float signedP = trk.sign() * trk.tpcInnerParam(); - - // DeDx all particles - registryDeDx.fill(HIST(dEdx_vs_Momentum[0]), signedP, trk.tpcSignal()); - - //////////////////////////////// - - // MIP for pions - - // TODO: 0.25 TO 0.35 - // range 0.2 to 0.6 - // float pion_m = 0.139; //GeV - if (trk.tpcInnerParam() >= 0.25 && trk.tpcInnerParam() <= 0.35) { - registryDeDx.fill(HIST("dEdxMIP_vs_eta"), trk.eta(), trk.tpcSignal()); - registryDeDx.fill(HIST("dEdxMIP_vs_phi"), trk.phi(), trk.tpcSignal()); - // After calibration - - for (int i = 0; i < 8; ++i) { - if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST("dEdxMIP_vs_eta_AfterCorr"), trk.eta(), trk.tpcSignal() * 50 / Correction[i]); - } - } - } - - // After calibration - for (int i = 0; i < 8; ++i) { - if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { - if (i == 0) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_neg[0]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[4]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } else if (i == 1) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_neg[1]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[3]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } else if (i == 2) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_neg[2]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[2]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } else if (i == 3) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_neg[3]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[1]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } else if (i == 4) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_pos[0]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[1]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } else if (i == 5) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_pos[1]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[2]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } else if (i == 6) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_pos[2]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[3]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } else if (i == 7) { - registryDeDx.fill(HIST(dEdx_vs_Momentum_pos[3]), signedP, trk.tpcSignal() * 50 / Correction[i]); - registryDeDx.fill(HIST(dEdx_vs_Momentum[4]), signedP, trk.tpcSignal() * 50 / Correction[i]); - } - } - } - } - - // Loop over Reconstructed V0s - for (auto& v0 : fullV0s) { - - // Standard V0 Selections - if (!passedV0Selection(v0, collision)) { - continue; - } - - if (v0.dcaV0daughters() > dcaV0DaughtersMax) { - continue; - } - - // Positive and Negative Tracks - const auto& posTrack = v0.posTrack_as(); - const auto& negTrack = v0.negTrack_as(); - - if (!posTrack.passedTPCRefit()) - continue; - if (!negTrack.passedTPCRefit()) - continue; - - float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); - float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); - - float px_v0 = v0.px(); - float py_v0 = v0.py(); - float pz_v0 = v0.pz(); - float p_v0 = sqrt(px_v0 * px_v0 + py_v0 * py_v0 + pz_v0 * pz_v0); - - float px_pos = posTrack.px(); - float py_pos = posTrack.py(); - float pz_pos = posTrack.pz(); - - float px_neg = negTrack.px(); - float py_neg = negTrack.py(); - float pz_neg = negTrack.pz(); - - const float protonMass = 0.938; // GeV/c^2 - const float piMass = 0.13957; // GeV/c^2 - const float K0SMass = 493.677; // MeV/c^2 - const float LambdaMass = 1.115; // GeV/c^2 - const float GammaMass = 1.022; // MeV/c^2 - const float eMass = 0.511; // MeV/c^2 - - // float E_pos_man = std::sqrt(px_pos * px_pos + py_pos * py_pos + pz_pos * pz_pos + piMass * piMass); - - //-------------------Armenteros plots-------- - - float pl_pos = (px_pos * px_v0 + py_pos * py_v0 + pz_pos * pz_v0) / p_v0; - float pl_neg = (px_neg * px_v0 + py_neg * py_v0 + pz_neg * pz_v0) / p_v0; - - float alpha = (pl_pos - pl_neg) / (pl_pos + pl_neg); - float p_pos = sqrt(px_pos * px_pos + py_pos * py_pos + pz_pos * pz_pos); - float qt = sqrt(p_pos * p_pos - pl_pos * pl_pos); - - registryDeDx.fill(HIST(Armenteros[0]), alpha, qt); - - //------------------------------------------- - - // K0s Selection - if (passedK0Selection(v0, negTrack, posTrack, collision)) { - float E_pos_pi = posTrack.energy(piMass); - float E_neg_pi = negTrack.energy(piMass); - - float InvMass = sqrt((E_neg_pi + E_pos_pi) * (E_neg_pi + E_pos_pi) - ((px_neg + px_pos) * (px_neg + px_pos) + (py_neg + py_pos) * (py_neg + py_pos) + (pz_neg + pz_pos) * (pz_neg + pz_pos))); - - if (TMath::Abs(InvMass * 1000 - K0SMass) > 10) { - continue; - } - - registryDeDx.fill(HIST(hInvMass[0]), InvMass * 1000); - registryDeDx.fill(HIST(Armenteros[1]), alpha, qt); - - for (int i = 0; i < 8; ++i) { - if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[0]), signedPneg, negTrack.tpcSignal() * 50 / Correction[i]); - } - if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[0]), signedPpos, posTrack.tpcSignal() * 50 / Correction[i]); - } - } - } - - // Lambda Selection - if (passedLambdaSelection(v0, negTrack, posTrack, collision)) { - float E_pos_p = posTrack.energy(protonMass); - float E_neg_pi = negTrack.energy(piMass); - - float InvMass = sqrt((E_neg_pi + E_pos_p) * (E_neg_pi + E_pos_p) - ((px_neg + px_pos) * (px_neg + px_pos) + (py_neg + py_pos) * (py_neg + py_pos) + (pz_neg + pz_pos) * (pz_neg + pz_pos))); - - if (TMath::Abs(InvMass - LambdaMass) > 0.01) { - continue; - } - - registryDeDx.fill(HIST(hInvMass[1]), InvMass); - registryDeDx.fill(HIST(Armenteros[2]), alpha, qt); - - for (int i = 0; i < 8; ++i) { - if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[0]), signedPneg, negTrack.tpcSignal() * 50 / Correction[i]); - } - if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[1]), signedPpos, posTrack.tpcSignal() * 50 / Correction[i]); - } - } - } - - // AntiLambda Selection - if (passedAntiLambdaSelection(v0, negTrack, posTrack, collision)) { - - float E_pos_pi = posTrack.energy(piMass); - float E_neg_p = negTrack.energy(protonMass); - - float InvMass = sqrt((E_neg_p + E_pos_pi) * (E_neg_p + E_pos_pi) - ((px_neg + px_pos) * (px_neg + px_pos) + (py_neg + py_pos) * (py_neg + py_pos) + (pz_neg + pz_pos) * (pz_neg + pz_pos))); - - if (TMath::Abs(InvMass - LambdaMass) > 0.01) { - continue; - } - - registryDeDx.fill(HIST(hInvMass[2]), InvMass); - registryDeDx.fill(HIST(Armenteros[3]), alpha, qt); - - for (int i = 0; i < 8; ++i) { - if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[1]), signedPneg, negTrack.tpcSignal() * 50 / Correction[i]); - } - if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[0]), signedPpos, posTrack.tpcSignal() * 50 / Correction[i]); - } - } - } - - // Gamma Selection - if (passedGammaSelection(v0, negTrack, posTrack, collision)) { - - float E_pos_e = posTrack.energy(eMass); - float E_neg_e = negTrack.energy(eMass); - - float InvMass = sqrt((E_neg_e + E_pos_e) * (E_neg_e + E_pos_e) - ((px_neg + px_pos) * (px_neg + px_pos) + (py_neg + py_pos) * (py_neg + py_pos) + (pz_neg + pz_pos) * (pz_neg + pz_pos))); - - if (TMath::Abs(InvMass - GammaMass) > 10) { - continue; - } - - registryDeDx.fill(HIST(hInvMass[3]), InvMass); - registryDeDx.fill(HIST(Armenteros[4]), alpha, qt); - - for (int i = 0; i < 8; ++i) { - if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[2]), signedPneg, negTrack.tpcSignal() * 50 / Correction[i]); - } - if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - - registryDeDx.fill(HIST(dEdx_vs_Momentum_v0[2]), signedPpos, posTrack.tpcSignal() * 50 / Correction[i]); - } - } - } - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -}