3131#include < Framework/OutputObjHeader.h>
3232#include < Framework/SliceCache.h>
3333#include < Framework/runDataProcessing.h>
34+ #include < SimulationDataFormat/MCGenProperties.h>
3435
3536#include < Math/GenVector/RotationZ.h>
3637#include < Math/Vector4D.h> // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h)
4950#include < map>
5051#include < memory>
5152#include < tuple>
53+ #include < unordered_set>
5254#include < vector>
5355
5456using namespace o2 ;
@@ -81,6 +83,12 @@ struct Xi1530Analysisqa {
8183 using ResoMicroTracks = aod::ResoMicroTracks_001;
8284 using ResoMCCols = soa::Join<ResoCollisions, aod::ResoMCCollisions_001>;
8385
86+ // This native generator status is a production-specific injection tag.
87+ static constexpr auto IsInjectedParent = [](auto const & mcparent) {
88+ constexpr int InjectedGeneratorStatus = -11 ;
89+ return o2::mcgenstatus::getGenStatusCode (mcparent.statusCode ()) == InjectedGeneratorStatus;
90+ };
91+
8492 // Own just the event rows: zero-copy slices would retain entire DF buffers.
8593 struct MixingCollision {
8694 float x, y, z, centrality, multiplicity;
@@ -142,8 +150,8 @@ struct Xi1530Analysisqa {
142150
143151 struct : ConfigurableGroup {
144152 // Primary track selections
145- Configurable<float > cMinPtcut{" cMinPtcut" , 0.15 , " Track minium pt cut" };
146- Configurable<float > cMaxetacut{" cMaxetacut" , 0.8 , " Track maximum eta cut" };
153+ Configurable<float > cMinPtcut{" cMinPtcut" , 0.00 , " Track minium pt cut" };
154+ Configurable<float > cMaxetacut{" cMaxetacut" , 999 . , " Track maximum eta cut" };
147155
148156 Configurable<bool > cfgPrimaryTrack{" cfgPrimaryTrack" , true , " Primary track selection" };
149157 Configurable<bool > cfgPVContributor{" cfgPVContributor" , true , " PV contributor track selection" };
@@ -152,6 +160,11 @@ struct Xi1530Analysisqa {
152160
153161 Configurable<int > cfgTPCRows{" cfgTPCRows" , 80 , " Minimum Number of TPC Crossed Rows " };
154162
163+ // Micro001 quality cuts use strict lower bounds; -1 preserves the previous selection.
164+ // Full ResoTracks has no ITS cluster map and retains cfgTPCcluster/cfgTPCRows.
165+ Configurable<int > cfgITSNCls{" cfgITSNCls" , -1 , " Require ITS NCls > cut; -1 disables the cut" };
166+ Configurable<int > cfgITSNClsInnerBarrel{" cfgITSNClsInnerBarrel" , -1 , " Require inner-barrel ITS NCls > cut; -1 disables the cut" };
167+
155168 Configurable<float > cfgRapidityMinCut{" cfgRapidityMinCut" , -0.5 , " Rapidity cut for tracks" };
156169 Configurable<float > cfgRapidityMaxCut{" cfgRapidityMaxCut" , 0.5 , " Rapidity cut for tracks" };
157170
@@ -315,6 +328,8 @@ struct Xi1530Analysisqa {
315328 Configurable<float > cfgMaxRot{" cfgMaxRot" , 7.0 * constants::math::PI / 6.0 , " Maximum of rotation" };
316329 Configurable<bool > cfgRotPion{" cfgRotPion" , true , " Rotate pion" };
317330 Configurable<int > cfgNrotBkg{" cfgNrotBkg" , 4 , " Number of rotated copies (background) per each original candidate" };
331+
332+ Configurable<bool > cMCInjection{" cMCInjection" , true , " Select generated MC parents with native status -11 (production-specific injection tag)" };
318333 } additionalConfig;
319334
320335 // *//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//
@@ -589,7 +604,13 @@ struct Xi1530Analysisqa {
589604 if (std::abs (track.dcaXY ()) >= dcaXYCut || std::abs (track.dcaZ ()) >= dcaZCut) {
590605 return false ;
591606 }
592- if constexpr (!IsResoMicrotrack) {
607+ if constexpr (IsResoMicrotrack) {
608+ if (track.itsNCls () <= primarytrackConfig.cfgITSNCls ||
609+ track.itsNClsInnerBarrel () <= primarytrackConfig.cfgITSNClsInnerBarrel ||
610+ track.tpcNClsCrossedRows () <= primarytrackConfig.cfgTPCRows ) {
611+ return false ;
612+ }
613+ } else {
593614 if (track.tpcNClsFound () <= primarytrackConfig.cfgTPCcluster ) {
594615 return false ;
595616 }
@@ -808,9 +829,25 @@ struct Xi1530Analysisqa {
808829 return properLifetime;
809830 }
810831
832+ // Build once per selected collision, not once per reconstructed pair.
833+ std::unordered_set<int > getInjectedMotherIds (aod::ResoMCParents_001 const & parents)
834+ {
835+ std::unordered_set<int > motherIds;
836+ if (!additionalConfig.cMCInjection ) {
837+ return motherIds;
838+ }
839+ for (auto const & parent : parents) {
840+ if (std::abs (parent.pdgCode ()) == kXiStar && IsInjectedParent (parent)) {
841+ motherIds.insert (parent.originalMcParticleId ());
842+ }
843+ }
844+ return motherIds;
845+ }
846+
811847 template <bool IsResoMicrotrack, bool IsMC, bool IsMix, typename CollisionType, typename centType, typename TracksType, typename TracksTypeCasc>
812848 void fillHistograms (const CollisionType& collision, const centType& inCent, const TracksType& dTracks1, const TracksTypeCasc& dTracks2,
813- const MixingCollision* cascadeCollision = nullptr ) // Order: ResoColl, ResoTrack, ResoCascTrack
849+ const MixingCollision* cascadeCollision = nullptr ,
850+ const std::unordered_set<int >& injectedMotherIds = {}) // Order: ResoColl, ResoTrack, ResoCascTrack
814851 {
815852 auto cent = inCent;
816853
@@ -1194,6 +1231,9 @@ struct Xi1530Analysisqa {
11941231 if (xiCand.motherId () < 0 || pionCand.motherId () != xiCand.motherId ()) {
11951232 continue ;
11961233 }
1234+ if (additionalConfig.cMCInjection && !injectedMotherIds.contains (xiCand.motherId ())) {
1235+ continue ;
1236+ }
11971237 auto lResonancePtMC = xiCand.motherPt ();
11981238 if (additionalConfig.cUseTruthRapidity ) {
11991239 const bool passesTruthRapidity = xiCand.motherRap () > primarytrackConfig.cfgRapidityMinCut && xiCand.motherRap () < primarytrackConfig.cfgRapidityMaxCut ;
@@ -1352,7 +1392,8 @@ struct Xi1530Analysisqa {
13521392 // Calculate numerator for the Acceptance x Efficiency
13531393 void processMC (ResoMCCols::iterator const & resoCollision,
13541394 soa::Join<aod::ResoCascades, aod::ResoMCCascades> const & cascTracks,
1355- soa::Join<aod::ResoTracks, aod::ResoTrackTracks, aod::ResoMCTracks> const & resoTracks)
1395+ soa::Join<aod::ResoTracks, aod::ResoTrackTracks, aod::ResoMCTracks> const & resoTracks,
1396+ aod::ResoMCParents_001 const & resoParents)
13561397 {
13571398 auto inCent = resoCollision.cent ();
13581399 const auto multiplicity = resoCollision.multiplicity ();
@@ -1365,12 +1406,14 @@ struct Xi1530Analysisqa {
13651406 if (histoConfig.multQA ) {
13661407 histos.fill (HIST (" multQA/h2MultCent" ), inCent, multiplicity);
13671408 }
1368- fillHistograms<false , true , false >(resoCollision, inCent, resoTracks, cascTracks);
1409+ const auto injectedMotherIds = getInjectedMotherIds (resoParents);
1410+ fillHistograms<false , true , false >(resoCollision, inCent, resoTracks, cascTracks, nullptr , injectedMotherIds);
13691411 }
13701412
13711413 void processMCMicro (ResoMCCols::iterator const & resoCollision,
13721414 soa::Join<aod::ResoCascades, aod::ResoMCCascades> const & cascTracks,
1373- soa::Join<ResoMicroTracks, aod::ResoMCMicroTracks_001> const & resoTracks)
1415+ soa::Join<ResoMicroTracks, aod::ResoMCMicroTracks_001> const & resoTracks,
1416+ aod::ResoMCParents_001 const & reParent)
13741417 {
13751418 if ((additionalConfig.cRecoINELgt0 && !resoCollision.isRecINELgt0 ()) ||
13761419 (additionalConfig.cMCINELgt0 && !resoCollision.isINELgt0 ()) ||
@@ -1380,7 +1423,8 @@ struct Xi1530Analysisqa {
13801423 if (histoConfig.multQA ) {
13811424 histos.fill (HIST (" multQA/h2MultCent" ), resoCollision.cent (), resoCollision.multiplicity ());
13821425 }
1383- fillHistograms<true , true , false >(resoCollision, resoCollision.cent (), resoTracks, cascTracks);
1426+ const auto injectedMotherIds = getInjectedMotherIds (reParent);
1427+ fillHistograms<true , true , false >(resoCollision, resoCollision.cent (), resoTracks, cascTracks, nullptr , injectedMotherIds);
13841428 }
13851429
13861430 // Calculate denominator for the Acceptance x Efficiency, actually it is not Trueth info...
@@ -1402,6 +1446,9 @@ struct Xi1530Analysisqa {
14021446 if (std::abs (part.pdgCode ()) != kXiStar ) {
14031447 continue ;
14041448 }
1449+ if (additionalConfig.cMCInjection && !IsInjectedParent (part)) {
1450+ continue ;
1451+ }
14051452 if ((part.y () <= primarytrackConfig.cfgRapidityMinCut ) || (part.y () >= primarytrackConfig.cfgRapidityMaxCut )) {
14061453 continue ;
14071454 }
0 commit comments