2626#include " Framework/AnalysisTask.h"
2727#include " Framework/AnalysisDataModel.h"
2828#include " Framework/ASoAHelpers.h"
29+ #include " Framework/O2DatabasePDGPlugin.h"
2930#include " ReconstructionDataFormats/Track.h"
3031#include " Common/Core/RecoDecay.h"
3132#include " Common/Core/trackUtilities.h"
3839#include " Common/DataModel/PIDResponse.h"
3940#include " CCDB/BasicCCDBManager.h"
4041#include " EventFiltering/Zorro.h"
42+ #include " PWGLF/Utils/inelGt.h"
4143
4244#include < TFile.h>
4345#include < TList.h>
@@ -78,6 +80,7 @@ using CascDataExtSelected = soa::Join<CascDataExt, CascadeFlags>;
7880using MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::PVMults>;
7981using MyCollisionsMult = soa::Join<aod::Collisions, aod::EvSels, aod::FT0Mults>;
8082using MyCascades = soa::Filtered<aod::CascDataExtSelected>;
83+ using LabeledCascades = soa::Join<aod::CascDataExt, aod::McCascLabels>;
8184
8285struct CascadeSelector {
8386 Service<o2::ccdb::BasicCCDBManager> ccdb;
@@ -399,6 +402,10 @@ struct CascadeCorrelations {
399402 TH1D* hEffOmegaMin;
400403 TH1D* hEffOmegaPlus;
401404
405+ // used in MC closure test
406+ Service<o2::framework::O2DatabasePDG> pdgDB;
407+ o2::pwglf::ParticleCounter<o2::framework::O2DatabasePDG> mCounter ;
408+
402409 void init (InitContext const &)
403410 {
404411 ccdb->setURL (ccdbUrl);
@@ -415,6 +422,9 @@ struct CascadeCorrelations {
415422 }
416423
417424 zorroSummary.setObject (zorro.getZorroSummary ());
425+
426+ mCounter .mPdgDatabase = pdgDB.service ;
427+ mCounter .mSelectPrimaries = true ;
418428 }
419429
420430 double getEfficiency (TH1D* h, double pT)
@@ -489,6 +499,16 @@ struct CascadeCorrelations {
489499 {" MixedEvents/hMEOmXiSS" , " hMEOmXiSS" , {HistType::kTHnSparseF , {deltaPhiAxis, deltaYAxis, ptAxis, ptAxis, invMassAxis, invMassAxis, vertexAxis, multiplicityAxis}}, true },
490500 {" MixedEvents/hMEOmOmOS" , " hMEOmOmOS" , {HistType::kTHnSparseF , {deltaPhiAxis, deltaYAxis, ptAxis, ptAxis, invMassAxis, invMassAxis, vertexAxis, multiplicityAxis}}, true },
491501 {" MixedEvents/hMEOmOmSS" , " hMEOmOmSS" , {HistType::kTHnSparseF , {deltaPhiAxis, deltaYAxis, ptAxis, ptAxis, invMassAxis, invMassAxis, vertexAxis, multiplicityAxis}}, true },
502+
503+ // MC closure
504+ {" MC/hMCPlusMinus" , " hMCPlusMinus" , {HistType::kTHnSparseF , {deltaPhiAxis, deltaYAxis, ptAxis, ptAxis, vertexAxis, multiplicityAxis}}, true },
505+ {" MC/hMCPlusPlus" , " hMCPlusPlus" , {HistType::kTHnSparseF , {deltaPhiAxis, deltaYAxis, ptAxis, ptAxis, vertexAxis, multiplicityAxis}}, true },
506+ {" MC/hMCMinusPlus" , " hMCMinusPlus" , {HistType::kTHnSparseF , {deltaPhiAxis, deltaYAxis, ptAxis, ptAxis, vertexAxis, multiplicityAxis}}, true },
507+ {" MC/hMCMinusMinus" , " hMCMinusMinus" , {HistType::kTHnSparseF , {deltaPhiAxis, deltaYAxis, ptAxis, ptAxis, vertexAxis, multiplicityAxis}}, true },
508+
509+ {" MC/hGenMultNoReco" , " hGenMultNoReco" , {HistType::kTH1I , {{100 , 0 , 100 , " Number of generated charged primaries" }}}},
510+ {" MC/hGenMultOneReco" , " hGenMultOneReco" , {HistType::kTH1I , {{100 , 0 , 100 , " Number of generated charged primaries" }}}},
511+ {" MC/hSplitEvents" , " hSplitEvents" , {HistType::kTH1I , {{10 , 0 , 10 , " Number of rec. events per gen event" }}}},
492512 },
493513 };
494514
@@ -503,9 +523,8 @@ struct CascadeCorrelations {
503523 // BinningType colBinning{{axisVtxZ, axisMult}, true}; // true is for 'ignore overflows' (true by default). Underflows and overflows will have bin -1.
504524 using BinningType = ColumnBinningPolicy<aod::collision::PosZ>;
505525 BinningType colBinning{{axisVtxZ}, true }; // true is for 'ignore overflows' (true by default). Underflows and overflows will have bin -1.
506- SameKindPair<MyCollisionsMult, MyCascades, BinningType> pair{colBinning, nMixedEvents, -1 , &cache};
507526
508- void processSameEvent (MyCollisionsMult::iterator const & collision, MyCascades const & Cascades, aod::V0sLinked const &, aod::V0Datas const &, FullTracksExtIU const &, aod::BCsWithTimestamps const &)
527+ void processSameEvent (MyCollisionsMult::iterator const & collision, MyCascades const & Cascades, FullTracksExtIU const &, aod::BCsWithTimestamps const &)
509528 {
510529 if (useTrigger) {
511530 auto bc = collision.bc_as <aod::BCsWithTimestamps>();
@@ -713,11 +732,13 @@ struct CascadeCorrelations {
713732 }
714733 }
715734 } // correlations
716- } // process same event
735+ } // process same event
717736
718- void processMixedEvent (MyCollisionsMult const & /* collisions*/ , MyCascades const & /* Cascades*/ ,
719- aod::V0sLinked const &, aod::V0Datas const &, FullTracksExtIU const &)
737+ void processMixedEvent (MyCollisionsMult const & collisions, MyCascades const & Cascades, FullTracksExtIU const &)
720738 {
739+ auto cascadesTuple = std::make_tuple (Cascades);
740+ SameKindPair<MyCollisionsMult, MyCascades, BinningType> pair{colBinning, nMixedEvents, -1 , collisions, cascadesTuple, &cache};
741+
721742 for (auto const & [col1, cascades1, col2, cascades2] : pair) {
722743 if (!col1.sel8 () || !col2.sel8 ())
723744 continue ;
@@ -891,8 +912,60 @@ struct CascadeCorrelations {
891912 } // collisions
892913 } // process mixed events
893914
915+ Filter genCascadesFilter = nabs(aod::mcparticle::pdgCode) == 3312 ;
916+
917+ void processMC (aod::McCollision const &, soa::SmallGroups<soa::Join<aod::McCollisionLabels, MyCollisionsMult>> const & collisions, soa::Filtered<aod::McParticles> const & genCascades, aod::McParticles const & mcParticles)
918+ {
919+ // Let's do some logic on matched reconstructed collisions - if there less or more than one, fill some QA and skip the rest
920+ double FT0mult = -1 ; // non-sensible default value just in case
921+ double vtxz = -999 .; // non-sensible default value just in case
922+ if (collisions.size () < 1 ) {
923+ registry.fill (HIST (" MC/hSplitEvents" ), 0 );
924+ registry.fill (HIST (" MC/hGenMultNoReco" ), mCounter .countFT0A (mcParticles) + mCounter .countFT0C (mcParticles));
925+ return ;
926+ } else if (collisions.size () == 1 ) {
927+ registry.fill (HIST (" MC/hSplitEvents" ), 1 );
928+ registry.fill (HIST (" MC/hGenMultOneReco" ), mCounter .countFT0A (mcParticles) + mCounter .countFT0C (mcParticles));
929+ for (auto const & collision : collisions) { // not really a loop, as there is only one collision
930+ FT0mult = collision.multFT0M ();
931+ vtxz = collision.posZ ();
932+ }
933+ } else if (collisions.size () > 1 ) {
934+ registry.fill (HIST (" MC/hSplitEvents" ), collisions.size ());
935+ return ;
936+ }
937+
938+ for (auto & [c0, c1] : combinations (genCascades, genCascades)) { // combinations automatically applies strictly upper in case of 2 identical tables
939+ // Define the trigger as the particle with the highest pT. As we can't swap the cascade tables themselves, we swap the addresses and later dereference them
940+ auto * triggerAddress = &c0;
941+ auto * assocAddress = &c1;
942+ if (assocAddress->pt () > triggerAddress->pt ()) {
943+ std::swap (triggerAddress, assocAddress);
944+ }
945+ auto trigger = *triggerAddress;
946+ auto assoc = *assocAddress;
947+
948+ double dphi = RecoDecay::constrainAngle (trigger.phi () - assoc.phi (), -PIHalf);
949+
950+ if (trigger.pdgCode () < 0 ) { // anti-trigg --> Plus
951+ if (assoc.pdgCode () < 0 ) { // anti-assoc --> Plus
952+ registry.fill (HIST (" MC/hMCPlusPlus" ), dphi, trigger.y () - assoc.y (), trigger.pt (), assoc.pt (), vtxz, FT0mult);
953+ } else { // assoc --> Minus
954+ registry.fill (HIST (" MC/hMCPlusMinus" ), dphi, trigger.y () - assoc.y (), trigger.pt (), assoc.pt (), vtxz, FT0mult);
955+ }
956+ } else { // trig --> Minus
957+ if (assoc.pdgCode () < 0 ) { // anti-assoc --> Plus
958+ registry.fill (HIST (" MC/hMCMinusPlus" ), dphi, trigger.y () - assoc.y (), trigger.pt (), assoc.pt (), vtxz, FT0mult);
959+ } else {
960+ registry.fill (HIST (" MC/hMCMinusMinus" ), dphi, trigger.y () - assoc.y (), trigger.pt (), assoc.pt (), vtxz, FT0mult);
961+ }
962+ }
963+ }
964+ }
965+
894966 PROCESS_SWITCH (CascadeCorrelations, processSameEvent, " Process same events" , true );
895967 PROCESS_SWITCH (CascadeCorrelations, processMixedEvent, " Process mixed events" , true );
968+ PROCESS_SWITCH (CascadeCorrelations, processMC, " Process MC" , false );
896969
897970}; // struct
898971
0 commit comments