1414// / \author Giorgio Alberto Lucia (giorgio.alberto.lucia@cern.ch)
1515// /
1616
17+ #include " PWGLF/DataModel/EPCalibrationTables.h"
1718#include " PWGLF/DataModel/LFSlimNucleiTables.h"
1819#include " PWGLF/Utils/nucleiUtils.h"
1920
20- #include " Common/CCDB/EventSelectionParams.h"
21+ #include " Common/Core/EventPlaneHelper.h"
22+ #include " Common/Core/PID/PIDTOF.h"
23+ #include " Common/Core/RecoDecay.h"
24+ #include " Common/Core/TrackSelection.h"
2125#include " Common/Core/Zorro.h"
26+ #include " Common/Core/ZorroSummary.h"
2227#include " Common/Core/trackUtilities.h"
2328#include " Common/DataModel/Centrality.h"
2429#include " Common/DataModel/EventSelection.h"
30+ #include " Common/DataModel/Multiplicity.h"
31+ #include " Common/DataModel/PIDResponseITS.h"
2532#include " Common/DataModel/PIDResponseTOF.h"
2633#include " Common/DataModel/PIDResponseTPC.h"
34+ #include " Common/DataModel/Qvectors.h"
35+ #include " Common/DataModel/TrackSelectionTables.h"
36+ #include " Common/TableProducer/PID/pidTOFBase.h"
2737#include " Common/Tools/TrackTuner.h"
2838
29- #include < CCDB/BasicCCDBManager.h>
30- #include < DataFormatsParameters/GRPMagField.h>
31- #include < DetectorsBase/MatLayerCylSet.h>
32- #include < DetectorsBase/Propagator.h>
33- #include < Framework/AnalysisDataModel.h>
34- #include < Framework/AnalysisHelpers.h>
35- #include < Framework/AnalysisTask.h>
36- #include < Framework/Array2D.h>
37- #include < Framework/Configurable.h>
38- #include < Framework/HistogramRegistry.h>
39- #include < Framework/HistogramSpec.h>
40- #include < Framework/InitContext.h>
41- #include < Framework/OutputObjHeader.h>
42- #include < Framework/StaticFor.h>
43- #include < Framework/runDataProcessing.h>
44- #include < ReconstructionDataFormats/DCA.h>
45- #include < ReconstructionDataFormats/TrackParametrizationWithError.h>
46-
47- #include < TH1.h>
48- #include < TH2.h>
49- #include < TMCProcess.h>
50- #include < TRandom3.h>
51-
52- #include < fmt/format.h>
53-
54- #include < GPUROOTCartesianFwd.h>
39+ #include " CCDB/BasicCCDBManager.h"
40+ #include " DataFormatsParameters/GRPMagField.h"
41+ #include " DataFormatsParameters/GRPObject.h"
42+ #include " DetectorsBase/GeometryManager.h"
43+ #include " DetectorsBase/Propagator.h"
44+ #include " Framework/ASoAHelpers.h"
45+ #include " Framework/AnalysisDataModel.h"
46+ #include " Framework/AnalysisTask.h"
47+ #include " Framework/HistogramRegistry.h"
48+ #include " Framework/StaticFor.h"
49+ #include " Framework/runDataProcessing.h"
50+ #include " MathUtils/BetheBlochAleph.h"
51+ #include " ReconstructionDataFormats/Track.h"
52+
53+ #include " Math/Vector4D.h"
54+ #include " TMCProcess.h"
55+ #include " TRandom3.h"
5556
5657#include < algorithm>
5758#include < array>
5859#include < cmath>
59- #include < cstddef>
60- #include < cstdint>
6160#include < memory>
62- #include < stdexcept>
6361#include < string>
6462#include < vector>
6563
@@ -78,10 +76,11 @@ enum trackQuality {
7876 kNCrossedRowsCut = 5 ,
7977 kTpcChi2Cut = 6 ,
8078 kItsChi2Cut = 7 ,
81- kNtrackQuality = 8
79+ kDcaCuts = 8 ,
80+ kNtrackQuality = 9
8281};
8382
84- std::array<std::string, trackQuality::kNtrackQuality > trackQualityLabels{" All" , " #eta cut" , " #it{p}_{TPC}^{min} cut" , " #it{N}_{cls}^{ITS} cut" , " #it{N}_{cls}^{TPC} cut" , " Crossed rows cut" , " #chi^{2}_{TPC} cut" , " #chi^{2}_{ITS} cut" };
83+ std::array<std::string, trackQuality::kNtrackQuality > trackQualityLabels{" All" , " #eta cut" , " #it{p}_{TPC}^{min} cut" , " #it{N}_{cls}^{ITS} cut" , " #it{N}_{cls}^{TPC} cut" , " Crossed rows cut" , " #chi^{2}_{TPC} cut" , " #chi^{2}_{ITS} cut" , " DCA cuts " };
8584
8685} // namespace
8786
@@ -125,6 +124,8 @@ struct nucleiQC {
125124 Configurable<float > cfgCutNclusCrossedRowsTPC{" cfgCutNclusCrossedRowsTPC" , 70 , " Minimum number of TPC clusters crossed rows" };
126125 Configurable<float > cfgCutChi2PerClusterTPC{" cfgCutChi2PerClusterTPC" , 4 .f , " Maximum chi2 per TPC cluster" };
127126 Configurable<float > cfgCutChi2PerClusterITS{" cfgCutChi2PerClusterITS" , 36 .f , " Maximum chi2 per ITS cluster" };
127+ Configurable<float > cfgCutDCAxy{" cfgCutDCAxy" , 10 .f , " Maximum DCA in the transverse plane" };
128+ Configurable<float > cfgCutDCAz{" cfgCutDCAz" , 10 .f , " Maximum DCA in the longitudinal direction" };
128129
129130 Configurable<LabeledArray<double >> cfgNsigmaTPC{" cfgNsigmaTPC" , {nuclei::nSigmaTPCdefault[0 ], nuclei::Species::kNspecies , 2 , nuclei::names, nuclei::nSigmaConfigName}, " TPC nsigma selection for light nuclei" };
130131 Configurable<LabeledArray<double >> cfgNsigmaTOF{" cfgNsigmaTOF" , {nuclei::nSigmaTOFdefault[0 ], nuclei::Species::kNspecies , 2 , nuclei::names, nuclei::nSigmaConfigName}, " TPC nsigma selection for light nuclei" };
@@ -142,6 +143,7 @@ struct nucleiQC {
142143 {" hEventSelections" , " Event selections; Selection step; Counts" , {HistType::kTH1D , {{nuclei::evSel::kNevSels + 1 , -0 .5f , static_cast <float >(nuclei::evSel::kNevSels ) + 0 .5f }}}},
143144 {" hVtxZBefore" , " Vertex distribution in Z before selections;Z (cm)" , {HistType::kTH1F , {{400 , -20.0 , 20.0 }}}},
144145 {" hVtxZ" , " Vertex distribution in Z;Z (cm)" , {HistType::kTH1F , {{400 , -20.0 , 20.0 }}}},
146+ {" hCentrality" , " Centrality distribution;Centrality (%)" , {HistType::kTH1F , {{100 , 0.0 , 100.0 }}}},
145147 {" hFailCentrality" , " 0: all the times the centrality filling function is called - 1: each time it fails ; Bool" , {HistType::kTH1F , {{2 , -0.5 , 1.50 }}}},
146148 {" hTrackTunedTracks" , " " , {HistType::kTH1F , {{1 , 0.5 , 1.5 }}}},
147149 },
@@ -252,8 +254,8 @@ struct nucleiQC {
252254 LOGF (info, " Retrieved GRP for timestamp %ull (%i) with magnetic field of %1.2f kZG" , timestamp, mRunNumber , mBz );
253255 }
254256
255- template <int iSpecies, typename Ttrack>
256- bool trackSelection (const Ttrack& track)
257+ template <int iSpecies, typename Ttrack, typename Tcollision >
258+ bool trackSelection (const Ttrack& track, const Tcollision& collision )
257259 {
258260 mHistograms .fill (HIST (nuclei::cNames[iSpecies]) + HIST (" /hTrackQuality" ), track.sign () * track.pt (), trackQuality::kNoCuts );
259261
@@ -285,6 +287,16 @@ struct nucleiQC {
285287 return false ;
286288 mHistograms .fill (HIST (nuclei::cNames[iSpecies]) + HIST (" /hTrackQuality" ), track.sign () * track.pt (), trackQuality::kItsChi2Cut );
287289
290+ const o2::math_utils::Point3D<float > collisionVertex{collision.posX (), collision.posY (), collision.posZ ()};
291+ mDcaInfoCov .set (999 , 999 , 999 , 999 , 999 );
292+ setTrackParCov (track, mTrackParCov );
293+ mTrackParCov .setPID (track.pidForTracking ());
294+ std::array<float , 2 > dcaInfo;
295+ o2::base::Propagator::Instance ()->propagateToDCA (collisionVertex, mTrackParCov , mBz , 2 .f , static_cast <o2::base::Propagator::MatCorrType>(cfgMaterialCorrection.value ), &dcaInfo);
296+ if (std::abs (dcaInfo[0 ]) > cfgCutDCAxy || std::abs (dcaInfo[1 ]) > cfgCutDCAz)
297+ return false ;
298+ mHistograms .fill (HIST (nuclei::cNames[iSpecies]) + HIST (" /hTrackQuality" ), track.sign () * track.pt (), trackQuality::kDcaCuts );
299+
288300 return true ;
289301 }
290302
@@ -293,7 +305,7 @@ struct nucleiQC {
293305 {
294306 constexpr int kIndex = iSpecies;
295307 if (!nuclei::checkSpeciesValidity (kIndex ))
296- std::runtime_error (" species contains invalid nucleus kIndex" );
308+ throw std::runtime_error (" species contains invalid nucleus kIndex" );
297309
298310 float centrality = nuclei::getCentrality (collision, cfgCentralityEstimator);
299311 float nsigmaTPC = mPidManagers [kIndex ].getNSigmaTPC (track);
@@ -329,7 +341,7 @@ struct nucleiQC {
329341 }
330342
331343 if (particle.isPhysicalPrimary ()) {
332- candidate.flags |= nuclei::Flags:: kIsPhysicalPrimary ;
344+ candidate.flags |= nuclei::QcFlags:: kQcIsPhysicalPrimary ;
333345
334346 // /< heavy flavour mother
335347 /* if (particle.has_mothers()) {
@@ -344,52 +356,33 @@ struct nucleiQC {
344356
345357 } else if (particle.getProcess () == TMCProcess::kPDecay ) {
346358 // /< assuming that strong decays are included in the previous step
347- candidate.flags |= nuclei::Flags:: kIsSecondaryFromWeakDecay ;
359+ candidate.flags |= nuclei::QcFlags:: kQcIsSecondaryFromWeakDecay ;
348360 } else {
349- candidate.flags |= nuclei::Flags:: kIsSecondaryFromMaterial ;
361+ candidate.flags |= nuclei::QcFlags:: kQcIsSecondaryFromMaterial ;
350362 }
351363 }
352364
353- void fillSpeciesFlags (const int iSpecies, nuclei::SlimCandidate& candidate)
365+ template <typename Tparticle>
366+ void fillCollisionFlag (const Tparticle& particle, nuclei::SlimCandidate& candidate, const std::vector<bool >& reconstructedCollision)
354367 {
355-
356- switch (iSpecies) {
357- case nuclei::Species::kPr :
358- candidate.flags |= nuclei::Flags::kProton ;
359- break ;
360- case nuclei::Species::kDe :
361- candidate.flags |= nuclei::Flags::kDeuteron ;
362- break ;
363- case nuclei::Species::kTr :
364- candidate.flags |= nuclei::Flags::kTriton ;
365- break ;
366- case nuclei::Species::kHe :
367- candidate.flags |= nuclei::Flags::kHe3 ;
368- break ;
369- case nuclei::Species::kAl :
370- candidate.flags |= nuclei::Flags::kHe4 ;
371- break ;
372- default :
373- candidate.flags |= 0 ;
374- break ;
368+ if (reconstructedCollision[particle.mcCollisionId ()]) {
369+ candidate.flags |= nuclei::QcFlags::kQcHasReconstructedCollision ;
375370 }
376371 }
377372
378373 template <typename Tcollision, typename Ttrack>
379- void fillNucleusFlagsPdgs (const int iSpecies, const Tcollision& collision, const Ttrack& track, nuclei::SlimCandidate& candidate)
374+ void fillNucleusFlagsPdgs (const Tcollision& collision, const Ttrack& track, nuclei::SlimCandidate& candidate)
380375 {
381376 candidate.flags = static_cast <uint16_t >((track.pidForTracking () & 0xF ) << 12 );
382377
383- fillSpeciesFlags (iSpecies, candidate);
384-
385378 if (track.hasTOF ())
386- candidate.flags |= nuclei::Flags:: kHasTOF ;
379+ candidate.flags |= nuclei::QcFlags:: kQcHasTOF ;
387380
388381 if (track.hasTRD ())
389- candidate.flags |= nuclei::Flags:: kHasTRD ;
382+ candidate.flags |= nuclei::QcFlags:: kQcHasTRD ;
390383
391384 if (!collision.selection_bit (o2::aod::evsel::kNoITSROFrameBorder ))
392- candidate.flags |= nuclei::Flags:: kITSrof ;
385+ candidate.flags |= nuclei::QcFlags:: kQcITSrof ;
393386 }
394387
395388 template <typename Tparticle>
@@ -405,8 +398,6 @@ struct nucleiQC {
405398 void fillDcaInformation (const int iSpecies, const Tcollision& collision, const Ttrack& track, nuclei::SlimCandidate& candidate, const aod::McParticles::iterator& particle)
406399 {
407400
408- const o2::math_utils::Point3D<float > collisionVertex{collision.posX (), collision.posY (), collision.posZ ()};
409-
410401 mDcaInfoCov .set (999 , 999 , 999 , 999 , 999 );
411402 setTrackParCov (track, mTrackParCov );
412403 mTrackParCov .setPID (track.pidForTracking ());
@@ -432,7 +423,7 @@ struct nucleiQC {
432423 nuclei::SlimCandidate fillCandidate (const int iSpecies, Tcollision const & collision, Ttrack const & track)
433424 {
434425 if (!nuclei::checkSpeciesValidity (iSpecies))
435- std::runtime_error (" species contains invalid nucleus index" );
426+ throw std::runtime_error (" species contains invalid nucleus index" );
436427
437428 nuclei::SlimCandidate candidate = {.pt = track.pt () * track.sign (),
438429 .eta = track.eta (),
@@ -455,7 +446,7 @@ struct nucleiQC {
455446 .nsigmaTpc = mPidManagers [iSpecies].getNSigmaTPC (track),
456447 .nsigmaTof = mPidManagers [iSpecies].getNSigmaTOF (track)};
457448
458- fillNucleusFlagsPdgs (iSpecies, collision, track, candidate);
449+ fillNucleusFlagsPdgs (collision, track, candidate);
459450
460451 aod::McParticles::iterator particle;
461452
@@ -497,7 +488,7 @@ struct nucleiQC {
497488 {
498489 constexpr int kIndex = iSpecies;
499490 if (!nuclei::checkSpeciesValidity (kIndex ))
500- std::runtime_error (" species contains invalid nucleus kIndex" );
491+ throw std::runtime_error (" species contains invalid nucleus kIndex" );
501492
502493 if (isGenerated) {
503494 const float ptGenerated = (kIndex == nuclei::Species::kPr || kIndex == nuclei::Species::kDe || kIndex == nuclei::Species::kTr ) ? candidate.ptGenerated : candidate.ptGenerated / 2 .f ;
@@ -517,11 +508,12 @@ struct nucleiQC {
517508 }
518509 }
519510
520- void processMc (const Collisions& collisions, const TrackCandidatesMC& tracks, const aod::BCsWithTimestamps&, const aod::McParticles& mcParticles)
511+ void processMc (const Collisions& collisions, const TrackCandidatesMC& tracks, const aod::BCsWithTimestamps&, const aod::McParticles& mcParticles, const aod::McCollisions& mcCollisions )
521512 {
522513 gRandom ->SetSeed (67 );
523514 mNucleiCandidates .clear ();
524515 std::vector<bool > reconstructedMcParticles (mcParticles.size (), false );
516+ std::vector<bool > reconstructedCollisions (mcCollisions.size (), false );
525517
526518 for (const auto & collision : collisions) {
527519
@@ -530,6 +522,8 @@ struct nucleiQC {
530522
531523 if (!nuclei::eventSelection (collision, mHistograms , cfgEventSelections, cfgCutVertex))
532524 continue ;
525+ mHistograms .fill (HIST (" hCentrality" ), nuclei::getCentrality (collision, cfgCentralityEstimator, mHistFailCentrality ));
526+ reconstructedCollisions[collision.mcCollisionId ()] = true ;
533527
534528 bool anyTrackTuner = false ;
535529 for (int iSpecies = 0 ; iSpecies < static_cast <int >(nuclei::Species::kNspecies ); iSpecies++) {
@@ -578,10 +572,8 @@ struct nucleiQC {
578572 if (cfgFillOnlyPhysicalPrimaries && !particle.isPhysicalPrimary ())
579573 return ;
580574
581- LOG (info) << " track passed physical primary cut" ;
582-
583575 mHistograms .fill (HIST (nuclei::cNames[kSpeciesCt ]) + HIST (" /hTrackSelections" ), nuclei::trackSelection::kNoCuts );
584- if (!trackSelection<kSpeciesRt >(track))
576+ if (!trackSelection<kSpeciesRt >(track, collision ))
585577 return ;
586578 mHistograms .fill (HIST (nuclei::cNames[kSpeciesCt ]) + HIST (" /hTrackSelections" ), nuclei::trackSelection::kTrackCuts );
587579
@@ -591,6 +583,7 @@ struct nucleiQC {
591583
592584 nuclei::SlimCandidate candidate;
593585 candidate = fillCandidate</* isMc*/ true >(kSpeciesCt , collision, track);
586+ fillCollisionFlag (particle, candidate, reconstructedCollisions);
594587
595588 mNucleiCandidates .emplace_back (candidate);
596589 reconstructedMcParticles[particle.globalIndex ()] = true ;
@@ -627,7 +620,7 @@ struct nucleiQC {
627620 nuclei::SlimCandidate candidate;
628621 // candidate.centrality = nuclei::getCentrality(collision, cfgCentralityEstimator, mHistFailCentrality);
629622 candidate.centrality = -1 .f ; // centrality is not well defined for non-reconstructed particles, set to -1 for now
630- fillSpeciesFlags (iSpecies , candidate);
623+ fillCollisionFlag (particle , candidate, reconstructedCollisions );
631624 fillNucleusFlagsPdgsMc (particle, candidate);
632625 fillNucleusGeneratedVariables (particle, candidate);
633626
0 commit comments