diff --git a/PWGJE/Tasks/trackEfficiency.cxx b/PWGJE/Tasks/trackEfficiency.cxx index 970833dfe88..5ca8c4816d4 100644 --- a/PWGJE/Tasks/trackEfficiency.cxx +++ b/PWGJE/Tasks/trackEfficiency.cxx @@ -55,7 +55,8 @@ struct TrackEfficiency { // Tracking efficiency process function configurables: Configurable checkPrimaryPart{"checkPrimaryPart", true, "0: doesn't check mcparticle.isPhysicalPrimary() - 1: checks particle.isPhysicalPrimary()"}; - Configurable checkCentrality{"checkCentrality", false, ""}; + Configurable cutCentrality{"cutCentrality", false, ""}; + Configurable checkCentFT0M{"checkCentFT0M", false, "0: centFT0C as default, 1: use centFT0M estimator"}; Configurable checkOccupancy{"checkOccupancy", false, "check occupancy only in general purpose Pb-Pb MC, default as false"}; Configurable acceptSplitCollisions{"acceptSplitCollisions", 0, "0: only look at mcCollisions that are not split; 1: accept split mcCollisions, 2: accept split mcCollisions but only look at the first reco collision associated with it"}; Configurable trackEtaAcceptanceCountQA{"trackEtaAcceptanceCountQA", 0.9, "eta acceptance"}; // removed from actual cuts for now because all the histograms have an eta axis @@ -73,7 +74,7 @@ struct TrackEfficiency { Configurable trackOccupancyInTimeRangeMax{"trackOccupancyInTimeRangeMax", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range; only applied for reconstructed tracks, not mc particles"}; Configurable trackOccupancyInTimeRangeMin{"trackOccupancyInTimeRangeMin", -999999, "minimum occupancy of tracks in neighbouring collisions in a given time range; only applied for reconstructed tracks, not mc particles"}; - Configurable> centralityBinning{"centralityBinning", {0., 10., 50., 70.}, "binning of centrality histograms"}; + Configurable> centralityBinning{"centralityBinning", {0., 10., 50., 70., 100}, "binning of centrality histograms"}; Configurable intRateNBins{"intRateNBins", 50, "number of bins for interaction rate axis"}; Configurable intRateMax{"intRateMax", 50000.0, "maximum value of interaction rate axis"}; Configurable phiEffNBins{"phiEffNBins", 200, "number of bins for phi axis in efficiency plots"}; @@ -100,6 +101,7 @@ struct TrackEfficiency { std::vector eventSelectionBits; int trackSelection = -1; + float simPtRef = 10.; enum AcceptSplitCollisionsOptions { NonSplitOnly = 0, @@ -115,7 +117,7 @@ struct TrackEfficiency { return true; } } else { - const auto& aodTrack = jetTrack.template track_as>(); // might need the aodTracks to have the TracksExtra table as well; should check; check what is needed for the track selection + const auto& aodTrack = jetTrack.template track_as>(); if (customTrackSelection.IsSelected(aodTrack)) { return true; } @@ -142,33 +144,37 @@ struct TrackEfficiency { continue; } - float simPtRef = 10.; float pTHat = simPtRef / (std::pow(weight, 1.0 / pTHatExponent)); if (track.pt() > pTHatMaxFractionMCD * pTHat) { continue; } - registry.fill(HIST("h2_centrality_track_pt"), collision.centFT0M(), track.pt(), weight); - registry.fill(HIST("h2_centrality_track_eta"), collision.centFT0M(), track.eta(), weight); - registry.fill(HIST("h2_centrality_track_phi"), collision.centFT0M(), track.phi(), weight); - registry.fill(HIST("h2_centrality_track_energy"), collision.centFT0M(), track.energy(), weight); + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + + registry.fill(HIST("h2_centrality_track_pt"), centrality, track.pt(), weight); + registry.fill(HIST("h2_centrality_track_eta"), centrality, track.eta(), weight); + registry.fill(HIST("h2_centrality_track_phi"), centrality, track.phi(), weight); + registry.fill(HIST("h2_centrality_track_energy"), centrality, track.energy(), weight); registry.fill(HIST("h2_track_pt_track_sigma1overpt"), track.pt(), track.sigma1Pt(), weight); registry.fill(HIST("h2_track_pt_track_sigmapt"), track.pt(), track.sigma1Pt() * track.pt(), weight); registry.fill(HIST("h2_track_pt_high_track_sigma1overpt"), track.pt(), track.sigma1Pt(), weight); registry.fill(HIST("h2_track_pt_high_track_sigmapt"), track.pt(), track.sigma1Pt() * track.pt(), weight); - registry.fill(HIST("h3_intrate_centrality_track_pt"), collision.hadronicRate(), collision.centFT0M(), track.pt(), weight); + registry.fill(HIST("h3_intrate_centrality_track_pt"), collision.hadronicRate(), centrality, track.pt(), weight); } } - template - void fillParticlesHistograms(TCollision const& collision, TParticles const& mcparticles, TTracks tracks, float weight = 1.0) + template + void fillParticlesHistograms(TMCCollision const& /*mcCollision*/, TCollisions const& collisions, TParticles const& mcparticles, TTracks tracks, float weight = 1.0) { + // float centrality = checkCentFT0M ? mcCollision.centFT0M() : mcCollision.centFT0C(); mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + float centrality = checkCentFT0M ? collisions.begin().centFT0M() : collisions.begin().centFT0C(); + for (auto const& mcparticle : mcparticles) { - registry.fill(HIST("h2_centrality_particle_pt"), collision.centFT0M(), mcparticle.pt(), weight); - registry.fill(HIST("h2_centrality_particle_eta"), collision.centFT0M(), mcparticle.eta(), weight); - registry.fill(HIST("h2_centrality_particle_phi"), collision.centFT0M(), mcparticle.phi(), weight); - registry.fill(HIST("h2_centrality_particle_energy"), collision.centFT0M(), mcparticle.energy(), weight); - registry.fill(HIST("h3_intrate_centrality_particle_pt"), collision.hadronicRate(), collision.centFT0M(), mcparticle.pt(), weight); + registry.fill(HIST("h2_centrality_particle_pt"), centrality, mcparticle.pt(), weight); + registry.fill(HIST("h2_centrality_particle_eta"), centrality, mcparticle.eta(), weight); + registry.fill(HIST("h2_centrality_particle_phi"), centrality, mcparticle.phi(), weight); + registry.fill(HIST("h2_centrality_particle_energy"), centrality, mcparticle.energy(), weight); + registry.fill(HIST("h3_intrate_centrality_particle_pt"), collisions.begin().hadronicRate(), centrality, mcparticle.pt(), weight); auto partTracks = tracks.sliceBy(tracksPerJParticles, mcparticle.globalIndex()); for (auto const& track : partTracks) { registry.fill(HIST("h2_particle_pt_track_pt_deltapt"), mcparticle.pt(), mcparticle.pt() - track.pt(), weight); @@ -374,7 +380,7 @@ struct TrackEfficiency { // filters for processTracks QA functions only: Filter trackCuts = (aod::jtrack::pt >= trackQAPtMin && aod::jtrack::pt < trackQAPtMax && aod::jtrack::eta > trackQAEtaMin && aod::jtrack::eta < trackQAEtaMax); Filter particleCuts = (aod::jmcparticle::pt >= trackQAPtMin && aod::jmcparticle::pt < trackQAPtMax && aod::jmcparticle::eta > trackQAEtaMin && aod::jmcparticle::eta < trackQAEtaMax); - Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centFT0M >= centralityMin && aod::jcollision::centFT0M < centralityMax); + Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut); void processEFficiencyPurity(soa::Join::iterator const& mcCollision, soa::Join const&, @@ -405,30 +411,33 @@ struct TrackEfficiency { } registry.fill(HIST("hMcCollCutsCounts"), 3.5); // split mcCollisions condition + float centrality = -1; bool hasSel8Coll = false; bool centralityCheck = false; bool occupancyCheck = false; if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have their first associated collision not reconstructed hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collisions.begin().centFT0M()) && (collisions.begin().centFT0M() < centralityMax))) { // effect unclear if mcColl is split - centralityCheck = true; - } if (!checkOccupancy || ((trackOccupancyInTimeRangeMin < collisions.begin().trackOccupancyInTimeRange()) && (collisions.begin().trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMax))) { // check occupancy only in GP Pb-Pb MC occupancyCheck = true; } + centrality = checkCentFT0M ? collisions.begin().centFT0M() : collisions.begin().centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics + centralityCheck = true; + } } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks for (auto const& collision : collisions) { if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collision.centFT0M()) && (collision.centFT0M() < centralityMax))) { // effect unclear if mcColl is split - centralityCheck = true; - } - if (!checkOccupancy || ((trackOccupancyInTimeRangeMin < collisions.begin().trackOccupancyInTimeRange()) && (collisions.begin().trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMax))) { // check occupancy only in GP Pb-Pb MC + if (!checkOccupancy || ((trackOccupancyInTimeRangeMin < collision.trackOccupancyInTimeRange()) && (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMax))) { // check occupancy only in GP Pb-Pb MC occupancyCheck = true; } + centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // effect unclear if mcColl is split + centralityCheck = true; + } } } if (!hasSel8Coll) { @@ -436,6 +445,10 @@ struct TrackEfficiency { } registry.fill(HIST("hMcCollCutsCounts"), 4.5); // at least one of the reconstructed collisions associated with this mcCollision is selected + // float centrality = checkCentFT0M ? mcCollision.centFT0M() : mcCollision.centFT0C(); mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + // if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + // return; + // } if (!centralityCheck) { return; } @@ -586,13 +599,15 @@ struct TrackEfficiency { } registry.fill(HIST("hMcCollCutsCounts"), 3.5, mcCollision.weight()); // split mcCollisions condition + float centrality = -1; bool hasSel8Coll = false; bool centralityCheck = false; if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have their first associated collision not reconstructed hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collisions.begin().centFT0M()) && (collisions.begin().centFT0M() < centralityMax))) { // effect unclear if mcColl is split + centrality = checkCentFT0M ? collisions.begin().centFT0M() : collisions.begin().centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics centralityCheck = true; } } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks @@ -600,7 +615,8 @@ struct TrackEfficiency { if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collision.centFT0M()) && (collision.centFT0M() < centralityMax))) { // effect unclear if mcColl is split + centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics centralityCheck = true; } } @@ -610,12 +626,15 @@ struct TrackEfficiency { } registry.fill(HIST("hMcCollCutsCounts"), 4.5, mcCollision.weight()); // at least one of the reconstructed collisions associated with this mcCollision is selected + // float centrality = checkCentFT0M ? mcCollision.centFT0M() : mcCollision.centFT0C(); mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + // if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + // return; + // } if (!centralityCheck) { return; } - registry.fill(HIST("hMcCollCutsCounts"), 5.5, mcCollision.weight()); // at least one of the reconstructed collisions associated with this mcCollision is selected with regard to centrality + registry.fill(HIST("hMcCollCutsCounts"), 5.5, mcCollision.weight()); // centrality condition - float simPtRef = 10.; float mcCollEventWeight = mcCollision.weight(); float pTHat = simPtRef / (std::pow(mcCollEventWeight, 1.0 / pTHatExponent)); if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max @@ -742,6 +761,10 @@ struct TrackEfficiency { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + return; + } if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; } @@ -750,7 +773,7 @@ struct TrackEfficiency { } PROCESS_SWITCH(TrackEfficiency, processTracksFromData, "QA for charged tracks in data", false); - void processTracksFromMc(soa::Join::iterator const& collision, // a filter should probably be added here to stay consistent with processTracksFromData + void processTracksFromMc(soa::Filtered>::iterator const& collision, soa::Join const&, soa::Join const&, soa::Filtered> const& jetTracks, @@ -762,6 +785,10 @@ struct TrackEfficiency { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + return; + } if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; } @@ -775,7 +802,7 @@ struct TrackEfficiency { } PROCESS_SWITCH(TrackEfficiency, processTracksFromMc, "QA for charged tracks in MC without weights", false); - void processTracksFromMcWeighted(soa::Join::iterator const& collision, // a filter should probably be added here to stay consistent with processTracksFromData + void processTracksFromMcWeighted(soa::Filtered>::iterator const& collision, soa::Join const&, soa::Join const&, soa::Filtered> const& jetTracks, @@ -788,6 +815,10 @@ struct TrackEfficiency { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + return; + } if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { return; } @@ -823,13 +854,15 @@ struct TrackEfficiency { return; } + float centrality = -1; bool hasSel8Coll = false; bool centralityCheck = false; if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have their first associated collision not reconstructed hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collisions.begin().centFT0M()) && (collisions.begin().centFT0M() < centralityMax))) { // effect unclear if mcColl is split + centrality = checkCentFT0M ? collisions.begin().centFT0M() : collisions.begin().centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics centralityCheck = true; } } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks @@ -837,7 +870,8 @@ struct TrackEfficiency { if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collision.centFT0M()) && (collision.centFT0M() < centralityMax))) { // effect unclear if mcColl is split + centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics centralityCheck = true; } } @@ -845,11 +879,15 @@ struct TrackEfficiency { if (!hasSel8Coll) { return; } + // float centrality = checkCentFT0M ? mcCollision.centFT0M() : mcCollision.centFT0C(); mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + // if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + // return; + // } if (!centralityCheck) { return; } - fillParticlesHistograms(collisions.begin(), mcparticles, tracks); + fillParticlesHistograms(mcCollision, collisions, mcparticles, tracks); } PROCESS_SWITCH(TrackEfficiency, processParticles, "QA for charged particles", false); @@ -880,13 +918,15 @@ struct TrackEfficiency { return; } + float centrality = -1; bool hasSel8Coll = false; bool centralityCheck = false; if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have their first associated collision not reconstructed hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collisions.begin().centFT0M()) && (collisions.begin().centFT0M() < centralityMax))) { // effect unclear if mcColl is split + centrality = checkCentFT0M ? collisions.begin().centFT0M() : collisions.begin().centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics centralityCheck = true; } } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks @@ -894,7 +934,8 @@ struct TrackEfficiency { if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } - if (!checkCentrality || ((centralityMin < collision.centFT0M()) && (collision.centFT0M() < centralityMax))) { // effect unclear if mcColl is split + centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics centralityCheck = true; } } @@ -902,65 +943,86 @@ struct TrackEfficiency { if (!hasSel8Coll) { return; } + + // float centrality = checkCentFT0M ? mcCollision.centFT0M() : mcCollision.centFT0C(); mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + // if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + // return; + // } if (!centralityCheck) { return; } - fillParticlesHistograms(collisions.begin(), mcparticles, tracks, eventWeight); + fillParticlesHistograms(mcCollision, collisions, mcparticles, tracks, eventWeight); } PROCESS_SWITCH(TrackEfficiency, processParticlesWeighted, "QA for charged particles weighted", false); void processCollisionsFromData(soa::Filtered::iterator const& collision) { + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + registry.fill(HIST("h_collisions"), 0.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 0.5); + registry.fill(HIST("h2_centrality_collisions"), centrality, 0.5); if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } registry.fill(HIST("h_collisions"), 1.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 1.5); - if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + registry.fill(HIST("h2_centrality_collisions"), centrality, 1.5); + if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { return; } registry.fill(HIST("h_collisions"), 2.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 2.5); + registry.fill(HIST("h2_centrality_collisions"), centrality, 2.5); + if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + return; + } + registry.fill(HIST("h_collisions"), 3.5); + registry.fill(HIST("h2_centrality_collisions"), centrality, 3.5); } PROCESS_SWITCH(TrackEfficiency, processCollisionsFromData, "QA for reconstructed collisions in data", false); - void processCollisionsFromMc(soa::Join::iterator const& collision, // a filter should probably be added here to stay consistent with processTracksFromData + void processCollisionsFromMc(soa::Filtered>::iterator const& collision, soa::Join const&, soa::Join const&) { + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!collision.has_mcCollision()) { // the collision is fake and has no associated mc coll; skip as .mccollision() cannot be called registry.fill(HIST("h_fakecollisions"), 0.5); return; } registry.fill(HIST("h_collisions"), 0.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 0.5); + registry.fill(HIST("h2_centrality_collisions"), centrality, 0.5); if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } registry.fill(HIST("h_collisions"), 1.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 1.5); - if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + registry.fill(HIST("h2_centrality_collisions"), centrality, 1.5); + if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { return; } registry.fill(HIST("h_collisions"), 2.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 2.5); + registry.fill(HIST("h2_centrality_collisions"), centrality, 2.5); + if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + return; + } + registry.fill(HIST("h_collisions"), 3.5); + registry.fill(HIST("h2_centrality_collisions"), centrality, 3.5); float pTHat = getPtHatFromHepMCXSection ? collision.mcCollision_as>().mcCollision_as>().ptHard() : 10. / (std::pow(collision.mcCollision().weight(), 1.0 / pTHatExponent)); if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max return; } - registry.fill(HIST("h_collisions"), 3.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 3.5); + registry.fill(HIST("h_collisions"), 4.5); + registry.fill(HIST("h2_centrality_collisions"), centrality, 4.5); } PROCESS_SWITCH(TrackEfficiency, processCollisionsFromMc, "QA for reconstructed collisions in MC without weights", false); - void processCollisionsFromMcWeighted(soa::Join::iterator const& collision, // a filter should probably be added here to stay consistent with processTracksFromData + void processCollisionsFromMcWeighted(soa::Filtered>::iterator const& collision, soa::Join const&, soa::Join const&) { + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!collision.has_mcCollision()) { // the collision is fake and has no associated mc coll; skip as .mccollision() cannot be called registry.fill(HIST("h_fakecollisions"), 0.5); return; @@ -973,18 +1035,23 @@ struct TrackEfficiency { } registry.fill(HIST("h_collisions"), 1.5); registry.fill(HIST("h_collisions_weighted"), 1.5, eventWeight); - if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { return; } registry.fill(HIST("h_collisions"), 2.5); registry.fill(HIST("h_collisions_weighted"), 2.5, eventWeight); + if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + return; + } + registry.fill(HIST("h_collisions"), 3.5); + registry.fill(HIST("h_collisions_weighted"), 3.5, eventWeight); float pTHat = getPtHatFromHepMCXSection ? collision.mcCollision_as>().mcCollision_as>().ptHard() : 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max return; } - registry.fill(HIST("h_collisions"), 3.5); - registry.fill(HIST("h2_centrality_collisions"), collision.centFT0M(), 3.5, eventWeight); + registry.fill(HIST("h_collisions"), 4.5); + registry.fill(HIST("h_collisions_weighted"), 4.5, eventWeight); } PROCESS_SWITCH(TrackEfficiency, processCollisionsFromMcWeighted, "QA for reconstructed collisions in weighted MC", false); @@ -992,12 +1059,39 @@ struct TrackEfficiency { soa::Join const&, soa::SmallGroups const& collisions) { + // float centrality = checkCentFT0M ? mcCollision.centFT0M() : mcCollision.centFT0C(); mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + float eventWeight = mcCollision.weight(); float pTHat = getPtHatFromHepMCXSection ? mcCollision.mcCollision_as>().ptHard() : 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); registry.fill(HIST("h2_mccollision_pthardfromweight_pthardfromhepmcxsection"), 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)), mcCollision.mcCollision_as>().ptHard()); + float centrality = -1; + bool hasSel8Coll = false; + bool centralityCheck = false; + if (collisions.size() > 1) { // remove and move the if block below under if (collisions.size() < 1) { when mccoll.centFt0C has been fixed + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have their first associated collision not reconstructed + hasSel8Coll = true; + } + centrality = checkCentFT0M ? collisions.begin().centFT0M() : collisions.begin().centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics + centralityCheck = true; + } + } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks + for (auto const& collision : collisions) { + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + hasSel8Coll = true; + } + centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics + centralityCheck = true; + } + } + } + } + registry.fill(HIST("h_mccollisions"), 0.5); - registry.fill(HIST("h2_centrality_mccollisions"), collisions.begin().centFT0M(), 0.5); + registry.fill(HIST("h2_centrality_mccollisions"), centrality, 0.5); if (!(std::abs(mcCollision.posZ()) < vertexZCut)) { return; @@ -1013,35 +1107,20 @@ struct TrackEfficiency { return; } registry.fill(HIST("h_mccollisions"), 1.5); - registry.fill(HIST("h2_centrality_mccollisions"), collisions.begin().centFT0M(), 1.5); + registry.fill(HIST("h2_centrality_mccollisions"), centrality, 1.5); - bool hasSel8Coll = false; - bool centralityCheck = false; - if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split - hasSel8Coll = true; - } - if (!checkCentrality || ((centralityMin < collisions.begin().centFT0M()) && (collisions.begin().centFT0M() < centralityMax))) { // effect unclear if mcColl is split - centralityCheck = true; - } - } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks - for (auto const& collision : collisions) { - if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split - hasSel8Coll = true; - } - if (!checkCentrality || ((centralityMin < collision.centFT0M()) && (collision.centFT0M() < centralityMax))) { // effect unclear if mcColl is split - centralityCheck = true; - } - } - } if (!hasSel8Coll) { return; } + // if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + // return; + // } if (!centralityCheck) { return; } + registry.fill(HIST("h_mccollisions"), 2.5); - registry.fill(HIST("h2_centrality_mccollisions"), collisions.begin().centFT0M(), 2.5); + registry.fill(HIST("h2_centrality_mccollisions"), centrality, 2.5); } PROCESS_SWITCH(TrackEfficiency, processMcCollisions, "QA for McCollisions in MC without weights", false); @@ -1053,13 +1132,42 @@ struct TrackEfficiency { return; } + // float centrality = checkCentFT0M ? mcCollision.centFT0M() : mcCollision.centFT0C(); mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + float eventWeight = mcCollision.weight(); float pTHat = getPtHatFromHepMCXSection ? mcCollision.mcCollision_as>().ptHard() : 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); registry.fill(HIST("h2_mccollision_pthardfromweight_pthardfromhepmcxsection"), 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)), mcCollision.mcCollision_as>().ptHard()); registry.fill(HIST("h2_mccollision_pthardfromweight_pthardfromhepmcxsection_weighted"), 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)), mcCollision.mcCollision_as>().ptHard(), eventWeight); + float centrality = -1; + bool hasSel8Coll = false; + bool centralityCheck = false; + if (collisions.size() > 1) { // remove and move the if block below under if (collisions.size() < 1) { when mccoll.centFt0C has been fixed + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have their first associated collision not reconstructed + hasSel8Coll = true; + } + centrality = checkCentFT0M ? collisions.begin().centFT0M() : collisions.begin().centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics + centralityCheck = true; + } + } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks + for (auto const& collision : collisions) { + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + hasSel8Coll = true; + } + centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (!cutCentrality || ((centralityMin < centrality) && (centrality < centralityMax))) { // mcCollision.centFT0C() isn't filled at the moment; can use it instead when it is added to O2Physics + centralityCheck = true; + } + } + } + } + registry.fill(HIST("h_mccollisions"), 0.5); registry.fill(HIST("h_mccollisions_weighted"), 0.5, eventWeight); + registry.fill(HIST("h2_centrality_mccollisions"), centrality, 0.5); + registry.fill(HIST("h2_centrality_mccollisions_weighted"), centrality, 0.5, eventWeight); if (!(std::abs(mcCollision.posZ()) < vertexZCut)) { return; @@ -1076,55 +1184,55 @@ struct TrackEfficiency { } registry.fill(HIST("h_mccollisions"), 1.5); registry.fill(HIST("h_mccollisions_weighted"), 1.5, eventWeight); + registry.fill(HIST("h2_centrality_mccollisions"), centrality, 1.5); + registry.fill(HIST("h2_centrality_mccollisions_weighted"), centrality, 1.5, eventWeight); - bool hasSel8Coll = false; - bool centralityCheck = false; - if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split - hasSel8Coll = true; - } - if (!checkCentrality || ((centralityMin < collisions.begin().centFT0M()) && (collisions.begin().centFT0M() < centralityMax))) { // effect unclear if mcColl is split - centralityCheck = true; - } - } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks - for (auto const& collision : collisions) { - if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split - hasSel8Coll = true; - } - if (!checkCentrality || ((centralityMin < collision.centFT0M()) && (collision.centFT0M() < centralityMax))) { // effect unclear if mcColl is split - centralityCheck = true; - } - } - } if (!hasSel8Coll) { return; } + // if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { mcCollision.centFT0C() isn't filled at the moment; can be added back when it is + // return; + // } if (!centralityCheck) { return; } registry.fill(HIST("h_mccollisions"), 2.5); registry.fill(HIST("h_mccollisions_weighted"), 2.5, eventWeight); + registry.fill(HIST("h2_centrality_mccollisions"), centrality, 2.5); + registry.fill(HIST("h2_centrality_mccollisions_weighted"), centrality, 2.5, eventWeight); } PROCESS_SWITCH(TrackEfficiency, processMcCollisionsWeighted, "QA for McCollisions in weighted MC", false); - void processTrackSelectionHistograms(soa::Join::iterator const& track, aod::JetCollisions const&) + void processTrackSelectionHistograms(soa::Filtered::iterator const& collision, soa::Join const& jetTracks, soa::Join const&) { - if (!jetderiveddatautilities::selectCollision(track.collision_as(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split - return; - } - registry.fill(HIST("h_trackselplot_tpccrossedrows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("h_trackselplot_tpccrossedrowsoverfindable"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("h_trackselplot_chi2ncls_tpc"), track.tpcChi2NCl()); - registry.fill(HIST("h_trackselplot_chi2ncls_its"), track.itsChi2NCl()); - registry.fill(HIST("h_trackselplot_dcaxy"), track.dcaXY()); - registry.fill(HIST("h_trackselplot_dcaz"), track.dcaZ()); - - registry.fill(HIST("h2_trackselplot_pt_tpccrossedrows"), track.pt(), track.tpcNClsCrossedRows()); - registry.fill(HIST("h2_trackselplot_pt_tpccrossedrowsoverfindable"), track.pt(), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("h2_trackselplot_pt_chi2ncls_tpc"), track.pt(), track.tpcChi2NCl()); - registry.fill(HIST("h2_trackselplot_pt_chi2ncls_its"), track.pt(), track.itsChi2NCl()); - registry.fill(HIST("h2_trackselplot_pt_dcaxy"), track.pt(), track.dcaXY()); - registry.fill(HIST("h2_trackselplot_pt_dcaz"), track.pt(), track.dcaZ()); + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { + return; + } + float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C(); + if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) { + return; + } + if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + return; + } + + for (auto const& jetTrack : jetTracks) { + const auto& aodTrack = jetTrack.track_as>(); + + registry.fill(HIST("h_trackselplot_tpccrossedrows"), aodTrack.tpcNClsCrossedRows()); + registry.fill(HIST("h_trackselplot_tpccrossedrowsoverfindable"), aodTrack.tpcCrossedRowsOverFindableCls()); + registry.fill(HIST("h_trackselplot_chi2ncls_tpc"), aodTrack.tpcChi2NCl()); + registry.fill(HIST("h_trackselplot_chi2ncls_its"), aodTrack.itsChi2NCl()); + registry.fill(HIST("h_trackselplot_dcaxy"), aodTrack.dcaXY()); + registry.fill(HIST("h_trackselplot_dcaz"), aodTrack.dcaZ()); + + registry.fill(HIST("h2_trackselplot_pt_tpccrossedrows"), aodTrack.pt(), aodTrack.tpcNClsCrossedRows()); + registry.fill(HIST("h2_trackselplot_pt_tpccrossedrowsoverfindable"), aodTrack.pt(), aodTrack.tpcCrossedRowsOverFindableCls()); + registry.fill(HIST("h2_trackselplot_pt_chi2ncls_tpc"), aodTrack.pt(), aodTrack.tpcChi2NCl()); + registry.fill(HIST("h2_trackselplot_pt_chi2ncls_its"), aodTrack.pt(), aodTrack.itsChi2NCl()); + registry.fill(HIST("h2_trackselplot_pt_dcaxy"), aodTrack.pt(), aodTrack.dcaXY()); + registry.fill(HIST("h2_trackselplot_pt_dcaz"), aodTrack.pt(), aodTrack.dcaZ()); + } } PROCESS_SWITCH(TrackEfficiency, processTrackSelectionHistograms, "plots distributions of variables that are cut on during track selection", false); };