1010// or submit itself to any jurisdiction.
1111
1212#include " PWGLF/DataModel/LFDoubleOmegaTables.h"
13+ #include " PWGLF/DataModel/LFDoubleOmegaTrackTables.h"
1314#include " PWGLF/DataModel/LFStrangenessTables.h"
1415#include " PWGLF/Utils/doubleOmegaBuilderHelper.h"
1516
1617#include " Common/CCDB/EventSelectionParams.h"
17- #include " Common/Core/RecoDecay.h"
1818#include " Common/Core/Zorro.h"
1919#include " Common/Core/ZorroSummary.h"
2020#include " Common/Core/trackUtilities.h"
4141#include < Framework/Logger.h>
4242#include < Framework/OutputObjHeader.h>
4343#include < Framework/runDataProcessing.h>
44- #include < GPU/GPUROOTCartesianFwd.h>
45- #include < ReconstructionDataFormats/Track.h>
4644
4745#include < TH1.h>
4846#include < TH2.h>
5755#include < deque>
5856#include < functional>
5957#include < iterator>
58+ #include < ratio>
6059#include < set>
6160#include < sstream>
6261#include < string>
@@ -153,6 +152,7 @@ struct doubleOmegaTreeCreator {
153152 kFindableSelectedTracks ,
154153 kFindableCascadeAndV0 ,
155154 kFindableCascadeAndV0SelectedTracks ,
155+ kFindableSkimCascadeAndV0 , // processFindableTracksWithSkim: in DOmegaCascades + DOmegaV0s (tracks selected by the track BDT)
156156 kNFindabilitySteps
157157 };
158158 enum MixingType : uint8_t {
@@ -360,6 +360,7 @@ struct doubleOmegaTreeCreator {
360360 printValue (doprocessDataFromCascades);
361361 printValue (doprocessMC);
362362 printValue (doprocessFindableTracks);
363+ printValue (doprocessFindableTracksWithSkim);
363364 printValue (doprocessDerivedData);
364365 printValue (doprocessDerivedMixing);
365366 printValue (doprocessDerivedMixingCandidates);
@@ -368,6 +369,9 @@ struct doubleOmegaTreeCreator {
368369 void init (InitContext const &)
369370 {
370371 printConfig ();
372+ if (doprocessFindableTracks && doprocessFindableTracksWithSkim) {
373+ LOG (fatal) << " processFindableTracks and processFindableTracksWithSkim are alternatives: enable only one of them" ;
374+ }
371375
372376 ccdb->setURL (ccdburl);
373377 ccdb->setCaching (true );
@@ -414,6 +418,7 @@ struct doubleOmegaTreeCreator {
414418 generatedAndFindable->GetXaxis ()->SetBinLabel (kFindableSelectedTracks + 1 , " Findable, selected tracks" );
415419 generatedAndFindable->GetXaxis ()->SetBinLabel (kFindableCascadeAndV0 + 1 , " Findable cascade + V0" );
416420 generatedAndFindable->GetXaxis ()->SetBinLabel (kFindableCascadeAndV0SelectedTracks + 1 , " Findable cascade + V0, selected tracks" );
421+ generatedAndFindable->GetXaxis ()->SetBinLabel (kFindableSkimCascadeAndV0 + 1 , " Findable skim cascade + V0" );
417422
418423 if (doprocessDerivedMixingCandidates) {
419424 histos.add (" Mixing/hSeedRadiusPhi" , " ;Double-#Omega decay radius (cm);Double-#Omega #varphi (rad);Same-event candidates" , HistType::kTH2F , {mixingOpts.binsRadius , mixingOpts.binsPhi });
@@ -1039,13 +1044,57 @@ struct doubleOmegaTreeCreator {
10391044 }
10401045 PROCESS_SWITCH (doubleOmegaTreeCreator, processMC, " Reconstruct and truth-match Omega + Lambda + kaon in MC" , false );
10411046
1042- void processFindableTracks (soa::Join<aod::Collisions, aod::McCollisionLabels> const & collisions,
1043- TracksFullMC const & tracks,
1044- aod::Cascades const & cascades,
1045- aod::V0s const & v0s,
1046- aod::McParticles const & mcParticles,
1047- aod::McCollisions const &,
1048- aod::BCsWithTimestamps const &)
1047+ // Whether the tracks of the Omega (daughterTrackIds 0-2) form a cascade of the table and those of the direct Lambda
1048+ // (daughterTrackIds 3-4) a V0, whatever the order of the tracks; the collisions of the first ones found
1049+ template <class Cascades , class V0s >
1050+ static void findCascadeAndV0 (Cascades const & cascades, V0s const & v0s, std::array<int , 6 > const & daughterTrackIds,
1051+ bool & omegaInCascade, int64_t & cascadeCollisionId, bool & directLambdaInV0, int64_t & directLambdaCollisionId)
1052+ {
1053+ omegaInCascade = false ;
1054+ directLambdaInV0 = false ;
1055+ for (const auto & cascade : cascades) {
1056+ const auto cascadeV0 = v0s.rawIteratorAt (cascade.v0Id ());
1057+ const std::array<int64_t , 3 > cascadeTrackIds{
1058+ cascadeV0.posTrackId (), cascadeV0.negTrackId (), cascade.bachelorId ()};
1059+ bool allOmegaTracksInCascade = true ;
1060+ for (std::size_t iDaughter = 0 ; iDaughter < 3 ; ++iDaughter) {
1061+ if (std::find (cascadeTrackIds.begin (), cascadeTrackIds.end (), daughterTrackIds[iDaughter]) == cascadeTrackIds.end ()) {
1062+ allOmegaTracksInCascade = false ;
1063+ break ;
1064+ }
1065+ }
1066+ if (allOmegaTracksInCascade) {
1067+ omegaInCascade = true ;
1068+ cascadeCollisionId = cascade.collisionId ();
1069+ break ;
1070+ }
1071+ }
1072+
1073+ for (const auto & v0 : v0s) {
1074+ const std::array<int64_t , 2 > v0TrackIds{v0.posTrackId (), v0.negTrackId ()};
1075+ bool allDirectLambdaTracksInV0 = true ;
1076+ for (std::size_t iDaughter = 3 ; iDaughter < 5 ; ++iDaughter) {
1077+ if (std::find (v0TrackIds.begin (), v0TrackIds.end (), daughterTrackIds[iDaughter]) == v0TrackIds.end ()) {
1078+ allDirectLambdaTracksInV0 = false ;
1079+ break ;
1080+ }
1081+ }
1082+ if (allDirectLambdaTracksInV0) {
1083+ directLambdaInV0 = true ;
1084+ directLambdaCollisionId = v0.collisionId ();
1085+ break ;
1086+ }
1087+ }
1088+ }
1089+
1090+ // skimCascades, skimV0s: tables of doubleOmegaTrackIndexSkimCreator (processFindableTracksWithSkim), nullptr otherwise
1091+ void runFindableTracks (soa::Join<aod::Collisions, aod::McCollisionLabels> const & collisions,
1092+ TracksFullMC const & tracks,
1093+ aod::Cascades const & cascades,
1094+ aod::V0s const & v0s,
1095+ aod::McParticles const & mcParticles,
1096+ aod::DOmegaCascades const * skimCascades,
1097+ aod::DOmegaV0s const * skimV0s)
10491098 {
10501099 for (const auto & mcParticle : mcParticles) {
10511100 if (std::abs (mcParticle.pdgCode ()) != kDoubleOmegaPdg ) {
@@ -1060,11 +1109,11 @@ struct doubleOmegaTreeCreator {
10601109
10611110 // First stage: double-Omega -> Omega + Lambda + kaon.
10621111 for (const auto & daughter : mcParticle.daughters_as <aod::McParticles>()) {
1063- if (daughter.pdgCode () == sign * 3334 && omegaId < 0 ) {
1112+ if (daughter.pdgCode () == sign * PDG_t:: kOmegaMinus && omegaId < 0 ) {
10641113 omegaId = daughter.globalIndex ();
1065- } else if (daughter.pdgCode () == sign * 3122 && directLambdaId < 0 ) {
1114+ } else if (daughter.pdgCode () == sign * PDG_t:: kLambda0 && directLambdaId < 0 ) {
10661115 directLambdaId = daughter.globalIndex ();
1067- } else if (daughter.pdgCode () == -sign * 321 && directKaonId < 0 ) {
1116+ } else if (daughter.pdgCode () == -sign * PDG_t:: kKPlus && directKaonId < 0 ) {
10681117 directKaonId = daughter.globalIndex ();
10691118 }
10701119 }
@@ -1078,9 +1127,9 @@ struct doubleOmegaTreeCreator {
10781127 int64_t omegaLambdaId = -1 ;
10791128 int64_t omegaKaonId = -1 ;
10801129 for (const auto & daughter : omega.daughters_as <aod::McParticles>()) {
1081- if (daughter.pdgCode () == sign * 3122 && omegaLambdaId < 0 ) {
1130+ if (daughter.pdgCode () == sign * PDG_t:: kLambda0 && omegaLambdaId < 0 ) {
10821131 omegaLambdaId = daughter.globalIndex ();
1083- } else if (daughter.pdgCode () == -sign * 321 && omegaKaonId < 0 ) {
1132+ } else if (daughter.pdgCode () == -sign * PDG_t:: kKPlus && omegaKaonId < 0 ) {
10841133 omegaKaonId = daughter.globalIndex ();
10851134 }
10861135 }
@@ -1165,41 +1214,18 @@ struct doubleOmegaTreeCreator {
11651214 }
11661215 if (allDaughtersReconstructed) {
11671216 histos.fill (HIST (" MC/generatedAndFindable" ), kFindable );
1168- bool omegaInCascade = false ;
1169- int64_t cascadeCollisionId = -1 ;
1170- for (const auto & cascade : cascades) {
1171- const auto cascadeV0 = cascade.v0 ();
1172- const std::array<int64_t , 3 > cascadeTrackIds{
1173- cascadeV0.posTrackId (), cascadeV0.negTrackId (), cascade.bachelorId ()};
1174- bool allOmegaTracksInCascade = true ;
1175- for (std::size_t iDaughter = 0 ; iDaughter < 3 ; ++iDaughter) {
1176- if (std::find (cascadeTrackIds.begin (), cascadeTrackIds.end (), daughterTrackIds[iDaughter]) == cascadeTrackIds.end ()) {
1177- allOmegaTracksInCascade = false ;
1178- break ;
1179- }
1180- }
1181- if (allOmegaTracksInCascade) {
1182- omegaInCascade = true ;
1183- cascadeCollisionId = cascade.collisionId ();
1184- break ;
1185- }
1186- }
1187-
1188- bool directLambdaInV0 = false ;
1189- int64_t directLambdaCollisionId = -1 ;
1190- for (const auto & v0 : v0s) {
1191- const std::array<int64_t , 2 > v0TrackIds{v0.posTrackId (), v0.negTrackId ()};
1192- bool allDirectLambdaTracksInV0 = true ;
1193- for (std::size_t iDaughter = 3 ; iDaughter < 5 ; ++iDaughter) {
1194- if (std::find (v0TrackIds.begin (), v0TrackIds.end (), daughterTrackIds[iDaughter]) == v0TrackIds.end ()) {
1195- allDirectLambdaTracksInV0 = false ;
1196- break ;
1197- }
1198- }
1199- if (allDirectLambdaTracksInV0) {
1200- directLambdaInV0 = true ;
1201- directLambdaCollisionId = v0.collisionId ();
1202- break ;
1217+ bool omegaInCascade = false , directLambdaInV0 = false ;
1218+ int64_t cascadeCollisionId = -1 , directLambdaCollisionId = -1 ;
1219+ findCascadeAndV0 (cascades, v0s, daughterTrackIds, omegaInCascade, cascadeCollisionId, directLambdaInV0, directLambdaCollisionId);
1220+
1221+ // The same with the V0s and cascades of doubleOmegaTrackIndexSkimCreator (tracks selected by the track BDT)
1222+ if (skimCascades != nullptr && skimV0s != nullptr ) {
1223+ bool omegaInSkimCascade = false , directLambdaInSkimV0 = false ;
1224+ int64_t skimCascadeCollisionId = -1 , skimDirectLambdaCollisionId = -1 ;
1225+ findCascadeAndV0 (*skimCascades, *skimV0s, daughterTrackIds, omegaInSkimCascade, skimCascadeCollisionId, directLambdaInSkimV0, skimDirectLambdaCollisionId);
1226+ // No track selection on top: the skim tracks are already selected by the track BDT
1227+ if (omegaInSkimCascade && directLambdaInSkimV0) {
1228+ histos.fill (HIST (" MC/generatedAndFindable" ), kFindableSkimCascadeAndV0 );
12031229 }
12041230 }
12051231
@@ -1232,8 +1258,36 @@ struct doubleOmegaTreeCreator {
12321258 }
12331259 }
12341260 }
1261+
1262+ void processFindableTracks (soa::Join<aod::Collisions, aod::McCollisionLabels> const & collisions,
1263+ TracksFullMC const & tracks,
1264+ aod::Cascades const & cascades,
1265+ aod::V0s const & v0s,
1266+ aod::McParticles const & mcParticles,
1267+ aod::McCollisions const &,
1268+ aod::BCsWithTimestamps const &)
1269+ {
1270+ runFindableTracks (collisions, tracks, cascades, v0s, mcParticles, nullptr , nullptr );
1271+ }
12351272 PROCESS_SWITCH (doubleOmegaTreeCreator, processFindableTracks, " Count findable double-Omega decays and reconstruct selected daughter tracks" , false );
12361273
1274+ // As processFindableTracks, and the findable double Omegas are also looked for in the V0s and cascades of
1275+ // doubleOmegaTrackIndexSkimCreator (bin "Findable skim cascade + V0" of MC/generatedAndFindable; it needs
1276+ // doubleOmegaTrackIndexSkimCreator with processCandidates in the same workflow)
1277+ void processFindableTracksWithSkim (soa::Join<aod::Collisions, aod::McCollisionLabels> const & collisions,
1278+ TracksFullMC const & tracks,
1279+ aod::Cascades const & cascades,
1280+ aod::V0s const & v0s,
1281+ aod::DOmegaCascades const & skimCascades,
1282+ aod::DOmegaV0s const & skimV0s,
1283+ aod::McParticles const & mcParticles,
1284+ aod::McCollisions const &,
1285+ aod::BCsWithTimestamps const &)
1286+ {
1287+ runFindableTracks (collisions, tracks, cascades, v0s, mcParticles, &skimCascades, &skimV0s);
1288+ }
1289+ PROCESS_SWITCH (doubleOmegaTreeCreator, processFindableTracksWithSkim, " processFindableTracks, with the findable double Omegas also looked for in the DOmegaCascades and DOmegaV0s tables of doubleOmegaTrackIndexSkimCreator" , false );
1290+
12371291 // Bin index of value on a ConfigurableAxis (variable or fixed width), -1 outside the axis.
12381292 static int findBin (std::vector<double > const & axis, double value)
12391293 {
0 commit comments