1818#include " Common/DataModel/Centrality.h"
1919#include " Common/DataModel/EventSelection.h"
2020#include " Common/DataModel/TrackSelectionTables.h"
21+ #include " PWGLF/DataModel/particleCompositionCorrectionTable.h"
2122
2223#include < Framework/AnalysisTask.h>
2324#include < Framework/HistogramRegistry.h>
2728
2829#include < unordered_set>
2930#include < vector>
31+ #include < random>
3032
3133using namespace o2 ;
3234using namespace o2 ::framework;
@@ -38,6 +40,19 @@ using aod::track::TrackSelectionFlags;
3840// --------------------------------------------------------------------------------------------------
3941// --------------------------------------------------------------------------------------------------
4042struct ChargedParticles {
43+ std::random_device rnd;
44+ std::mt19937 gen{rnd ()};
45+ std::uniform_real_distribution<float > dist{0 .f , 1 .f };
46+ uint32_t getNRepetitons (float scalingFactor)
47+ {
48+ uint32_t nRepetitions = static_cast <uint32_t >(scalingFactor);
49+ float rest = scalingFactor - nRepetitions;
50+ if (rest) {
51+ nRepetitions += (dist (gen) <= rest) ? 1u : 0u ;
52+ // LOGP(info, "scalingFactor: {} -> {}", scalingFactor, nRepetitions);
53+ }
54+ return nRepetitions;
55+ };
4156
4257 HistogramRegistry histos;
4358 Service<o2::framework::O2DatabasePDG> pdg;
@@ -62,9 +77,11 @@ struct ChargedParticles {
6277 kSystUpDCAxy ,
6378 kSystDownDCAz ,
6479 kSystUpDCAz ,
65- kSystITSHits ,
80+ kSystITSHits , // only relevant for converted data
6681 kSystDownTPCCrossedRows ,
67- kSystUpTPCCrossedRows
82+ kSystUpTPCCrossedRows ,
83+ kSystDownPCC = 120 ,
84+ kSystUpPCC
6885 };
6986 Configurable<uint32_t > systMode{" systMode" , kSystNominal , " variation for systematic uncertainties" };
7087 uint16_t trackSelMask{TrackSelectionFlags::kGlobalTrackWoPtEta }; // track selection bitmask (without cut that is being varied)
@@ -80,6 +97,7 @@ struct ChargedParticles {
8097 bool isAcceptedEventMC{false };
8198 bool isINELGT0EventMC{false };
8299 bool isChargedPrimary{false };
100+ uint32_t nRepetitions{1u };
83101 };
84102 VarContainer vars;
85103 static constexpr float kMaxVtxZ = 10 .f;
@@ -92,7 +110,7 @@ struct ChargedParticles {
92110 template <typename T>
93111 bool initTrack (const T& track);
94112
95- template <typename C, typename T>
113+ template <bool IS_MC, typename C, typename T>
96114 void initEvent (const C& collision, const T& tracks);
97115
98116 template <typename C, typename P>
@@ -112,9 +130,9 @@ struct ChargedParticles {
112130 using CollisionTableMCTrue = aod::McCollisions;
113131 using CollisionTableMC = soa::SmallGroups<soa::Join<aod::McCollisionLabels, aod::Collisions, aod::EvSels>>;
114132 using TrackTableMC = soa::Join<aod::FullTracks, aod::TracksDCA, aod::TrackSelection, aod::McTrackLabels>;
115- using ParticleTableMC = aod::McParticles;
133+ using ParticleTableMC = soa::Join< aod::McParticles, aod::ParticleCompositionCorrection> ;
116134 Preslice<TrackTableMC> perCollision = aod::track::collisionId;
117- void processMC (CollisionTableMCTrue::iterator const & mcCollision, CollisionTableMC const & collisions, TrackTableMC const & tracks , ParticleTableMC const & particles);
135+ void processMC (CollisionTableMCTrue::iterator const & mcCollision, TrackTableMC const & tracks, CollisionTableMC const & collisions , ParticleTableMC const & particles);
118136 PROCESS_SWITCH (ChargedParticles, processMC, " process mc" , true );
119137};
120138
@@ -241,7 +259,7 @@ void ChargedParticles::init(InitContext const&)
241259// **************************************************************************************************
242260void ChargedParticles::processData (CollisionTableData::iterator const & collision, TrackTableData const & tracks)
243261{
244- initEvent (collision, tracks);
262+ initEvent< false > (collision, tracks);
245263 processMeas<false >(tracks);
246264}
247265
@@ -250,7 +268,7 @@ void ChargedParticles::processData(CollisionTableData::iterator const& collision
250268 * Entrypoint to processes mc.
251269 */
252270// **************************************************************************************************
253- void ChargedParticles::processMC (CollisionTableMCTrue::iterator const & mcCollision, CollisionTableMC const & collisions, TrackTableMC const & tracks , ParticleTableMC const & particles)
271+ void ChargedParticles::processMC (CollisionTableMCTrue::iterator const & mcCollision, TrackTableMC const & tracks, CollisionTableMC const & collisions , ParticleTableMC const & particles)
254272{
255273 histos.fill (HIST (" collision_ambiguity" ), collisions.size ());
256274
@@ -270,7 +288,7 @@ void ChargedParticles::processMC(CollisionTableMCTrue::iterator const& mcCollisi
270288 } else {
271289 for (const auto & collision : collisions) {
272290 auto curTracks = tracks.sliceBy (perCollision, collision.globalIndex ());
273- initEvent (collision, curTracks);
291+ initEvent< true > (collision, curTracks);
274292 processMeas<true >(curTracks);
275293 break ; // for now look only at first collision...
276294 }
@@ -302,6 +320,15 @@ bool ChargedParticles::initParticle(const P& particle)
302320 if (particle.pt () <= ptMinCut || particle.pt () >= ptMaxCut) {
303321 return false ;
304322 }
323+
324+ float pccWeight = particle.pccWeight ();
325+ if (systMode == kSystDownPCC ) {
326+ pccWeight = particle.pccWeightSysDown ();
327+ } else if (systMode == kSystUpPCC ) {
328+ pccWeight = particle.pccWeightSysUp ();
329+ }
330+ vars.nRepetitions = getNRepetitons (pccWeight);
331+ // FIXME: in case of nRepetitions = 0 INELGT0 can be wrong
305332 return true ;
306333}
307334
@@ -334,20 +361,43 @@ bool ChargedParticles::initTrack(const T& track)
334361 * Check if event is good.
335362 */
336363// **************************************************************************************************
337- template <typename C, typename T>
364+ template <bool IS_MC, typename C, typename T>
338365void ChargedParticles::initEvent (const C& collision, const T& tracks)
339366{
340367 vars.multMeas = 0 ;
341368 for (const auto & track : tracks) {
342369 if (initTrack (track)) {
343- ++vars.multMeas ;
370+ if constexpr (IS_MC) {
371+ if (!track.has_mcParticle ()) {
372+ continue ;
373+ }
374+ const auto & particle = track.template mcParticle_as <ParticleTableMC>();
375+ if (!initParticle (particle)) {
376+ continue ;
377+ }
378+ vars.multMeas += vars.nRepetitions ;
379+ } else {
380+ ++vars.multMeas ;
381+ }
344382 }
345383 }
346384
347385 vars.isAcceptedEvent = false ;
348386 if (std::abs (collision.posZ ()) < kMaxVtxZ ) {
349- if (isRun3 ? collision.sel8 () : collision.sel7 ()) {
350- if ((isRun3 || doprocessMC) ? true : collision.alias_bit (kINT7 )) {
387+ if (isRun3) {
388+ if (collision.sel8 () &&
389+ collision.selection_bit (aod::evsel::kNoSameBunchPileup ) &&
390+ collision.selection_bit (aod::evsel::kIsVertexITSTPC ) &&
391+ collision.selection_bit (aod::evsel::kIsGoodZvtxFT0vsPV ))
392+ // !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched) &&
393+ // collision.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) &&
394+ // collision.selection_bit(aod::evsel::kNoCollInRofStandard) &&
395+ // collision.selection_bit(aod::evsel::kIsVertexTOFmatched)
396+ {
397+ vars.isAcceptedEvent = true ;
398+ }
399+ } else {
400+ if (collision.sel7 () && ((doprocessMC) ? true : collision.alias_bit (kINT7 ))) {
351401 vars.isAcceptedEvent = true ;
352402 }
353403 }
@@ -368,7 +418,7 @@ void ChargedParticles::initEventMC(const C& collision, const P& particles)
368418 if (!initParticle (particle) || !vars.isChargedPrimary ) {
369419 continue ;
370420 }
371- ++ vars.multTrue ;
421+ vars.multTrue += vars. nRepetitions ;
372422 }
373423 bool isGoodEventClass = (normINELGT0) ? vars.isINELGT0EventMC : (vars.multTrue > 0 );
374424 vars.isAcceptedEventMC = isGoodEventClass && (std::abs (collision.posZ ()) < kMaxVtxZ );
@@ -390,9 +440,11 @@ void ChargedParticles::processTrue(const P& particles)
390440
391441 for (const auto & particle : particles) {
392442 if (initParticle (particle) && vars.isChargedPrimary ) {
393- histos.fill (HIST (" multPtSpec_prim_gen" ), vars.multTrue , particle.pt ());
394- if (!vars.isAcceptedEvent ) {
395- histos.fill (HIST (" multPtSpec_prim_gen_evtloss" ), vars.multTrue , particle.pt ());
443+ for (auto i = 0u ; i < vars.nRepetitions ; ++i) {
444+ histos.fill (HIST (" multPtSpec_prim_gen" ), vars.multTrue , particle.pt ());
445+ if (!vars.isAcceptedEvent ) {
446+ histos.fill (HIST (" multPtSpec_prim_gen_evtloss" ), vars.multTrue , particle.pt ());
447+ }
396448 }
397449 }
398450 }
@@ -441,7 +493,7 @@ void ChargedParticles::processMeas(const T& tracks)
441493
442494 foundParticles.push_back (track.mcParticleId ());
443495
444- const auto & particle = track.template mcParticle_as <aod::McParticles >();
496+ const auto & particle = track.template mcParticle_as <ParticleTableMC >();
445497
446498 if (!vars.isAcceptedEventMC ) {
447499 histos.fill (HIST (" multPtSpec_trk_meas_evtcont" ), vars.multMeas , track.pt ());
@@ -450,19 +502,21 @@ void ChargedParticles::processMeas(const T& tracks)
450502
451503 histos.fill (HIST (" multPtSpec_trk_inter" ), vars.multTrue , track.pt ());
452504 if (initParticle (particle)) {
453- if (!vars.isChargedPrimary ) {
454- histos.fill (HIST (" multPtSpec_trk_sec_meas" ), vars.multMeas , track.pt ());
455- } else {
456- histos.fill (HIST (" multCorrel_prim" ), vars.multMeas , vars.multTrue );
457- histos.fill (HIST (" ptCorrel_prim" ), track.pt (), particle.pt ());
458- histos.fill (HIST (" multPtSpec_prim_meas" ), vars.multTrue , particle.pt ());
459- histos.fill (HIST (" multPtSpec_trk_prim_meas" ), vars.multMeas , track.pt ());
505+ for (auto i = 0u ; i < vars.nRepetitions ; ++i) {
506+ if (!vars.isChargedPrimary ) {
507+ histos.fill (HIST (" multPtSpec_trk_sec_meas" ), vars.multMeas , track.pt ());
508+ } else {
509+ histos.fill (HIST (" multCorrel_prim" ), vars.multMeas , vars.multTrue );
510+ histos.fill (HIST (" ptCorrel_prim" ), track.pt (), particle.pt ());
511+ histos.fill (HIST (" multPtSpec_prim_meas" ), vars.multTrue , particle.pt ());
512+ histos.fill (HIST (" multPtSpec_trk_prim_meas" ), vars.multMeas , track.pt ());
513+ }
460514 }
461515 }
462516 }
463517 }
464518
465- std::unordered_set<int > uniqueIndices (foundParticles.begin (), foundParticles.end ());
519+ std::unordered_set<int32_t > uniqueIndices (foundParticles.begin (), foundParticles.end ());
466520 for (const auto & mcParticleID : uniqueIndices) {
467521 histos.fill (HIST (" track_ambiguity" ), std::count (foundParticles.begin (), foundParticles.end (), mcParticleID));
468522 }
0 commit comments