@@ -148,6 +148,7 @@ enum TrackLabels {
148148 kPassV0DauTrackSel ,
149149 kPassV0KinCuts ,
150150 kPassV0TopoSel ,
151+ kAllV0SelPassed ,
151152 kAllSelPassed ,
152153 kNotPrimaryLambda ,
153154 kNotSecondaryLambda ,
@@ -259,6 +260,18 @@ struct LambdaTableProducer {
259260 Configurable<bool > cV0TypeSelFlag{" cV0TypeSelFlag" , false , " V0 Type Selection Flag" };
260261 Configurable<int > cV0TypeSelection{" cV0TypeSelection" , 1 , " V0 Type Selection" };
261262
263+ // Cascade V0
264+ Configurable<bool > cRemoveCascLambda{" cRemoveCascLambda" , false , " Remove Cascade V0s" };
265+ Configurable<float > cMinCascDcaPosToPV{" cMinCascDcaPosToPV" , 0.03 , " DCA Casc Pos To PV" };
266+ Configurable<float > cMinCascDcaNegToPV{" cMinCascDcaNegToPV" , 0.03 , " DCA Casc Neg To PV" };
267+ Configurable<float > cMinCascDcaBachToPV{" cMinCascDcaBachToPV" , 0.03 , " DCA Casc Bach To PV" };
268+ Configurable<float > cMaxCascDcaDaughters{" cMaxCascDcaDaughters" , 1.0 , " DCA Casc Dau at Casc Decay Vtx" };
269+ Configurable<float > cMinCascRadius{" cMinCascRadius" , 0.4 , " Casc Decay Radius" };
270+ Configurable<float > cMinCascV0Radius{" cMinCascV0Radius" , 0.9 , " Casc V0 Decay Radius" };
271+ Configurable<float > cMinCascCosPA{" cMinCascCosPA" , 0.99 , " Casc CosThetaPA" };
272+ Configurable<float > cMinCascV0CosPA{" cMinCascV0CosPA" , 0.99 , " Casc V0 CosThetaPA" };
273+ Configurable<float > cCascMassWindow{" cCascMassWindow" , 0.005 , " Casc Mass Window" };
274+
262275 // V0s MC
263276 Configurable<bool > cHasMcFlag{" cHasMcFlag" , true , " Has Mc Tag" };
264277 Configurable<bool > cSelectTrueLambda{" cSelectTrueLambda" , true , " Select True Lambda" };
@@ -336,6 +349,8 @@ struct LambdaTableProducer {
336349 const AxisSpec axisNsigma (401 , -10.025 , 10.025 , {" n#sigma" });
337350 const AxisSpec axisdEdx (360 , 20 , 200 , " #frac{dE}{dx}" );
338351
352+ const AxisSpec axisCascMass{100 , 1.28 , 1.38 , " M_{#Xi}" };
353+
339354 // Create Histograms.
340355 // Event histograms
341356 histos.add (" Events/h1f_collisions_info" , " # of Collisions" , kTH1F , {axisCols});
@@ -380,6 +395,9 @@ struct LambdaTableProducer {
380395 histos.add (" QA/Lambda/h2f_pos_prong_tpc_nsigma_pi_vs_p" , " TPC n#sigma Pos Prong" , kTH2F , {axisMomPID, axisNsigma});
381396 histos.add (" QA/Lambda/h2f_neg_prong_tpc_nsigma_pi_vs_p" , " TPC n#sigma Neg Prong" , kTH2F , {axisMomPID, axisNsigma});
382397
398+ histos.add (" QA/Casc/hMassBeforeCuts" , " Xi Mass" , kTH1F , {axisCascMass});
399+ histos.add (" QA/Casc/hMass" , " Xi Mass" , kTH1F , {axisCascMass});
400+
383401 // Kinematic Histograms
384402 histos.add (" McRec/Lambda/hPt" , " Transverse Momentum" , kTH1F , {axisV0Pt});
385403 histos.add (" McRec/Lambda/hEta" , " Pseudorapidity" , kTH1F , {axisV0Eta});
@@ -391,7 +409,7 @@ struct LambdaTableProducer {
391409 histos.addClone (" McRec/Lambda/" , " McRec/AntiLambda/" );
392410
393411 // MC Generated Histograms
394- if (doprocessMCRun3 || doprocessMCRun2 || doprocessRecoGen ) {
412+ if (doprocessMCRun3 || doprocessMCRun2) {
395413 // McReco Histos
396414 histos.add (" Tracks/h2f_tracks_pid_before_sel" , " PIDs" , kTH2F , {axisPID, axisV0Pt});
397415 histos.add (" Tracks/h2f_tracks_pid_after_sel" , " PIDs" , kTH2F , {axisPID, axisV0Pt});
@@ -446,6 +464,7 @@ struct LambdaTableProducer {
446464 histos.get <TH1>(HIST (" Tracks/h1f_tracks_info" ))->GetXaxis ()->SetBinLabel (TrackLabels::kPassV0DauTrackSel , " kPassV0DauTrackSel" );
447465 histos.get <TH1>(HIST (" Tracks/h1f_tracks_info" ))->GetXaxis ()->SetBinLabel (TrackLabels::kPassV0KinCuts , " kPassV0KinCuts" );
448466 histos.get <TH1>(HIST (" Tracks/h1f_tracks_info" ))->GetXaxis ()->SetBinLabel (TrackLabels::kPassV0TopoSel , " kPassV0TopoSel" );
467+ histos.get <TH1>(HIST (" Tracks/h1f_tracks_info" ))->GetXaxis ()->SetBinLabel (TrackLabels::kAllV0SelPassed , " kAllV0SelPassed" );
449468 histos.get <TH1>(HIST (" Tracks/h1f_tracks_info" ))->GetXaxis ()->SetBinLabel (TrackLabels::kAllSelPassed , " kAllSelPassed" );
450469 histos.get <TH1>(HIST (" Tracks/h1f_tracks_info" ))->GetXaxis ()->SetBinLabel (TrackLabels::kEffCorrPt , " kEffCorrPt" );
451470 histos.get <TH1>(HIST (" Tracks/h1f_tracks_info" ))->GetXaxis ()->SetBinLabel (TrackLabels::kEffCorrPtRap , " kEffCorrPtRap" );
@@ -790,6 +809,57 @@ struct LambdaTableProducer {
790809 return true ;
791810 }
792811
812+ // Remove Lambda from Xi ---> Lambda Pi
813+ template <typename C, typename V, typename X, typename T>
814+ bool removeCascLambda (C const & collision, V const & v0, X const & cascs, T const &)
815+ {
816+ // Loop over cascades
817+ for (auto const & casc : cascs) {
818+ // cascade daughters
819+ auto cascposdau = casc.template posTrack_as <T>();
820+ auto cascnegdau = casc.template negTrack_as <T>();
821+ auto bachelor = casc.template bachelor_as <T>();
822+
823+ // V0 daughters
824+ auto v0posdau = v0.template posTrack_as <T>();
825+ auto v0negdau = v0.template negTrack_as <T>();
826+
827+ // topological selection
828+ if (std::abs (casc.dcapostopv ()) <= cMinCascDcaPosToPV ||
829+ std::abs (casc.dcanegtopv ()) <= cMinCascDcaNegToPV ||
830+ std::abs (casc.dcabachtopv ()) <= cMinCascDcaBachToPV ||
831+ casc.dcaV0daughters () >= cMaxV0DcaDaughters ||
832+ casc.dcacascdaughters () >= cMaxCascDcaDaughters ||
833+ casc.cascradius () <= cMinCascRadius ||
834+ casc.v0radius () <= cMinCascV0Radius ||
835+ casc.casccosPA (collision.posX (), collision.posY (), collision.posZ ()) <= cMinCascCosPA ||
836+ casc.v0cosPA (collision.posX (), collision.posY (), collision.posZ ()) <= cMinCascV0CosPA ||
837+ std::abs (cascposdau.eta ()) >= cTrackEtaCut ||
838+ std::abs (cascnegdau.eta ()) >= cTrackEtaCut ||
839+ std::abs (bachelor.eta ()) >= cTrackEtaCut) {
840+ continue ;
841+ }
842+
843+ histos.fill (HIST (" QA/Casc/hMassBeforeCuts" ), casc.mXi ());
844+
845+ // apply mass window selection to Xi
846+ if (std::abs (casc.mXi () - MassXiMinus) >= cCascMassWindow) {
847+ continue ;
848+ }
849+
850+ histos.fill (HIST (" QA/Casc/hMass" ), casc.mXi ());
851+
852+ // Check if the daughters of cascades match with v0 daughters
853+ // The "OR" Logic is Temperory, we can further see the effect of "AND" Logic
854+ if (v0posdau.index () == cascposdau.index () || v0negdau.index () == cascnegdau.index ()) {
855+ return true ;
856+ }
857+ }
858+
859+ // No Lambda from Cascade
860+ return false ;
861+ }
862+
793863 template <typename T>
794864 bool getMcMatch (T const & vrec, T const & vgen)
795865 {
@@ -943,8 +1013,8 @@ struct LambdaTableProducer {
9431013 }
9441014
9451015 // Reconstructed Level Tables
946- template <RunType run, DMCType dmc, typename C, typename V, typename T>
947- void fillLambdaRecoTables (C const & collision, V const & v0tracks, T const & tracks)
1016+ template <RunType run, DMCType dmc, typename C, typename V, typename T, typename X >
1017+ void fillLambdaRecoTables (C const & collision, V const & v0tracks, T const & tracks, X const & cascs )
9481018 {
9491019 // Total Collisions
9501020 histos.fill (HIST (" Events/h1f_collisions_info" ), kTotCol );
@@ -966,6 +1036,7 @@ struct LambdaTableProducer {
9661036 ParticleType v0Type = kLambda ;
9671037 float mass = 0 ., corr_fact = 1 .;
9681038
1039+ // Loop Over V0s
9691040 for (auto const & v0 : v0tracks) {
9701041 // check for corresponding MCGen Particle
9711042 if constexpr (dmc == kMC ) {
@@ -988,6 +1059,13 @@ struct LambdaTableProducer {
9881059 continue ;
9891060 }
9901061
1062+ histos.fill (HIST (" Tracks/h1f_tracks_info" ), kAllV0SelPassed );
1063+
1064+ // Remove Lambda V0 coming from Xi -> Lambda Pi
1065+ if (cRemoveCascLambda && removeCascLambda (collision, v0, cascs, tracks)) {
1066+ continue ;
1067+ }
1068+
9911069 histos.fill (HIST (" Tracks/h1f_tracks_info" ), kAllSelPassed );
9921070
9931071 // we have v0 as lambda
@@ -1145,8 +1223,8 @@ struct LambdaTableProducer {
11451223 }
11461224 }
11471225
1148- template <RunType run, DMCType dmc, typename M, typename C, typename V, typename T, typename P>
1149- void analyzeMcRecoGen (M const & mcCollision, C const & collisions, V const & V0s, T const & tracks, P const & mcParticles)
1226+ template <RunType run, DMCType dmc, typename M, typename C, typename V, typename T, typename X, typename P>
1227+ void analyzeMcRecoGen (M const & mcCollision, C const & collisions, V const & V0s, T const & tracks, X const & cascs, P const & mcParticles)
11501228 {
11511229 // Number of Rec Collisions Associated to the McGen Collision
11521230 int nRecCols = collisions.size ();
@@ -1173,7 +1251,7 @@ struct LambdaTableProducer {
11731251 histos.fill (HIST (" McGen/h2f_collision_posZ" ), mcCollision.posZ (), collisions.begin ().posZ ());
11741252 histos.fill (HIST (" McGen/h2f_collision_cent" ), mcCollision.centFT0M (), cent);
11751253 auto v0Tracks = V0s.sliceBy (perCollision, collisions.begin ().globalIndex ());
1176- fillLambdaRecoTables<run, dmc>(collisions.begin (), v0Tracks, tracks);
1254+ fillLambdaRecoTables<run, dmc>(collisions.begin (), v0Tracks, tracks, cascs );
11771255 fillLambdaMcGenTables<run>(mcCollision, mcParticles);
11781256 }
11791257
@@ -1182,92 +1260,45 @@ struct LambdaTableProducer {
11821260
11831261 using CollisionsRun3 = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Ms>;
11841262 using CollisionsRun2 = soa::Join<aod::Collisions, aod::EvSels, aod::CentRun2V0Ms>;
1263+ using CascsTracks = aod::CascDataExt;
11851264 using Tracks = soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA, aod::pidTPCPi, aod::pidTPCPr, aod::pidTOFPi, aod::pidTOFPr>;
11861265 using McV0Tracks = soa::Join<aod::V0Datas, aod::McV0Labels>;
1266+ using McCascTracks = soa::Join<aod::CascDataExt, aod::McCascLabels>;
11871267 using TracksMC = soa::Join<Tracks, aod::McTrackLabels>;
11881268
1189- void processDataRun3 (CollisionsRun3::iterator const & collision, aod::V0Datas const & V0s, Tracks const & tracks)
1269+ void processDataRun3 (CollisionsRun3::iterator const & collision, aod::V0Datas const & V0s, Tracks const & tracks, CascsTracks const & cascs )
11901270 {
1191- fillLambdaRecoTables<kRun3 , kData >(collision, V0s, tracks);
1271+ fillLambdaRecoTables<kRun3 , kData >(collision, V0s, tracks, cascs );
11921272 }
11931273
11941274 PROCESS_SWITCH (LambdaTableProducer, processDataRun3, " Process for Run3 DATA" , true );
11951275
1196- void processDataRun2 (CollisionsRun2::iterator const & collision, aod::V0Datas const & V0s, Tracks const & tracks)
1276+ void processDataRun2 (CollisionsRun2::iterator const & collision, aod::V0Datas const & V0s, Tracks const & tracks, CascsTracks const & cascs )
11971277 {
1198- fillLambdaRecoTables<kRun2 , kData >(collision, V0s, tracks);
1278+ fillLambdaRecoTables<kRun2 , kData >(collision, V0s, tracks, cascs );
11991279 }
12001280
12011281 PROCESS_SWITCH (LambdaTableProducer, processDataRun2, " Process for Run2 DATA" , false );
12021282
12031283 void processMCRun3 (soa::Join<aod::McCollisions, aod::McCentFT0Ms>::iterator const & mcCollision,
12041284 soa::SmallGroups<soa::Join<CollisionsRun3, aod::McCollisionLabels>> const & collisions,
1205- McV0Tracks const & V0s, TracksMC const & tracks,
1285+ McV0Tracks const & V0s, TracksMC const & tracks, McCascTracks const & cascs,
12061286 aod::McParticles const & mcParticles)
12071287 {
1208- analyzeMcRecoGen<kRun3 , kMC >(mcCollision, collisions, V0s, tracks, mcParticles);
1288+ analyzeMcRecoGen<kRun3 , kMC >(mcCollision, collisions, V0s, tracks, cascs, mcParticles);
12091289 }
12101290
12111291 PROCESS_SWITCH (LambdaTableProducer, processMCRun3, " Process for Run3 MC RecoGen" , false );
12121292
12131293 void processMCRun2 (soa::Join<aod::McCollisions, aod::McCentFT0Ms>::iterator const & mcCollision,
12141294 soa::SmallGroups<soa::Join<CollisionsRun2, aod::McCollisionLabels>> const & collisions,
1215- McV0Tracks const & V0s, TracksMC const & tracks,
1295+ McV0Tracks const & V0s, TracksMC const & tracks, McCascTracks const & cascs,
12161296 aod::McParticles const & mcParticles)
12171297 {
1218- analyzeMcRecoGen<kRun2 , kMC >(mcCollision, collisions, V0s, tracks, mcParticles);
1298+ analyzeMcRecoGen<kRun2 , kMC >(mcCollision, collisions, V0s, tracks, cascs, mcParticles);
12191299 }
12201300
12211301 PROCESS_SWITCH (LambdaTableProducer, processMCRun2, " Process for Run2 MC RecoGen" , false );
1222-
1223- void processRecoGen (soa::Join<CollisionsRun3, aod::McCollisionLabels>::iterator const & collision,
1224- soa::Join<aod::McCollisions, aod::McCentFT0Ms> const &,
1225- McV0Tracks const & V0s, TracksMC const & tracks,
1226- aod::McParticles const & mcParticles)
1227- {
1228- // Select Collision
1229- if (!selCollision<kRun3 >(collision) || !collision.has_mcCollision ()) {
1230- return ;
1231- }
1232-
1233- // Fill Reco Table
1234- fillLambdaRecoTables<kRun3 , kMC >(collision, V0s, tracks);
1235-
1236- // Get Generator Level Collision and Particles
1237- auto mcCollision = collision.template mcCollision_as <soa::Join<aod::McCollisions, aod::McCentFT0Ms>>();
1238- auto mcGenParticles = mcParticles.sliceByCached (aod::mcparticle::mcCollisionId, mcCollision.globalIndex (), cache);
1239-
1240- // Fill Gen Table
1241- lambdaMCGenCollisionTable (mcCollision.centFT0M (), mcCollision.posX (), mcCollision.posY (), mcCollision.posZ ());
1242-
1243- // initialize track objects
1244- ParticleType v0Type = kLambda ;
1245- for (auto const & mcpart : mcGenParticles) {
1246- if (!mcpart.isPhysicalPrimary ()) {
1247- continue ;
1248- }
1249-
1250- if (std::abs (mcpart.y ()) > cMaxV0Rap) {
1251- continue ;
1252- }
1253-
1254- // check for Lambda first
1255- if (mcpart.pdgCode () == kLambda0 ) {
1256- v0Type = kLambda ;
1257- } else if (mcpart.pdgCode () == kLambda0Bar ) {
1258- v0Type = kAntiLambda ;
1259- } else {
1260- continue ;
1261- }
1262-
1263- // Fill Lambda McGen Table
1264- lambdaMCGenTrackTable (lambdaMCGenCollisionTable.lastIndex (), mcpart.px (), mcpart.py (), mcpart.pz (),
1265- mcpart.pt (), mcpart.eta (), mcpart.phi (), mcpart.y (), RecoDecay::m (mcpart.p (), mcpart.e ()),
1266- 99 ., -97 ., (int8_t )v0Type, -999 ., -999 ., 1 .);
1267- }
1268- }
1269-
1270- PROCESS_SWITCH (LambdaTableProducer, processRecoGen, " Process for MC RecoGen" , false );
12711302};
12721303
12731304struct LambdaTracksExtProducer {
0 commit comments