Skip to content

Commit dbf2e75

Browse files
authored
Merge branch 'master' into mftextras
2 parents 0544ca7 + 600bd24 commit dbf2e75

34 files changed

+2772
-938
lines changed

.github/workflows/mega-linter.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
id: ml
3939
# You can override MegaLinter flavor used to have faster performances
4040
# More info at https://megalinter.io/flavors/
41-
uses: oxsecurity/megalinter@v8.1.0
41+
uses: oxsecurity/megalinter@v8.3.0
4242
env:
4343
# All available variables are described in documentation:
4444
# https://megalinter.io/configuration/

Common/TableProducer/Converters/trackQA002Converter.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ using namespace o2::framework;
2020
struct TrackQAConverter002 {
2121
Produces<aod::TracksQA_002> tracksQA_002;
2222

23-
void process000(aod::TracksQA_000 const& tracksQA_001)
23+
void process000(aod::TracksQA_000 const& tracksQA_000)
2424
{
2525
for (const auto& trackQA : tracksQA_001) {
2626
tracksQA_002(

DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFMC.cxx

Lines changed: 226 additions & 221 deletions
Large diffs are not rendered by default.

EventFiltering/PWGHF/HFFilter.cxx

Lines changed: 90 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,27 @@
1919
/// \author Biao Zhang <[email protected]>, CCNU
2020
/// \author Federica Zanone <[email protected]>, Heidelberg University
2121

22+
#include <array>
23+
#include <memory>
24+
#include <string>
25+
#include <vector>
26+
2227
#include "TRandom3.h"
2328

2429
#include "CommonConstants/PhysicsConstants.h"
2530
#include "CCDB/BasicCCDBManager.h"
2631
#include "DataFormatsParameters/GRPMagField.h"
2732
#include "DataFormatsParameters/GRPObject.h"
33+
#include "DCAFitter/DCAFitterN.h"
2834
#include "DetectorsBase/Propagator.h"
2935
#include "Framework/AnalysisDataModel.h"
3036
#include "Framework/AnalysisTask.h"
3137
#include "Framework/ASoAHelpers.h"
3238
#include "Framework/HistogramRegistry.h"
3339
#include "Framework/runDataProcessing.h"
40+
#include "ReconstructionDataFormats/DCA.h"
3441

42+
#include "Common/Core/RecoDecay.h"
3543
#include "Common/Core/trackUtilities.h"
3644
#include "Common/DataModel/CollisionAssociationTables.h"
3745
#include "Common/DataModel/EventSelection.h"
@@ -41,6 +49,7 @@
4149

4250
#include "EventFiltering/filterTables.h"
4351
#include "EventFiltering/PWGHF/HFFilterHelpers.h"
52+
#include "PWGHF/Utils/utilsTrkCandHf.h"
4453

4554
using namespace o2;
4655
using namespace o2::analysis;
@@ -59,6 +68,7 @@ struct HfFilter { // Main struct for HF triggers
5968
Configurable<int> activateQA{"activateQA", 0, "flag to enable QA histos (0 no QA, 1 basic QA, 2 extended QA, 3 very extended QA)"};
6069
Configurable<bool> applyEventSelection{"applyEventSelection", true, "flag to enable event selection (sel8 + Zvt and possibly time-frame border cut)"};
6170
Configurable<bool> applyTimeFrameBorderCut{"applyTimeFrameBorderCut", true, "flag to enable time-frame border cut"};
71+
Configurable<bool> activateSecVtx{"activateSecVtx", false, "flag to enable 2nd vertex fitting - only beauty hadrons"};
6272

6373
// parameters for all triggers
6474
// nsigma PID (except for V0 and cascades)
@@ -76,6 +86,8 @@ struct HfFilter { // Main struct for HF triggers
7686
Configurable<LabeledArray<double>> cutsTrackBeauty4Prong{"cutsTrackBeauty4Prong", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for 4-prong beauty candidates"};
7787
Configurable<std::string> paramCharmMassShape{"paramCharmMassShape", "2023_pass3", "Parametrisation of charm-hadron mass shape (options: 2023_pass3)"};
7888
Configurable<float> numSigmaDeltaMassCharmHad{"numSigmaDeltaMassCharmHad", 2.5, "Number of sigma for charm-hadron delta mass cut in B and D resonance triggers"};
89+
Configurable<std::vector<double>> pTBinsBHadron{"pTBinsBHadron", std::vector<double>{hf_trigger_cuts_presel_beauty::vecBinsPt}, "pT bin limits for beauty hadrons preselections"};
90+
Configurable<LabeledArray<double>> cutsBplus{"cutsBplus", {hf_trigger_cuts_presel_beauty::cuts[0], hf_trigger_cuts_presel_beauty::nBinsPt, hf_trigger_cuts_presel_beauty::nCutVars, hf_trigger_cuts_presel_beauty::labelsPt, hf_trigger_cuts_presel_beauty::labelsRowsTopolBeauty}, "B+ candidate selection per pT bin"};
7991

8092
// parameters for femto triggers
8193
Configurable<float> femtoMaxRelativeMomentum{"femtoMaxRelativeMomentum", 2., "Maximal allowed value for relative momentum between charm-proton pairs in GeV/c"};
@@ -135,6 +147,9 @@ struct HfFilter { // Main struct for HF triggers
135147
// array of BDT thresholds
136148
std::array<LabeledArray<double>, kNCharmParticles> thresholdBDTScores;
137149

150+
o2::vertexing::DCAFitterN<2> df2; // fitter for Charm Hadron vertex (2-prong vertex fitter)
151+
o2::vertexing::DCAFitterN<2> dfB; // fitter for Beauty Hadron vertex (2-prong vertex fitter)
152+
138153
HistogramRegistry registry{"registry"};
139154
std::shared_ptr<TH1> hProcessedEvents;
140155

@@ -151,6 +166,9 @@ struct HfFilter { // Main struct for HF triggers
151166
std::array<std::shared_ptr<TH2>, kNV0> hArmPod{};
152167
std::shared_ptr<TH2> hV0Selected;
153168
std::shared_ptr<TH1> hMassXi;
169+
std::array<std::shared_ptr<TH2>, kNBeautyParticles> hCpaVsPtB{};
170+
std::array<std::shared_ptr<TH2>, kNBeautyParticles> hDecayLengthVsPtB{};
171+
std::array<std::shared_ptr<TH2>, kNBeautyParticles> hImpactParamProductVsPtB{};
154172

155173
// material correction for track propagation
156174
o2::base::MatLayerCylSet* lut;
@@ -164,12 +182,14 @@ struct HfFilter { // Main struct for HF triggers
164182
{
165183
helper.setHighPtTriggerThresholds(ptThresholds->get(0u, 0u), ptThresholds->get(0u, 1u));
166184
helper.setPtBinsSingleTracks(pTBinsTrack);
185+
helper.setPtBinsBeautyHadrons(pTBinsBHadron);
167186
helper.setPtLimitsBeautyBachelor(ptCuts->get(0u, 0u), ptCuts->get(1u, 0u));
168187
helper.setPtLimitsDstarSoftPion(ptCuts->get(0u, 1u), ptCuts->get(1u, 1u));
169188
helper.setPtLimitsProtonForFemto(ptCuts->get(0u, 2u), ptCuts->get(1u, 2u));
170189
helper.setPtLimitsCharmBaryonBachelor(ptCuts->get(0u, 3u), ptCuts->get(1u, 3u));
171190
helper.setCutsSingleTrackBeauty(cutsTrackBeauty3Prong, cutsTrackBeauty4Prong);
172191
helper.setCutsSingleTrackCharmBaryonBachelor(cutsTrackCharmBaryonBachelor);
192+
helper.setCutsBplus(cutsBplus);
173193
helper.setPtThresholdPidStrategyForFemto(ptThresholdForFemtoPid);
174194
helper.setNsigmaProtonCutsForFemto(std::array{nSigmaPidCuts->get(0u, 3u), nSigmaPidCuts->get(1u, 3u), nSigmaPidCuts->get(2u, 3u)});
175195
helper.setNsigmaProtonCutsForCharmBaryons(nSigmaPidCuts->get(0u, 0u), nSigmaPidCuts->get(1u, 0u));
@@ -184,7 +204,10 @@ struct HfFilter { // Main struct for HF triggers
184204
helper.setPtRangeSoftPiSigmaC(ptCuts->get(0u, 4u), ptCuts->get(1u, 4u));
185205
helper.setPtDeltaMassRangeSigmaC(cutsPtDeltaMassCharmReso->get(0u, 6u), cutsPtDeltaMassCharmReso->get(1u, 6u), cutsPtDeltaMassCharmReso->get(0u, 7u), cutsPtDeltaMassCharmReso->get(1u, 7u), cutsPtDeltaMassCharmReso->get(0u, 8u), cutsPtDeltaMassCharmReso->get(1u, 8u), cutsPtDeltaMassCharmReso->get(0u, 9u), cutsPtDeltaMassCharmReso->get(1u, 9u), cutsPtDeltaMassCharmReso->get(2u, 6u), cutsPtDeltaMassCharmReso->get(2u, 7u), cutsPtDeltaMassCharmReso->get(2u, 8u), cutsPtDeltaMassCharmReso->get(2u, 9u));
186206
helper.setPtRangeSoftKaonXicResoToSigmaC(ptCuts->get(0u, 5u), ptCuts->get(1u, 5u));
187-
207+
if (activateSecVtx) {
208+
helper.setVtxConfiguration(df2, false); // (DCAFitterN, useAbsDCA)
209+
helper.setVtxConfiguration(dfB, true);
210+
}
188211
hProcessedEvents = registry.add<TH1>("fProcessedEvents", "HF - event filtered;;counts", HistType::kTH1F, {{kNtriggersHF + 2, -0.5, +kNtriggersHF + 1.5}});
189212
for (auto iBin = 0; iBin < kNtriggersHF + 2; ++iBin) {
190213
if (iBin < 2)
@@ -230,7 +253,21 @@ struct HfFilter { // Main struct for HF triggers
230253

231254
for (int iBeautyPart{0}; iBeautyPart < kNBeautyParticles; ++iBeautyPart) {
232255
hMassVsPtB[iBeautyPart] = registry.add<TH2>(Form("fMassVsPt%s", beautyParticleNames[iBeautyPart].data()), Form("#it{M} vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", beautyParticleNames[iBeautyPart].data()), HistType::kTH2F, {ptAxis, massAxisB[iBeautyPart]});
256+
hCpaVsPtB[iBeautyPart] = registry.add<TH2>(Form("fCpaVsPt%s", beautyParticleNames[iBeautyPart].data()), Form("CPA vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", beautyParticleNames[iBeautyPart].data()), HistType::kTH2F, {ptAxis, {100, -1, 1}});
257+
hDecayLengthVsPtB[iBeautyPart] = registry.add<TH2>(Form("fDecayLengthVsPt%s", beautyParticleNames[iBeautyPart].data()), Form("DecayLength vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", beautyParticleNames[iBeautyPart].data()), HistType::kTH2F, {ptAxis, {100, 0, 20}});
258+
hImpactParamProductVsPtB[iBeautyPart] = registry.add<TH2>(Form("fImpactParamProductVsPt%s", beautyParticleNames[iBeautyPart].data()), Form("ImpactParamProduct vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", beautyParticleNames[iBeautyPart].data()), HistType::kTH2F, {ptAxis, {100, -2.5, +2.5}});
259+
}
260+
constexpr int kNBinsHfVtxStages = kNHfVtxStage;
261+
std::string labels[kNBinsHfVtxStages];
262+
labels[HfVtxStage::Skimmed] = "Skimm CharmHad-Pi pairs";
263+
labels[HfVtxStage::BeautyVertex] = "vertex CharmHad-Pi pairs";
264+
labels[HfVtxStage::CharmHadPiSelected] = "selected CharmHad-Pi pairs";
265+
static const AxisSpec axisHfVtxStages = {kNBinsHfVtxStages, 0.5, kNBinsHfVtxStages + 0.5, ""};
266+
registry.add("fHfVtxStages", "HfVtxStages;;entries", HistType::kTH1F, {axisHfVtxStages});
267+
for (int iBin = 0; iBin < kNBinsHfVtxStages; iBin++) {
268+
registry.get<TH1>(HIST("fHfVtxStages"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data());
233269
}
270+
234271
for (int iV0{kPhoton}; iV0 < kNV0; ++iV0) {
235272
hArmPod[iV0] = registry.add<TH2>(Form("fArmPod%s", v0Names[iV0].data()), Form("Armenteros Podolanski plot for selected %s;#it{#alpha};#it{q}_{T} (GeV/#it{c})", v0Labels[iV0].data()), HistType::kTH2F, {alphaAxis, qtAxis});
236273
}
@@ -267,7 +304,7 @@ struct HfFilter { // Main struct for HF triggers
267304
}
268305

269306
using BigTracksMCPID = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr, aod::McTrackLabels>;
270-
using BigTracksPID = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection, aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr>;
307+
using BigTracksPID = soa::Join<aod::Tracks, aod::TracksWCovDcaExtra, aod::TracksDCA, aod::TrackSelection, aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr>;
271308
using CollsWithEvSel = soa::Join<aod::Collisions, aod::EvSels>;
272309

273310
using Hf2ProngsWithMl = soa::Join<aod::Hf2Prongs, aod::Hf2ProngMlProbs>;
@@ -342,8 +379,8 @@ struct HfFilter { // Main struct for HF triggers
342379
continue;
343380
}
344381

345-
auto trackParPos = getTrackPar(trackPos);
346-
auto trackParNeg = getTrackPar(trackNeg);
382+
auto trackParPos = getTrackParCov(trackPos);
383+
auto trackParNeg = getTrackParCov(trackNeg);
347384
o2::gpu::gpustd::array<float, 2> dcaPos{trackPos.dcaXY(), trackPos.dcaZ()};
348385
o2::gpu::gpustd::array<float, 2> dcaNeg{trackNeg.dcaXY(), trackNeg.dcaZ()};
349386
std::array<float, 3> pVecPos{trackPos.pVector()};
@@ -418,7 +455,7 @@ struct HfFilter { // Main struct for HF triggers
418455
continue;
419456
}
420457

421-
auto trackParThird = getTrackPar(track);
458+
auto trackParThird = getTrackParCov(track);
422459
o2::gpu::gpustd::array<float, 2> dcaThird{track.dcaXY(), track.dcaZ()};
423460
std::array<float, 3> pVecThird = track.pVector();
424461
if (track.collisionId() != thisCollId) {
@@ -432,14 +469,52 @@ struct HfFilter { // Main struct for HF triggers
432469
auto massCand = RecoDecay::m(std::array{pVec2Prong, pVecThird}, std::array{massD0, massPi});
433470
auto pVecBeauty3Prong = RecoDecay::pVec(pVec2Prong, pVecThird);
434471
auto ptCand = RecoDecay::pt(pVecBeauty3Prong);
435-
if (TESTBIT(isTrackSelected, kForBeauty) && std::fabs(massCand - massBPlus) <= deltaMassBeauty->get(0u, 0u)) {
436-
keepEvent[kBeauty3P] = true;
437-
// fill optimisation tree for D0
438-
if (applyOptimisation) {
439-
optimisationTreeBeauty(thisCollId, o2::constants::physics::Pdg::kD0, pt2Prong, scores[0], scores[1], scores[2], dcaThird[0]);
440-
}
472+
if (TESTBIT(isTrackSelected, kForBeauty) && helper.isSelectedBplusInMassRange(ptCand, massCand)) {
441473
if (activateQA) {
442-
hMassVsPtB[kBplus]->Fill(ptCand, massCand);
474+
registry.fill(HIST("fHfVtxStages"), 1 + HfVtxStage::Skimmed);
475+
}
476+
if (!activateSecVtx) {
477+
keepEvent[kBeauty3P] = true;
478+
// fill optimisation tree for D0
479+
if (applyOptimisation) {
480+
optimisationTreeBeauty(thisCollId, o2::constants::physics::Pdg::kD0, pt2Prong, scores[0], scores[1], scores[2], dcaThird[0]);
481+
}
482+
if (activateQA) {
483+
hMassVsPtB[kBplus]->Fill(ptCand, massCand);
484+
}
485+
} else {
486+
df2.process(trackParPos, trackParNeg);
487+
df2.getTrack(0).getPxPyPzGlo(pVecPos);
488+
df2.getTrack(1).getPxPyPzGlo(pVecNeg);
489+
auto trackParD = df2.createParentTrackParCov();
490+
trackParD.setAbsCharge(0); // to be sure
491+
auto pVec2Prong = RecoDecay::pVec(pVecPos, pVecNeg);
492+
if (dfB.process(trackParD, trackParThird) != 0) {
493+
if (activateQA) {
494+
registry.fill(HIST("fHfVtxStages"), 1 + HfVtxStage::BeautyVertex);
495+
}
496+
const auto& secondaryVertexBplus = dfB.getPCACandidate();
497+
dfB.propagateTracksToVertex();
498+
dfB.getTrack(0).getPxPyPzGlo(pVec2Prong);
499+
dfB.getTrack(1).getPxPyPzGlo(pVecThird);
500+
o2::gpu::gpustd::array<float, 2> dca2Prong; //{trackParD.dcaXY(), trackParD.dcaZ()};
501+
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParD, 2.f, noMatCorr, &dca2Prong);
502+
bool isBplus = helper.isSelectedBplus(pVec2Prong, pVecThird, dca2Prong, dcaThird, std::array<double, 3>{static_cast<double>(collision.posX()), static_cast<double>(collision.posY()), static_cast<double>(collision.posZ())}, std::array{secondaryVertexBplus[0], secondaryVertexBplus[1], secondaryVertexBplus[2]});
503+
if (isBplus) {
504+
keepEvent[kBeauty3P] = true;
505+
// fill optimisation tree for D0
506+
if (applyOptimisation) {
507+
optimisationTreeBeauty(thisCollId, o2::constants::physics::Pdg::kD0, pt2Prong, scores[0], scores[1], scores[2], dcaThird[0]);
508+
}
509+
if (activateQA) {
510+
registry.fill(HIST("fHfVtxStages"), 1 + HfVtxStage::CharmHadPiSelected);
511+
hCpaVsPtB[kBplus]->Fill(RecoDecay::pt(RecoDecay::pVec(pVec2Prong, pVecThird)), RecoDecay::cpa(std::array<double, 3>{static_cast<double>(collision.posX()), static_cast<double>(collision.posY()), static_cast<double>(collision.posZ())}, std::array{secondaryVertexBplus[0], secondaryVertexBplus[1], secondaryVertexBplus[2]}, RecoDecay::pVec(pVec2Prong, pVecThird)));
512+
hDecayLengthVsPtB[kBplus]->Fill(RecoDecay::pt(RecoDecay::pVec(pVec2Prong, pVecThird)), RecoDecay::distance(std::array<double, 3>{static_cast<double>(collision.posX()), static_cast<double>(collision.posY()), static_cast<double>(collision.posZ())}, std::array{secondaryVertexBplus[0], secondaryVertexBplus[1], secondaryVertexBplus[2]}));
513+
hImpactParamProductVsPtB[kBplus]->Fill(RecoDecay::pt(RecoDecay::pVec(pVec2Prong, pVecThird)), dca2Prong[0] * dcaThird[0]);
514+
hMassVsPtB[kBplus]->Fill(ptCand, massCand);
515+
}
516+
}
517+
}
443518
}
444519
}
445520
}
@@ -990,9 +1065,9 @@ struct HfFilter { // Main struct for HF triggers
9901065
}
9911066
}
9921067
} // end SigmaC++ candidate
993-
} // end loop over tracks (soft pi)
994-
} // end candidate Lc->pKpi
995-
} // end loop over tracks
1068+
} // end loop over tracks (soft pi)
1069+
} // end candidate Lc->pKpi
1070+
} // end loop over tracks
9961071

9971072
// Ds with photon
9981073
bool isGoodDsToKKPi = (isSignalTagged[kDs - 1]) && TESTBIT(is3ProngInMass[kDs - 1], 0);

0 commit comments

Comments
 (0)