1+ // Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+ // See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+ // All rights not expressly granted are reserved.
4+ //
5+ // This software is distributed under the terms of the GNU General Public
6+ // License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+ //
8+ // In applying this license CERN does not waive the privileges and immunities
9+ // granted to it by virtue of its status as an Intergovernmental Organization
10+ // or submit itself to any jurisdiction.
11+
112#include " Framework/runDataProcessing.h"
213#include " Framework/AnalysisTask.h"
314#include " Common/DataModel/TrackSelectionTables.h"
@@ -26,59 +37,59 @@ struct PIDFeatureExtractor {
2637 // ============================================================================
2738 // OUTPUT OBJECTS - File and data structures for feature storage
2839 // ============================================================================
29-
40+
3041 // / Output ROOT file for storing the TTree with extracted features
3142 std::unique_ptr<TFile> outputFile;
32-
43+
3344 // / TTree storing all extracted features for each track
3445 std::unique_ptr<TTree> featureTree;
35-
46+
3647 // / CSV output stream for exporting features in comma-separated format
3748 std::ofstream csvFile;
3849
3950 // ============================================================================
4051 // KINEMATIC VARIABLES - Track momentum and position information
4152 // ============================================================================
42-
53+
4354 int event_id; // / Unique identifier for each collision event
4455 int track_id; // / Track index within the event
45-
56+
4657 // Momentum components (in GeV/c)
4758 float px, py, pz; // / Cartesian momentum components
4859 float pt, p; // / Transverse momentum and total momentum
49-
60+
5061 // Angular variables
5162 float eta; // / Pseudorapidity
5263 float phi; // / Azimuthal angle
5364 float theta; // / Polar angle (calculated from eta)
54-
65+
5566 // Track properties
5667 int charge; // / Track charge (+1 or -1)
5768 int track_type; // / Type of track (e.g., 0=global, 1=TPC-only, etc.)
5869
5970 // ============================================================================
6071 // TPC VARIABLES - Time Projection Chamber PID information
6172 // ============================================================================
62-
73+
6374 float tpc_signal; // / dE/dx energy loss in TPC (specific ionization)
64-
75+
6576 // n-sigma values: standard deviations from expected energy loss for each particle
6677 float tpc_nsigma_pi; // / n-sigma for pion (π)
6778 float tpc_nsigma_ka; // / n-sigma for kaon (K)
6879 float tpc_nsigma_pr; // / n-sigma for proton (p)
6980 float tpc_nsigma_el; // / n-sigma for electron (e)
70-
81+
7182 // Track quality variables
7283 int tpc_nclusters; // / Number of TPC clusters used in track fit
7384 float tpc_chi2; // / Chi-square per degree of freedom of TPC fit
7485
7586 // ============================================================================
7687 // TOF VARIABLES - Time-Of-Flight PID information
7788 // ============================================================================
78-
89+
7990 float tof_beta; // / β = v/c (velocity over speed of light)
8091 float tof_mass; // / Reconstructed mass from TOF measurement
81-
92+
8293 // n-sigma values for TOF detection
8394 float tof_nsigma_pi; // / n-sigma for pion in TOF
8495 float tof_nsigma_ka; // / n-sigma for kaon in TOF
@@ -88,7 +99,7 @@ struct PIDFeatureExtractor {
8899 // ============================================================================
89100 // BAYESIAN PID VARIABLES - Combined PID probabilities
90101 // ============================================================================
91-
102+
92103 // / Bayesian probability that track is a pion (probability sum = 1.0)
93104 float bayes_prob_pi;
94105 // / Bayesian probability that track is a kaon
@@ -101,60 +112,60 @@ struct PIDFeatureExtractor {
101112 // ============================================================================
102113 // MONTE CARLO TRUTH INFORMATION - For simulated data
103114 // ============================================================================
104-
115+
105116 int mc_pdg; // / PDG code of true particle (0 if no MC match)
106117 float mc_px, mc_py, mc_pz; // / True momentum components from simulation
107118
108119 // ============================================================================
109120 // DETECTOR AVAILABILITY FLAGS
110121 // ============================================================================
111-
122+
112123 bool has_tpc; // / Flag: track has TPC information
113124 bool has_tof; // / Flag: track has TOF information
114125
115126 // ============================================================================
116127 // TRACK IMPACT PARAMETERS - Quality and background rejection
117128 // ============================================================================
118-
129+
119130 float dca_xy; // / Distance of closest approach in xy-plane
120131 float dca_z; // / Distance of closest approach in z-direction
121132
122133 // ============================================================================
123134 // HISTOGRAM REGISTRY - Quality control histograms
124135 // ============================================================================
125-
136+
126137 // / Registry for quality control histograms
127138 HistogramRegistry histos{" histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
128139
129140 // ============================================================================
130141 // CONFIGURABLE PARAMETERS - User-adjustable settings
131142 // ============================================================================
132-
143+
133144 // / Base path and filename for output files (without extension)
134145 Configurable<std::string> outputPath{" outputPath" , " pid_features" , " Output file base" };
135-
146+
136147 // / Enable CSV export of features
137148 Configurable<bool > exportCSV{" exportCSV" , true , " Export CSV" };
138-
149+
139150 // / Enable ROOT file export of features
140151 Configurable<bool > exportROOT{" exportROOT" , true , " Export ROOT" };
141-
152+
142153 // / Minimum pseudorapidity cut for track selection
143154 Configurable<float > etaMin{" etaMin" , -1 .5f , " Minimum eta" };
144-
155+
145156 // / Maximum pseudorapidity cut for track selection
146157 Configurable<float > etaMax{" etaMax" , 1 .5f , " Maximum eta" };
147-
158+
148159 // / Minimum transverse momentum cut (GeV/c)
149160 Configurable<float > ptMin{" ptMin" , 0 .1f , " Minimum pT" };
150-
161+
151162 // / Maximum transverse momentum cut (GeV/c)
152163 Configurable<float > ptMax{" ptMax" , 20 .0f , " Maximum pT" };
153164
154165 // ============================================================================
155166 // INITIALIZATION FUNCTION
156167 // ============================================================================
157-
168+
158169 /* *
159170 * @brief Initialize output files and histograms
160171 *
@@ -163,14 +174,14 @@ struct PIDFeatureExtractor {
163174 */
164175 void init (InitContext const &) {
165176 std::string base = outputPath.value ;
166-
177+
167178 // ========================================================================
168179 // ROOT OUTPUT SETUP
169180 // ========================================================================
170181 if (exportROOT) {
171182 // Create ROOT file for storing the TTree
172183 outputFile = std::make_unique<TFile>((base + " .root" ).c_str (), " RECREATE" );
173-
184+
174185 // Create TTree with descriptive name and title
175186 featureTree = std::make_unique<TTree>(" pid_features" , " PID features" );
176187
@@ -220,7 +231,7 @@ struct PIDFeatureExtractor {
220231 // Create branches for DETECTOR FLAGS
221232 featureTree->Branch (" has_tpc" , &has_tpc);
222233 featureTree->Branch (" has_tof" , &has_tof);
223-
234+
224235 // Create branches for IMPACT PARAMETERS
225236 featureTree->Branch (" dca_xy" , &dca_xy);
226237 featureTree->Branch (" dca_z" , &dca_z);
@@ -244,7 +255,7 @@ struct PIDFeatureExtractor {
244255 // ========================================================================
245256 // HISTOGRAM SETUP - Quality Control Plots
246257 // ========================================================================
247-
258+
248259 // Define histogram axes with binning
249260 const AxisSpec axisPt{200 , 0 , 10 , " pT" }; // 200 bins, 0-10 GeV/c
250261 const AxisSpec axisEta{60 , -1.5 , 1.5 , " eta" }; // 60 bins, -1.5 to 1.5
@@ -264,7 +275,7 @@ struct PIDFeatureExtractor {
264275 // ============================================================================
265276 // BAYESIAN PID CALCULATION FUNCTION
266277 // ============================================================================
267-
278+
268279 /* *
269280 * @brief Compute Bayesian probabilities combining TPC and TOF information
270281 *
@@ -282,19 +293,19 @@ struct PIDFeatureExtractor {
282293 */
283294 void computeBayesianPID (float nsTPC[4 ], float nsTOF[4 ], float pri[4 ], float out[4 ]) {
284295 float sum = 0 ;
285-
296+
286297 // Calculate likelihood for each particle species
287298 for (int i = 0 ; i < 4 ; i++) {
288299 // Gaussian likelihood: exp(-0.5 * chi²)
289300 // Handle invalid TOF values (NaN) by replacing with 0 contribution
290- float l = std::exp (-0 .5f * (nsTPC[i]*nsTPC[i] +
301+ float l = std::exp (-0 .5f * (nsTPC[i]*nsTPC[i] +
291302 (std::isfinite (nsTOF[i]) ? nsTOF[i]*nsTOF[i] : 0 .f )));
292-
303+
293304 // Apply prior probability and accumulate
294305 out[i] = l * pri[i];
295306 sum += out[i];
296307 }
297-
308+
298309 // Normalize probabilities so they sum to 1.0
299310 for (int i = 0 ; i < 4 ; i++) {
300311 out[i] = sum > 0 ? out[i] / sum : 0 .f ;
@@ -304,7 +315,7 @@ struct PIDFeatureExtractor {
304315 // ============================================================================
305316 // MAIN PROCESSING FUNCTION
306317 // ============================================================================
307-
318+
308319 /* *
309320 * @brief Process collision and track data, extract PID features
310321 *
@@ -340,15 +351,15 @@ struct PIDFeatureExtractor {
340351 // TRACK LOOP - Process each track in the event
341352 // ======================================================================
342353 for (auto & t : tracks) {
343-
354+
344355 // ====================================================================
345356 // TRACK SELECTION - Apply kinematic cuts
346357 // ====================================================================
347358 if (t.pt () < ptMin || t.pt () > ptMax) continue ; // Apply pT cut
348359 if (t.eta () < etaMin || t.eta () > etaMax) continue ; // Apply eta cut
349-
360+
350361 track_id = idx++;
351-
362+
352363 // ====================================================================
353364 // EXTRACT KINEMATIC VARIABLES
354365 // ====================================================================
@@ -415,7 +426,7 @@ struct PIDFeatureExtractor {
415426 float arrTOF[4 ] = {tof_nsigma_pi, tof_nsigma_ka, tof_nsigma_pr, tof_nsigma_el};
416427 float priors[4 ] = {1 .f , 0 .2f , 0 .1f , 0 .05f }; // Prior prob: π, K, p, e
417428 float probs[4 ];
418-
429+
419430 // Compute combined PID probabilities
420431 computeBayesianPID (arrTPC, arrTOF, priors, probs);
421432 bayes_prob_pi = probs[0 ];
@@ -442,10 +453,10 @@ struct PIDFeatureExtractor {
442453 // ====================================================================
443454 // WRITE OUTPUT
444455 // ====================================================================
445-
456+
446457 // Write to ROOT TTree
447458 if (exportROOT) featureTree->Fill ();
448-
459+
449460 // Write to CSV file
450461 if (exportCSV) {
451462 csvFile << event_id << " ," << track_id << " ,"
@@ -468,10 +479,10 @@ struct PIDFeatureExtractor {
468479 histos.fill (HIST (" QC/nTracks" ), 1 ); // Count total tracks processed
469480 histos.fill (HIST (" QC/pt" ), pt); // pT distribution
470481 histos.fill (HIST (" QC/eta" ), eta); // eta distribution
471-
482+
472483 // TPC dE/dx vs pT (only if TPC measurement exists)
473484 if (has_tpc) histos.fill (HIST (" QC/tpc_dEdx_vs_pt" ), pt, tpc_signal);
474-
485+
475486 // TOF beta and mass vs momentum (only if TOF measurement exists)
476487 if (has_tof) {
477488 histos.fill (HIST (" QC/tof_beta_vs_p" ), p, tof_beta);
@@ -483,7 +494,7 @@ struct PIDFeatureExtractor {
483494 // ============================================================================
484495 // FINALIZATION FUNCTION
485496 // ============================================================================
486-
497+
487498 /* *
488499 * @brief Clean up and finalize output files
489500 *
0 commit comments