Skip to content

Commit 0a560dd

Browse files
authored
Merge pull request #1 from alibuild/alibot-cleanup-13822
Please consider the following formatting changes to #13822
2 parents 43319f3 + a2930c3 commit 0a560dd

File tree

2 files changed

+208
-197
lines changed

2 files changed

+208
-197
lines changed

Tools/PIDFeatureExtractor/PIDFeatureExtractor.cxx

Lines changed: 100 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,19 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
#include "Framework/runDataProcessing.h"
13-
#include "Framework/AnalysisTask.h"
12+
#include "Common/DataModel/EventSelection.h"
13+
#include "Common/DataModel/PIDResponse.h"
1414
#include "Common/DataModel/TrackSelectionTables.h"
15+
1516
#include "Framework/ASoAHelpers.h"
16-
#include "Common/DataModel/PIDResponse.h"
17-
#include "Common/DataModel/EventSelection.h"
17+
#include "Framework/AnalysisTask.h"
18+
#include "Framework/runDataProcessing.h"
19+
1820
#include "TFile.h"
1921
#include "TTree.h"
20-
#include <fstream>
22+
2123
#include <cmath>
24+
#include <fstream>
2225

2326
using namespace o2;
2427
using namespace o2::framework;
@@ -51,50 +54,50 @@ struct PIDFeatureExtractor {
5154
// KINEMATIC VARIABLES - Track momentum and position information
5255
// ============================================================================
5356

54-
int event_id; /// Unique identifier for each collision event
55-
int track_id; /// Track index within the event
57+
int event_id; /// Unique identifier for each collision event
58+
int track_id; /// Track index within the event
5659

5760
// Momentum components (in GeV/c)
58-
float px, py, pz; /// Cartesian momentum components
59-
float pt, p; /// Transverse momentum and total momentum
61+
float px, py, pz; /// Cartesian momentum components
62+
float pt, p; /// Transverse momentum and total momentum
6063

6164
// Angular variables
62-
float eta; /// Pseudorapidity
63-
float phi; /// Azimuthal angle
64-
float theta; /// Polar angle (calculated from eta)
65+
float eta; /// Pseudorapidity
66+
float phi; /// Azimuthal angle
67+
float theta; /// Polar angle (calculated from eta)
6568

6669
// Track properties
67-
int charge; /// Track charge (+1 or -1)
68-
int track_type; /// Type of track (e.g., 0=global, 1=TPC-only, etc.)
70+
int charge; /// Track charge (+1 or -1)
71+
int track_type; /// Type of track (e.g., 0=global, 1=TPC-only, etc.)
6972

7073
// ============================================================================
7174
// TPC VARIABLES - Time Projection Chamber PID information
7275
// ============================================================================
7376

74-
float tpc_signal; /// dE/dx energy loss in TPC (specific ionization)
77+
float tpc_signal; /// dE/dx energy loss in TPC (specific ionization)
7578

7679
// n-sigma values: standard deviations from expected energy loss for each particle
77-
float tpc_nsigma_pi; /// n-sigma for pion (π)
78-
float tpc_nsigma_ka; /// n-sigma for kaon (K)
79-
float tpc_nsigma_pr; /// n-sigma for proton (p)
80-
float tpc_nsigma_el; /// n-sigma for electron (e)
80+
float tpc_nsigma_pi; /// n-sigma for pion (π)
81+
float tpc_nsigma_ka; /// n-sigma for kaon (K)
82+
float tpc_nsigma_pr; /// n-sigma for proton (p)
83+
float tpc_nsigma_el; /// n-sigma for electron (e)
8184

8285
// Track quality variables
83-
int tpc_nclusters; /// Number of TPC clusters used in track fit
84-
float tpc_chi2; /// Chi-square per degree of freedom of TPC fit
86+
int tpc_nclusters; /// Number of TPC clusters used in track fit
87+
float tpc_chi2; /// Chi-square per degree of freedom of TPC fit
8588

8689
// ============================================================================
8790
// TOF VARIABLES - Time-Of-Flight PID information
8891
// ============================================================================
8992

90-
float tof_beta; /// β = v/c (velocity over speed of light)
91-
float tof_mass; /// Reconstructed mass from TOF measurement
93+
float tof_beta; /// β = v/c (velocity over speed of light)
94+
float tof_mass; /// Reconstructed mass from TOF measurement
9295

9396
// n-sigma values for TOF detection
94-
float tof_nsigma_pi; /// n-sigma for pion in TOF
95-
float tof_nsigma_ka; /// n-sigma for kaon in TOF
96-
float tof_nsigma_pr; /// n-sigma for proton in TOF
97-
float tof_nsigma_el; /// n-sigma for electron in TOF
97+
float tof_nsigma_pi; /// n-sigma for pion in TOF
98+
float tof_nsigma_ka; /// n-sigma for kaon in TOF
99+
float tof_nsigma_pr; /// n-sigma for proton in TOF
100+
float tof_nsigma_el; /// n-sigma for electron in TOF
98101

99102
// ============================================================================
100103
// BAYESIAN PID VARIABLES - Combined PID probabilities
@@ -113,22 +116,22 @@ struct PIDFeatureExtractor {
113116
// MONTE CARLO TRUTH INFORMATION - For simulated data
114117
// ============================================================================
115118

116-
int mc_pdg; /// PDG code of true particle (0 if no MC match)
117-
float mc_px, mc_py, mc_pz; /// True momentum components from simulation
119+
int mc_pdg; /// PDG code of true particle (0 if no MC match)
120+
float mc_px, mc_py, mc_pz; /// True momentum components from simulation
118121

119122
// ============================================================================
120123
// DETECTOR AVAILABILITY FLAGS
121124
// ============================================================================
122125

123-
bool has_tpc; /// Flag: track has TPC information
124-
bool has_tof; /// Flag: track has TOF information
126+
bool has_tpc; /// Flag: track has TPC information
127+
bool has_tof; /// Flag: track has TOF information
125128

126129
// ============================================================================
127130
// TRACK IMPACT PARAMETERS - Quality and background rejection
128131
// ============================================================================
129132

130-
float dca_xy; /// Distance of closest approach in xy-plane
131-
float dca_z; /// Distance of closest approach in z-direction
133+
float dca_xy; /// Distance of closest approach in xy-plane
134+
float dca_z; /// Distance of closest approach in z-direction
132135

133136
// ============================================================================
134137
// HISTOGRAM REGISTRY - Quality control histograms
@@ -172,7 +175,8 @@ struct PIDFeatureExtractor {
172175
* Called once at task startup. Creates ROOT TTree and CSV file headers,
173176
* and initializes all quality control histograms.
174177
*/
175-
void init(InitContext const&) {
178+
void init(InitContext const&)
179+
{
176180
std::string base = outputPath.value;
177181

178182
// ========================================================================
@@ -243,25 +247,24 @@ struct PIDFeatureExtractor {
243247
if (exportCSV) {
244248
csvFile.open((base + ".csv").c_str());
245249
// Write CSV header with all column names
246-
csvFile <<
247-
"event_id,track_id,px,py,pz,pt,p,eta,phi,theta,charge,track_type,"
248-
"tpc_signal,tpc_nsigma_pi,tpc_nsigma_ka,tpc_nsigma_pr,tpc_nsigma_el,"
249-
"tpc_nclusters,tpc_chi2,"
250-
"tof_beta,tof_mass,tof_nsigma_pi,tof_nsigma_ka,tof_nsigma_pr,tof_nsigma_el,"
251-
"bayes_prob_pi,bayes_prob_ka,bayes_prob_pr,bayes_prob_el,"
252-
"mc_pdg,mc_px,mc_py,mc_pz,has_tpc,has_tof,dca_xy,dca_z\n";
250+
csvFile << "event_id,track_id,px,py,pz,pt,p,eta,phi,theta,charge,track_type,"
251+
"tpc_signal,tpc_nsigma_pi,tpc_nsigma_ka,tpc_nsigma_pr,tpc_nsigma_el,"
252+
"tpc_nclusters,tpc_chi2,"
253+
"tof_beta,tof_mass,tof_nsigma_pi,tof_nsigma_ka,tof_nsigma_pr,tof_nsigma_el,"
254+
"bayes_prob_pi,bayes_prob_ka,bayes_prob_pr,bayes_prob_el,"
255+
"mc_pdg,mc_px,mc_py,mc_pz,has_tpc,has_tof,dca_xy,dca_z\n";
253256
}
254257

255258
// ========================================================================
256259
// HISTOGRAM SETUP - Quality Control Plots
257260
// ========================================================================
258261

259262
// Define histogram axes with binning
260-
const AxisSpec axisPt{200, 0, 10, "pT"}; // 200 bins, 0-10 GeV/c
261-
const AxisSpec axisEta{60, -1.5, 1.5, "eta"}; // 60 bins, -1.5 to 1.5
262-
const AxisSpec axisdEdx{300, 0, 300, "dE/dx"}; // 300 bins, 0-300
263-
const AxisSpec axisBeta{120, 0, 1.2, "beta"}; // 120 bins, 0 to 1.2
264-
const AxisSpec axisMass{100, -0.2, 2.0, "mass"}; // 100 bins, -0.2 to 2.0 GeV/c²
263+
const AxisSpec axisPt{200, 0, 10, "pT"}; // 200 bins, 0-10 GeV/c
264+
const AxisSpec axisEta{60, -1.5, 1.5, "eta"}; // 60 bins, -1.5 to 1.5
265+
const AxisSpec axisdEdx{300, 0, 300, "dE/dx"}; // 300 bins, 0-300
266+
const AxisSpec axisBeta{120, 0, 1.2, "beta"}; // 120 bins, 0 to 1.2
267+
const AxisSpec axisMass{100, -0.2, 2.0, "mass"}; // 100 bins, -0.2 to 2.0 GeV/c²
265268

266269
// Add histograms to registry
267270
histos.add("QC/nTracks", "Tracks", kTH1F, {{10000, 0, 100000}});
@@ -291,15 +294,16 @@ struct PIDFeatureExtractor {
291294
*
292295
* Likelihood: L_i = exp(-0.5 * (ns_TPC_i² + ns_TOF_i²))
293296
*/
294-
void computeBayesianPID(float nsTPC[4], float nsTOF[4], float pri[4], float out[4]) {
297+
void computeBayesianPID(float nsTPC[4], float nsTOF[4], float pri[4], float out[4])
298+
{
295299
float sum = 0;
296300

297301
// Calculate likelihood for each particle species
298302
for (int i = 0; i < 4; i++) {
299303
// Gaussian likelihood: exp(-0.5 * chi²)
300304
// Handle invalid TOF values (NaN) by replacing with 0 contribution
301-
float l = std::exp(-0.5f * (nsTPC[i]*nsTPC[i] +
302-
(std::isfinite(nsTOF[i]) ? nsTOF[i]*nsTOF[i] : 0.f)));
305+
float l = std::exp(-0.5f * (nsTPC[i] * nsTPC[i] +
306+
(std::isfinite(nsTOF[i]) ? nsTOF[i] * nsTOF[i] : 0.f)));
303307

304308
// Apply prior probability and accumulate
305309
out[i] = l * pri[i];
@@ -330,16 +334,16 @@ struct PIDFeatureExtractor {
330334
void process(
331335
aod::Collision const& collision,
332336
soa::Join<
333-
aod::Tracks, // Base track properties
334-
aod::TracksExtra, // Extended track info
335-
aod::TracksDCA, // Impact parameters (DCA)
336-
aod::pidTPCPi, aod::pidTPCKa, aod::pidTPCPr, // TPC PID for pion, kaon, proton
337-
aod::pidTPCEl, // TPC PID for electron
338-
aod::pidTOFPi, aod::pidTOFKa, aod::pidTOFPr, // TOF PID for pion, kaon, proton
339-
aod::pidTOFEl, // TOF PID for electron
340-
aod::pidTOFmass, aod::pidTOFbeta, // TOF mass and beta
341-
aod::McTrackLabels // MC truth matching
342-
> const& tracks,
337+
aod::Tracks, // Base track properties
338+
aod::TracksExtra, // Extended track info
339+
aod::TracksDCA, // Impact parameters (DCA)
340+
aod::pidTPCPi, aod::pidTPCKa, aod::pidTPCPr, // TPC PID for pion, kaon, proton
341+
aod::pidTPCEl, // TPC PID for electron
342+
aod::pidTOFPi, aod::pidTOFKa, aod::pidTOFPr, // TOF PID for pion, kaon, proton
343+
aod::pidTOFEl, // TOF PID for electron
344+
aod::pidTOFmass, aod::pidTOFbeta, // TOF mass and beta
345+
aod::McTrackLabels // MC truth matching
346+
> const& tracks,
343347
aod::McParticles const& mcParticles)
344348
{
345349
// Use static counter to maintain event numbering across process calls
@@ -355,8 +359,10 @@ struct PIDFeatureExtractor {
355359
// ====================================================================
356360
// TRACK SELECTION - Apply kinematic cuts
357361
// ====================================================================
358-
if (t.pt() < ptMin || t.pt() > ptMax) continue; // Apply pT cut
359-
if (t.eta() < etaMin || t.eta() > etaMax) continue; // Apply eta cut
362+
if (t.pt() < ptMin || t.pt() > ptMax)
363+
continue; // Apply pT cut
364+
if (t.eta() < etaMin || t.eta() > etaMax)
365+
continue; // Apply eta cut
360366

361367
track_id = idx++;
362368

@@ -372,22 +378,22 @@ struct PIDFeatureExtractor {
372378
phi = t.phi();
373379
// Calculate polar angle from pseudorapidity: θ = 2*arctan(exp(-η))
374380
theta = 2.f * atanf(expf(-eta));
375-
charge = t.sign(); // Track charge
376-
track_type = t.trackType(); // Track categorization
381+
charge = t.sign(); // Track charge
382+
track_type = t.trackType(); // Track categorization
377383

378384
// ====================================================================
379385
// EXTRACT TPC INFORMATION
380386
// ====================================================================
381387
has_tpc = t.hasTPC();
382388
if (has_tpc) {
383389
// TPC has valid measurement
384-
tpc_signal = t.tpcSignal(); // dE/dx specific ionization
385-
tpc_nsigma_pi = t.tpcNSigmaPi(); // Deviation from pion hypothesis
386-
tpc_nsigma_ka = t.tpcNSigmaKa(); // Deviation from kaon hypothesis
387-
tpc_nsigma_pr = t.tpcNSigmaPr(); // Deviation from proton hypothesis
388-
tpc_nsigma_el = t.tpcNSigmaEl(); // Deviation from electron hypothesis
389-
tpc_nclusters = t.tpcNClsFound(); // Quality: number of clusters
390-
tpc_chi2 = t.tpcChi2NCl(); // Quality: fit chi-square
390+
tpc_signal = t.tpcSignal(); // dE/dx specific ionization
391+
tpc_nsigma_pi = t.tpcNSigmaPi(); // Deviation from pion hypothesis
392+
tpc_nsigma_ka = t.tpcNSigmaKa(); // Deviation from kaon hypothesis
393+
tpc_nsigma_pr = t.tpcNSigmaPr(); // Deviation from proton hypothesis
394+
tpc_nsigma_el = t.tpcNSigmaEl(); // Deviation from electron hypothesis
395+
tpc_nclusters = t.tpcNClsFound(); // Quality: number of clusters
396+
tpc_chi2 = t.tpcChi2NCl(); // Quality: fit chi-square
391397
} else {
392398
// TPC has no valid measurement - set sentinel values
393399
tpc_signal = tpc_nsigma_pi = tpc_nsigma_ka = tpc_nsigma_pr = tpc_nsigma_el = -999;
@@ -401,12 +407,12 @@ struct PIDFeatureExtractor {
401407
has_tof = t.hasTOF();
402408
if (has_tof) {
403409
// TOF has valid measurement
404-
tof_beta = t.beta(); // Velocity over c
405-
tof_mass = t.mass(); // Reconstructed mass
406-
tof_nsigma_pi = t.tofNSigmaPi(); // Deviation from pion hypothesis
407-
tof_nsigma_ka = t.tofNSigmaKa(); // Deviation from kaon hypothesis
408-
tof_nsigma_pr = t.tofNSigmaPr(); // Deviation from proton hypothesis
409-
tof_nsigma_el = t.tofNSigmaEl(); // Deviation from electron hypothesis
410+
tof_beta = t.beta(); // Velocity over c
411+
tof_mass = t.mass(); // Reconstructed mass
412+
tof_nsigma_pi = t.tofNSigmaPi(); // Deviation from pion hypothesis
413+
tof_nsigma_ka = t.tofNSigmaKa(); // Deviation from kaon hypothesis
414+
tof_nsigma_pr = t.tofNSigmaPr(); // Deviation from proton hypothesis
415+
tof_nsigma_el = t.tofNSigmaEl(); // Deviation from electron hypothesis
410416
} else {
411417
// TOF has no valid measurement - set sentinel values
412418
tof_beta = tof_mass = -999;
@@ -416,15 +422,15 @@ struct PIDFeatureExtractor {
416422
// ====================================================================
417423
// EXTRACT IMPACT PARAMETERS (track quality)
418424
// ====================================================================
419-
dca_xy = t.dcaXY(); // Distance of closest approach in transverse plane
420-
dca_z = t.dcaZ(); // Distance of closest approach along beam axis
425+
dca_xy = t.dcaXY(); // Distance of closest approach in transverse plane
426+
dca_z = t.dcaZ(); // Distance of closest approach along beam axis
421427

422428
// ====================================================================
423429
// COMPUTE BAYESIAN PID
424430
// ====================================================================
425431
float arrTPC[4] = {tpc_nsigma_pi, tpc_nsigma_ka, tpc_nsigma_pr, tpc_nsigma_el};
426432
float arrTOF[4] = {tof_nsigma_pi, tof_nsigma_ka, tof_nsigma_pr, tof_nsigma_el};
427-
float priors[4] = {1.f, 0.2f, 0.1f, 0.05f}; // Prior prob: π, K, p, e
433+
float priors[4] = {1.f, 0.2f, 0.1f, 0.05f}; // Prior prob: π, K, p, e
428434
float probs[4];
429435

430436
// Compute combined PID probabilities
@@ -440,8 +446,8 @@ struct PIDFeatureExtractor {
440446
// Safely access MC particle information with existence check
441447
if (t.has_mcParticle()) {
442448
auto mc = t.mcParticle();
443-
mc_pdg = mc.pdgCode(); // Particle identifier code
444-
mc_px = mc.px(); // True momentum components
449+
mc_pdg = mc.pdgCode(); // Particle identifier code
450+
mc_px = mc.px(); // True momentum components
445451
mc_py = mc.py();
446452
mc_pz = mc.pz();
447453
} else {
@@ -455,7 +461,8 @@ struct PIDFeatureExtractor {
455461
// ====================================================================
456462

457463
// Write to ROOT TTree
458-
if (exportROOT) featureTree->Fill();
464+
if (exportROOT)
465+
featureTree->Fill();
459466

460467
// Write to CSV file
461468
if (exportCSV) {
@@ -476,12 +483,13 @@ struct PIDFeatureExtractor {
476483
// ====================================================================
477484
// FILL QUALITY CONTROL HISTOGRAMS
478485
// ====================================================================
479-
histos.fill(HIST("QC/nTracks"), 1); // Count total tracks processed
480-
histos.fill(HIST("QC/pt"), pt); // pT distribution
481-
histos.fill(HIST("QC/eta"), eta); // eta distribution
486+
histos.fill(HIST("QC/nTracks"), 1); // Count total tracks processed
487+
histos.fill(HIST("QC/pt"), pt); // pT distribution
488+
histos.fill(HIST("QC/eta"), eta); // eta distribution
482489

483490
// TPC dE/dx vs pT (only if TPC measurement exists)
484-
if (has_tpc) histos.fill(HIST("QC/tpc_dEdx_vs_pt"), pt, tpc_signal);
491+
if (has_tpc)
492+
histos.fill(HIST("QC/tpc_dEdx_vs_pt"), pt, tpc_signal);
485493

486494
// TOF beta and mass vs momentum (only if TOF measurement exists)
487495
if (has_tof) {
@@ -500,7 +508,8 @@ struct PIDFeatureExtractor {
500508
*
501509
* Called at task completion. Writes TTree to file and closes all output files.
502510
*/
503-
void finalize() {
511+
void finalize()
512+
{
504513
if (exportROOT) {
505514
// Write TTree to ROOT file and close
506515
outputFile->cd();
@@ -524,6 +533,8 @@ struct PIDFeatureExtractor {
524533
* This function creates and registers the PIDFeatureExtractor task
525534
* into the O2 data processing workflow.
526535
*/
527-
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) {
536+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
537+
{
528538
return WorkflowSpec{adaptAnalysisTask<PIDFeatureExtractor>(cfgc)};
529-
}
539+
}
540+

0 commit comments

Comments
 (0)