Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c07dec8
add kDeltaPhiPair Histogram
Shunsuke-Kurita Dec 21, 2023
ac0dfc2
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Feb 13, 2024
9e6a154
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita May 25, 2024
a9caa8b
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita May 27, 2024
c35f72d
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jun 28, 2024
e3272bb
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 18, 2024
144bb96
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 28, 2024
d2d6efc
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 29, 2024
14f244d
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 29, 2024
290f861
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 29, 2024
c885d07
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 31, 2024
607f2f6
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Oct 23, 2024
66f069c
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Oct 30, 2024
00c114a
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Nov 1, 2024
8c1915a
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Nov 6, 2024
faf8b2a
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Nov 15, 2024
36c3698
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Nov 26, 2024
d3f8e5e
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Dec 12, 2024
71cc0c2
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Apr 21, 2025
8bf7ea5
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jun 8, 2025
9e39d01
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 4, 2025
2c2c279
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Aug 28, 2025
2a1ca8b
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Nov 22, 2025
9ed16b2
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Dec 24, 2025
96e8aa2
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jan 27, 2026
8b678f7
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Apr 13, 2026
db8356c
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Apr 15, 2026
0aad0be
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Apr 27, 2026
7ab9406
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita May 15, 2026
aeacd7d
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jun 15, 2026
59bcc15
Merge branch 'AliceO2Group:master' into master
Shunsuke-Kurita Jul 24, 2026
7012202
[PWGDQ] Add post-prefilter single-track selection task to dqEfficienc…
Shunsuke-Kurita Jul 24, 2026
6db7649
[PWGDQ] Fill electron-leg DCA variables in FillPair for kElectronMuon…
Shunsuke-Kurita Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions PWGDQ/Core/VarManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -1524,7 +1524,7 @@

static void SetCalibrationType(int type, bool useInterpolation = true)
{
if (type < 0 || type > 2) {

Check failure on line 1527 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
LOG(fatal) << "Invalid calibration type. Must be 0, 1, or 2.";
}
fgCalibrationType = type;
Expand Down Expand Up @@ -1751,7 +1751,7 @@
{
o2::track::TrackParCovFwd fwdtrack = o2::aod::fwdtrackutils::getTrackParCovFwdShift(muon, fgzShiftFwd, muon);
o2::dataformats::GlobalFwdTrack propmuon;
if (static_cast<int>(muon.trackType()) > 2) {

Check failure on line 1754 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
o2::dataformats::GlobalFwdTrack track;
track.setParameters(fwdtrack.getParameters());
track.setZ(fwdtrack.getZ());
Expand All @@ -1776,7 +1776,7 @@
propmuon.setZ(proptrack.getZ());
propmuon.setCovariances(proptrack.getCovariances());

} else if (static_cast<int>(muon.trackType()) < 2) {

Check failure on line 1779 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
std::array<double, 3> dcaInfOrig{999.f, 999.f, 999.f};
fwdtrack.propagateToDCAhelix(fgMagField, {collision.posX(), collision.posY(), collision.posZ()}, dcaInfOrig);
propmuon.setParameters(fwdtrack.getParameters());
Expand Down Expand Up @@ -1838,7 +1838,7 @@

// Redo propagation only for muon tracks
// propagation of MFT tracks alredy done in fwdtrack-extention task
if (static_cast<int>(muon.trackType()) > 2) {

Check failure on line 1841 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
o2::dataformats::GlobalFwdTrack propmuonAtDCA = PropagateMuon(muon, collision, kToDCA);
o2::dataformats::GlobalFwdTrack propmuonAtRabs = PropagateMuon(muon, collision, kToRabs);
float dcaX = (propmuonAtDCA.getX() - collision.posX());
Expand Down Expand Up @@ -2639,7 +2639,7 @@
if (!track.hasTPC()) {
continue; // skip tracks without TPC information
}
if (track.dcaZ() > 998) {

Check failure on line 2642 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
continue; // skip tracks without valid DCAz
}
dcazValues.push_back(track.dcaZ());
Expand Down Expand Up @@ -2727,15 +2727,15 @@
int counter10mm = 0;
for (auto const& d : dcazValues) {
double absD = std::abs(d);
if (absD > 0.01) {

Check failure on line 2730 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
counter100um++;
if (absD > 0.02) {

Check failure on line 2732 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
counter200um++;
if (absD > 0.05) {

Check failure on line 2734 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
counter500um++;
if (absD > 0.1) {

Check failure on line 2736 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
counter1mm++;
if (absD > 0.2) {

Check failure on line 2738 in PWGDQ/Core/VarManager.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
counter2mm++;
if (absD > 0.5) {
counter5mm++;
Expand Down Expand Up @@ -3923,6 +3923,11 @@
values[kQuadDCAabsXY] = std::sqrt((dca1XY * dca1XY + dca2XY * dca2XY) / 2.);
}
}
if constexpr ((pairType == kElectronMuon) && ((fillMap & ReducedTrackBarrel) > 0)) {
// DCA of the barrel (electron) leg; not filled in FillPairME since the mixed-event barrel track type has no DCA columns
values[kDCAxy1] = t1.dcaXY();
values[kDCAz1] = t1.dcaZ();
}
if (fgUsedVars[kPairPhiv]) {
values[kPairPhiv] = calculatePhiV<pairType>(t1, t2);
}
Expand Down
218 changes: 218 additions & 0 deletions PWGDQ/Tasks/dqEfficiency_withAssoc.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,223 @@ struct AnalysisPrefilterSelection {
PROCESS_SWITCH(AnalysisPrefilterSelection, processDummy, "Do nothing", true);
};

// Single-track selection on the barrel tracks after the prefilter decisions (which are not visible in the
// AnalysisTrackSelection histograms): fills track-level histograms separately for surviving and vetoed tracks,
// per track cut and per MC signal.
// NOTE: Histograms are filled per association, regardless of whether the association is the correct one.
struct AnalysisPostPrefilterTrackSelection {
OutputObj<THashList> fOutputList{"output"};

Configurable<std::string> fConfigTrackCuts{"cfgTrackCuts", "", "Comma separated list of track cuts (among those of analysis-track-selection) for which to fill histograms"};
Configurable<std::string> fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"};
Configurable<std::string> fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"};
Configurable<std::string> fConfigMCSignals{"cfgTrackMCSignals", "", "Comma separated list of MC signals"};
Configurable<std::string> fConfigMCSignalsJSON{"cfgTrackMCsignalsJSON", "", "Additional list of MC signals via JSON"};
Configurable<std::string> fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
Configurable<std::string> grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"};

Service<o2::ccdb::BasicCCDBManager> fCCDB{};

HistogramManager* fHistMan = nullptr;
std::vector<MCSignal*> fMCSignals;
std::vector<int> fCutBits; // bit positions of the requested cuts in the track-selection task cut list
std::vector<TString> fHistNamesSurvived; // [icut]
std::vector<TString> fHistNamesVetoed; // [icut]
std::vector<TString> fHistNamesMCSurvived; // [icut * nSignals + isig]
std::vector<TString> fHistNamesMCVetoed; // [icut * nSignals + isig]

int fCurrentRun = 0; // current run (needed to detect run changes for loading CCDB parameters)

void init(o2::framework::InitContext& context)
{
if (context.mOptions.get<bool>("processDummy")) {
return;
}
VarManager::SetDefaultVarNames();

fCurrentRun = 0;
TString trackCutsStr = fConfigTrackCuts.value;
std::unique_ptr<TObjArray> objArrayCuts(trackCutsStr.Tokenize(","));
if (objArrayCuts == nullptr || objArrayCuts->GetEntries() == 0) {
LOG(fatal) << " No track cuts specified! Check the cfgTrackCuts configurable";
}
// get the full list of cuts computed by the track-selection task and resolve the requested cuts to bit positions
std::string trackCuts;
getTaskOptionValue<std::string>(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<std::string>(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", trackCuts, false);
TString addTrackCutsStr = trackCuts;
if (addTrackCutsStr != "") {
std::vector<AnalysisCut*> addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data());
for (auto const& t : addTrackCuts) {
allTrackCutsStr += Form(",%s", t->GetName());
}
}
std::unique_ptr<TObjArray> objArrayAllCuts(allTrackCutsStr.Tokenize(","));
if (objArrayAllCuts == nullptr) {
LOG(fatal) << " Not getting any track cuts from the barrel-track-selection ";
}
std::vector<TString> cutNames;
for (int icut = 0; icut < objArrayCuts->GetEntries(); ++icut) {
TString cutName = objArrayCuts->At(icut)->GetName();
if (objArrayAllCuts->FindObject(cutName.Data()) == nullptr) {
LOG(fatal) << " Track cut " << cutName << " not among the cuts calculated by the track-selection task! ";
}
for (int jcut = 0; jcut < objArrayAllCuts->GetEntries(); ++jcut) {
if (cutName.CompareTo(objArrayAllCuts->At(jcut)->GetName()) == 0) {
fCutBits.push_back(jcut);
}
}
cutNames.push_back(cutName);
}

// Setting the MC signals
TString configSigNamesStr = fConfigMCSignals.value;
std::unique_ptr<TObjArray> sigNamesArray(configSigNamesStr.Tokenize(","));
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<MCSignal*> addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data());
for (auto const& mcIt : addMCSignals) {
if (mcIt->GetNProngs() != 1) { // NOTE: only 1 prong signals
continue;
}
fMCSignals.push_back(mcIt);
}
}

fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars);
fHistMan->SetUseDefaultVariableNames(kTRUE);
fHistMan->SetDefaultVarNames(dqefficiency_helpers::varNames(), dqefficiency_helpers::varUnits());

// Configure histogram classes for each track cut, separately for prefilter-surviving and prefilter-vetoed tracks,
// and for each requested MC signal (reconstructed tracks with MC truth)
TString histClasses = "";
for (auto const& cutName : cutNames) {
TString nameStr = Form("TrackBarrelPostPrefilter_%s", cutName.Data());
fHistNamesSurvived.push_back(nameStr);
histClasses += Form("%s;", nameStr.Data());
nameStr = Form("TrackBarrelPrefilterVetoed_%s", cutName.Data());
fHistNamesVetoed.push_back(nameStr);
histClasses += Form("%s;", nameStr.Data());
for (auto const& sig : fMCSignals) {
TString nameStr2 = Form("TrackBarrelPostPrefilter_%s_%s", cutName.Data(), sig->GetName());
fHistNamesMCSurvived.push_back(nameStr2);
histClasses += Form("%s;", nameStr2.Data());
nameStr2 = Form("TrackBarrelPrefilterVetoed_%s_%s", cutName.Data(), sig->GetName());
fHistNamesMCVetoed.push_back(nameStr2);
histClasses += Form("%s;", nameStr2.Data());
}
}

DefineHistograms(fHistMan, histClasses.Data(), fConfigAddTrackHistogram.value.data());
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());

fCCDB->setURL(fConfigCcdbUrl.value);
fCCDB->setCaching(true);
fCCDB->setLocalObjectValidityChecking();
}

template <uint32_t TEventFillMap, uint32_t TTrackFillMap, typename TEvents, typename TTracks, typename TTracksMC>
void runPostPrefilterTrackSelection(soa::Join<aod::ReducedTracksAssoc, aod::BarrelTrackCuts, aod::Prefilter> const& assocs,
TEvents const& events, TTracks const& /*tracks*/, TTracksMC const& tracksMC)
{
// load the magnetic field (needed to recompute the DCA with respect to the associated collision)
if (events.size() > 0 && fCurrentRun != events.begin().runNumber()) {
auto grpmag = fCCDB->getForTimeStamp<o2::parameters::GRPMagField>(grpmagPath, events.begin().timestamp());
if (grpmag != nullptr) {
VarManager::SetMagneticField(grpmag->getNominalL3Field());
} else {
LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", events.begin().timestamp());
}
fCurrentRun = events.begin().runNumber();
}

// Loop over associations
for (auto const& assoc : assocs) {
auto event = assoc.template reducedevent_as<TEvents>();
if (!event.isEventSelected_bit(0)) {
continue;
}

// check which of the requested cuts are fulfilled by this association and which of those are prefilter-vetoed
uint32_t selectedMap = 0;
uint32_t vetoMap = 0;
for (std::size_t icut = 0; icut < fCutBits.size(); ++icut) {
if (assoc.isBarrelSelected_bit(fCutBits[icut])) {
selectedMap |= (static_cast<uint32_t>(1) << icut);
if (!assoc.isBarrelSelectedPrefilter_bit(fCutBits[icut])) {
vetoMap |= (static_cast<uint32_t>(1) << icut);
}
}
}
if (selectedMap == 0) {
continue;
}

VarManager::ResetValues(0, VarManager::kNBarrelTrackVariables);
// fill event information which might be needed in histograms that combine track and event properties
VarManager::FillEvent<TEventFillMap>(event);
if (event.has_reducedMCevent()) {
VarManager::FillEvent<VarManager::ObjTypes::ReducedEventMC>(event.reducedMCevent());
}

auto track = assoc.template reducedtrack_as<TTracks>();
VarManager::FillTrack<TTrackFillMap>(track);
// compute quantities which depend on the associated collision, such as DCA
VarManager::FillTrackCollision<TTrackFillMap>(track, event);
if (track.has_reducedMCTrack()) {
VarManager::FillTrackMC(tracksMC, track.reducedMCTrack());
}

for (std::size_t icut = 0; icut < fCutBits.size(); ++icut) {
if (!(selectedMap & (static_cast<uint32_t>(1) << icut))) {
continue;
}
bool isVetoed = (vetoMap & (static_cast<uint32_t>(1) << icut)) > 0;
fHistMan->FillHistClass((isVetoed ? fHistNamesVetoed[icut] : fHistNamesSurvived[icut]).Data(), dqefficiency_helpers::varValues());
if (track.has_reducedMCTrack()) {
int isig = 0;
for (auto sig = fMCSignals.begin(); sig != fMCSignals.end(); sig++, isig++) {
if ((*sig)->CheckSignal(true, track.reducedMCTrack())) {
fHistMan->FillHistClass((isVetoed ? fHistNamesMCVetoed : fHistNamesMCSurvived)[icut * fMCSignals.size() + isig].Data(), dqefficiency_helpers::varValues());
}
}
}
} // end loop over cuts
} // end loop over associations
}

void processSkimmed(soa::Join<aod::ReducedTracksAssoc, aod::BarrelTrackCuts, aod::Prefilter> const& assocs, MyEventsSelected const& events, MyBarrelTracks const& tracks, ReducedMCEvents const& /*eventsMC*/, ReducedMCTracks const& tracksMC)
{
runPostPrefilterTrackSelection<gkEventFillMap, gkTrackFillMap>(assocs, events, tracks, tracksMC);
}
void processSkimmedWithCov(soa::Join<aod::ReducedTracksAssoc, aod::BarrelTrackCuts, aod::Prefilter> const& assocs, MyEventsVtxCovSelected const& events, MyBarrelTracksWithCov const& tracks, ReducedMCEvents const& /*eventsMC*/, ReducedMCTracks const& tracksMC)
{
runPostPrefilterTrackSelection<gkEventFillMapWithCov, gkTrackFillMapWithCov>(assocs, events, tracks, tracksMC);
}
void processDummy(MyEvents const&)
{
// do nothing
}

PROCESS_SWITCH(AnalysisPostPrefilterTrackSelection, processSkimmed, "Run barrel track post-prefilter selection on DQ skimmed track associations", false);
PROCESS_SWITCH(AnalysisPostPrefilterTrackSelection, processSkimmedWithCov, "Run barrel track post-prefilter selection on DQ skimmed track associations w/ cov matrix", false);
PROCESS_SWITCH(AnalysisPostPrefilterTrackSelection, processDummy, "Dummy function", 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, muon-muon and barrel-muon combinations
Expand Down Expand Up @@ -5183,6 +5400,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
adaptAnalysisTask<AnalysisTrackSelection>(cfgc),
adaptAnalysisTask<AnalysisMuonSelection>(cfgc),
adaptAnalysisTask<AnalysisPrefilterSelection>(cfgc),
adaptAnalysisTask<AnalysisPostPrefilterTrackSelection>(cfgc),
adaptAnalysisTask<AnalysisSameEventPairing>(cfgc),
adaptAnalysisTask<AnalysisAsymmetricPairing>(cfgc),
adaptAnalysisTask<AnalysisDileptonTrack>(cfgc)};
Expand Down
Loading