@@ -54,7 +54,7 @@ using FullTracksExtWithPID = soa::Join<aod::Tracks, aod::TracksExtra, aod::Track
5454using FullTracksExtIUWithPID = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksCovIU, aod::TracksDCA, aod::pidTPCPi, aod::pidTPCKa, aod::pidTPCPr>;
5555
5656// Add a column to the cascdataext table: IsSelected.
57- // 0 = not selected, 1 = Xi, 2 = Omega , 3 = both
57+ // 0 = not selected, 1 = Xi, 2 = both , 3 = Omega
5858namespace o2 ::aod
5959{
6060namespace cascadeflags
@@ -75,44 +75,119 @@ struct cascadeSelector {
7575 Configurable<float > tpcNsigmaPion{" tpcNsigmaPion" , 3 , " TPC NSigma pion <- lambda" };
7676 Configurable<int > minTPCCrossedRows{" minTPCCrossedRows" , 80 , " min N TPC crossed rows" }; // TODO: finetune! 80 > 159/2, so no split tracks?
7777 Configurable<int > minITSClusters{" minITSClusters" , 4 , " minimum number of ITS clusters" };
78- // Configurable<bool> doTPConly{"doTPConly", false, "use TPC-only tracks"}; // TODO: maybe do this for high pT only? as cascade decays after IB
7978
8079 // Selection criteria - compatible with core wagon autodetect - copied from cascadeanalysis.cxx
8180 // *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*
82- Configurable<double > v0setting_cospa{" v0setting_cospa" , 0.95 , " v0setting_cospa" };
81+ Configurable<double > v0setting_cospa{" v0setting_cospa" , 0.995 , " v0setting_cospa" };
8382 Configurable<float > v0setting_dcav0dau{" v0setting_dcav0dau" , 1.0 , " v0setting_dcav0dau" };
8483 Configurable<float > v0setting_dcapostopv{" v0setting_dcapostopv" , 0.1 , " v0setting_dcapostopv" };
8584 Configurable<float > v0setting_dcanegtopv{" v0setting_dcanegtopv" , 0.1 , " v0setting_dcanegtopv" };
8685 Configurable<float > v0setting_radius{" v0setting_radius" , 0.9 , " v0setting_radius" };
8786 Configurable<double > cascadesetting_cospa{" cascadesetting_cospa" , 0.95 , " cascadesetting_cospa" };
8887 Configurable<float > cascadesetting_dcacascdau{" cascadesetting_dcacascdau" , 1.0 , " cascadesetting_dcacascdau" };
89- Configurable<float > cascadesetting_dcabachtopv{" cascadesetting_dcabachtopv" , 0.1 , " cascadesetting_dcabachtopv" };
90- Configurable<float > cascadesetting_cascradius{" cascadesetting_cascradius" , 0.5 , " cascadesetting_cascradius" };
88+ Configurable<float > cascadesetting_dcabachtopv{" cascadesetting_dcabachtopv" , 0.05 , " cascadesetting_dcabachtopv" };
89+ Configurable<float > cascadesetting_cascradius{" cascadesetting_cascradius" , 0.9 , " cascadesetting_cascradius" };
9190 Configurable<float > cascadesetting_v0masswindow{" cascadesetting_v0masswindow" , 0.01 , " cascadesetting_v0masswindow" };
9291 Configurable<float > cascadesetting_mindcav0topv{" cascadesetting_mindcav0topv" , 0.01 , " cascadesetting_mindcav0topv" };
9392 // *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*
9493
94+ // TODO: variables as function of Omega mass, only do Xi for now
95+ AxisSpec vertexAxis = {200 , -10 .0f , 10 .0f , " cm" };
96+ AxisSpec dcaAxis = {100 , 0 .0f , 10 .0f , " cm" };
97+ AxisSpec invMassAxis = {1000 , 1 .0f , 2 .0f , " Inv. Mass (GeV/c^{2})" };
98+ AxisSpec ptAxis = {100 , 0 , 15 , " #it{p}_{T}" };
99+ HistogramRegistry registry{
100+ " registry" ,
101+ {
102+ // basic selection variables
103+ {" hV0Radius" , " hV0Radius" , {HistType::kTH3F , {{100 , 0 .0f , 100 .0f , " cm" }, invMassAxis, ptAxis}}},
104+ {" hCascRadius" , " hCascRadius" , {HistType::kTH3F , {{100 , 0 .0f , 100 .0f , " cm" }, invMassAxis, ptAxis}}},
105+ {" hV0CosPA" , " hV0CosPA" , {HistType::kTH3F , {{100 , 0 .95f , 1 .0f }, invMassAxis, ptAxis}}},
106+ {" hCascCosPA" , " hCascCosPA" , {HistType::kTH3F , {{100 , 0 .95f , 1 .0f }, invMassAxis, ptAxis}}},
107+ {" hDCAPosToPV" , " hDCAPosToPV" , {HistType::kTH3F , {vertexAxis, invMassAxis, ptAxis}}},
108+ {" hDCANegToPV" , " hDCANegToPV" , {HistType::kTH3F , {vertexAxis, invMassAxis, ptAxis}}},
109+ {" hDCABachToPV" , " hDCABachToPV" , {HistType::kTH3F , {vertexAxis, invMassAxis, ptAxis}}},
110+ {" hDCAV0ToPV" , " hDCAV0ToPV" , {HistType::kTH3F , {vertexAxis, invMassAxis, ptAxis}}},
111+ {" hDCAV0Dau" , " hDCAV0Dau" , {HistType::kTH3F , {dcaAxis, invMassAxis, ptAxis}}},
112+ {" hDCACascDau" , " hDCACascDau" , {HistType::kTH3F , {dcaAxis, invMassAxis, ptAxis}}},
113+ {" hLambdaMass" , " hLambdaMass" , {HistType::kTH3F , {{100 , 1 .0f , 1 .2f , " Inv. Mass (GeV/c^{2})" }, invMassAxis, ptAxis}}},
114+
115+ // invariant mass per cut, start with Xi
116+ {" hMassXi0" , " Xi inv mass before selections" , {HistType::kTH2F , {invMassAxis, ptAxis}}},
117+ {" hMassXi1" , " Xi inv mass after TPCnCrossedRows cut" , {HistType::kTH2F , {invMassAxis, ptAxis}}},
118+ {" hMassXi2" , " Xi inv mass after ITSnClusters cut" , {HistType::kTH2F , {invMassAxis, ptAxis}}},
119+ {" hMassXi3" , " Xi inv mass after topo cuts" , {HistType::kTH2F , {invMassAxis, ptAxis}}},
120+ {" hMassXi4" , " Xi inv mass after V0 daughters PID cut" , {HistType::kTH2F , {invMassAxis, ptAxis}}},
121+ {" hMassXi5" , " Xi inv mass after bachelor PID cut" , {HistType::kTH2F , {invMassAxis, ptAxis}}},
122+
123+ // ITS & TPC clusters, with Xi inv mass
124+ {" hTPCnCrossedRowsPos" , " hTPCnCrossedRowsPos" , {HistType::kTH3F , {{160 , -0.5 , 159.5 , " TPC crossed rows" }, invMassAxis, ptAxis}}},
125+ {" hTPCnCrossedRowsNeg" , " hTPCnCrossedRowsNeg" , {HistType::kTH3F , {{160 , -0.5 , 159.5 , " TPC crossed rows" }, invMassAxis, ptAxis}}},
126+ {" hTPCnCrossedRowsBach" , " hTPCnCrossedRowsBach" , {HistType::kTH3F , {{160 , -0.5 , 159.5 , " TPC crossed rows" }, invMassAxis, ptAxis}}},
127+ {" hITSnClustersPos" , " hITSnClustersPos" , {HistType::kTH3F , {{8 , -0.5 , 7.5 , " number of ITS clusters" }, invMassAxis, ptAxis}}},
128+ {" hITSnClustersNeg" , " hITSnClustersNeg" , {HistType::kTH3F , {{8 , -0.5 , 7.5 , " number of ITS clusters" }, invMassAxis, ptAxis}}},
129+ {" hITSnClustersBach" , " hITSnClustersBach" , {HistType::kTH3F , {{8 , -0.5 , 7.5 , " number of ITS clusters" }, invMassAxis, ptAxis}}},
130+ },
131+ };
132+
133+ // Keep track of which selections the candidates pass
134+ void init (InitContext const &)
135+ {
136+ auto h = registry.add <TH1>(" hSelectionStatus" , " hSelectionStatus" , HistType::kTH1I , {{10 , 0 , 10 , " status" }});
137+ h->GetXaxis ()->SetBinLabel (1 , " All" );
138+ h->GetXaxis ()->SetBinLabel (2 , " nTPC OK" );
139+ h->GetXaxis ()->SetBinLabel (3 , " nITS OK" );
140+ h->GetXaxis ()->SetBinLabel (4 , " Topo OK" );
141+ h->GetXaxis ()->SetBinLabel (5 , " V0 PID OK" );
142+ h->GetXaxis ()->SetBinLabel (6 , " Bach PID OK" );
143+ }
95144 void process (soa::Join<aod::Collisions, aod::EvSels>::iterator const & collision, aod::CascDataExt const & Cascades, FullTracksExtIUWithPID const &)
96145 {
97146 for (auto & casc : Cascades) {
98- // TODO: make QA histo with info on where cascades fail selections
99147
100- // Let's try to do some PID & track quality cuts
101148 // these are the tracks:
102149 auto bachTrack = casc.bachelor_as <FullTracksExtIUWithPID>();
103150 auto posTrack = casc.posTrack_as <FullTracksExtIUWithPID>();
104151 auto negTrack = casc.negTrack_as <FullTracksExtIUWithPID>();
105152
153+ // topo variables before cuts:
154+ registry.fill (HIST (" hV0Radius" ), casc.v0radius (), casc.mXi (), casc.pt ());
155+ registry.fill (HIST (" hCascRadius" ), casc.cascradius (), casc.mXi (), casc.pt ());
156+ registry.fill (HIST (" hV0CosPA" ), casc.v0cosPA (collision.posX (), collision.posY (), collision.posZ ()), casc.mXi (), casc.pt ());
157+ registry.fill (HIST (" hCascCosPA" ), casc.casccosPA (collision.posX (), collision.posY (), collision.posZ ()), casc.mXi (), casc.pt ());
158+ registry.fill (HIST (" hDCAPosToPV" ), casc.dcapostopv (), casc.mXi (), casc.pt ());
159+ registry.fill (HIST (" hDCANegToPV" ), casc.dcanegtopv (), casc.mXi (), casc.pt ());
160+ registry.fill (HIST (" hDCABachToPV" ), casc.dcabachtopv (), casc.mXi (), casc.pt ());
161+ registry.fill (HIST (" hDCAV0ToPV" ), casc.dcav0topv (collision.posX (), collision.posY (), collision.posZ ()), casc.mXi (), casc.pt ());
162+ registry.fill (HIST (" hDCAV0Dau" ), casc.dcaV0daughters (), casc.mXi (), casc.pt ());
163+ registry.fill (HIST (" hDCACascDau" ), casc.dcacascdaughters (), casc.mXi (), casc.pt ());
164+ registry.fill (HIST (" hLambdaMass" ), casc.mLambda (), casc.mXi (), casc.pt ());
165+
166+ registry.fill (HIST (" hITSnClustersPos" ), posTrack.itsNCls (), casc.mXi (), casc.pt ());
167+ registry.fill (HIST (" hITSnClustersNeg" ), negTrack.itsNCls (), casc.mXi (), casc.pt ());
168+ registry.fill (HIST (" hITSnClustersBach" ), bachTrack.itsNCls (), casc.mXi (), casc.pt ());
169+ registry.fill (HIST (" hTPCnCrossedRowsPos" ), posTrack.tpcNClsCrossedRows (), casc.mXi (), casc.pt ());
170+ registry.fill (HIST (" hTPCnCrossedRowsNeg" ), negTrack.tpcNClsCrossedRows (), casc.mXi (), casc.pt ());
171+ registry.fill (HIST (" hTPCnCrossedRowsBach" ), bachTrack.tpcNClsCrossedRows (), casc.mXi (), casc.pt ());
172+
173+ registry.fill (HIST (" hSelectionStatus" ), 0 ); // all the cascade before selections
174+ registry.fill (HIST (" hMassXi0" ), casc.mXi (), casc.pt ());
175+
106176 // TPC N crossed rows
107177 if (posTrack.tpcNClsCrossedRows () < minTPCCrossedRows || negTrack.tpcNClsCrossedRows () < minTPCCrossedRows || bachTrack.tpcNClsCrossedRows () < minTPCCrossedRows) {
108178 cascflags (0 );
109179 continue ;
110180 }
181+ registry.fill (HIST (" hSelectionStatus" ), 1 ); // passes nTPC crossed rows
182+ registry.fill (HIST (" hMassXi1" ), casc.mXi (), casc.pt ());
183+
111184 // ITS N clusters
112185 if (posTrack.itsNCls () < minITSClusters || negTrack.itsNCls () < minITSClusters || bachTrack.itsNCls () < minITSClusters) {
113186 cascflags (0 );
114187 continue ;
115188 }
189+ registry.fill (HIST (" hSelectionStatus" ), 2 ); // passes nITS clusters
190+ registry.fill (HIST (" hMassXi2" ), casc.mXi (), casc.pt ());
116191
117192 // // TOPO CUTS //// TODO: improve!
118193 double pvx = collision.posX ();
@@ -128,10 +203,12 @@ struct cascadeSelector {
128203 cascflags (0 );
129204 continue ;
130205 }
206+ registry.fill (HIST (" hSelectionStatus" ), 3 ); // passes topo
207+ registry.fill (HIST (" hMassXi3" ), casc.mXi (), casc.pt ());
131208
132209 // TODO: TOF (for pT > 2 GeV per track?)
133210
134- // // TPC ////
211+ // // TPC PID ////
135212 // Lambda check
136213 if (casc.sign () < 0 ) {
137214 // Proton check:
@@ -156,17 +233,25 @@ struct cascadeSelector {
156233 continue ;
157234 }
158235 }
236+ registry.fill (HIST (" hSelectionStatus" ), 4 ); // fails at V0 daughters PID
237+ registry.fill (HIST (" hMassXi4" ), casc.mXi (), casc.pt ());
238+
159239 // Bachelor check
160240 if (TMath::Abs (bachTrack.tpcNSigmaPi ()) < tpcNsigmaBachelor) {
161241 if (TMath::Abs (bachTrack.tpcNSigmaKa ()) < tpcNsigmaBachelor) {
162242 // consistent with both!
163- cascflags (3 );
243+ cascflags (2 );
244+ registry.fill (HIST (" hSelectionStatus" ), 5 ); // passes bach PID
245+ registry.fill (HIST (" hMassXi5" ), casc.mXi (), casc.pt ());
164246 continue ;
165247 }
166248 cascflags (1 );
249+ registry.fill (HIST (" hSelectionStatus" ), 5 ); // passes bach PID
250+ registry.fill (HIST (" hMassXi5" ), casc.mXi (), casc.pt ());
167251 continue ;
168252 } else if (TMath::Abs (bachTrack.tpcNSigmaKa ()) < tpcNsigmaBachelor) {
169- cascflags (2 );
253+ cascflags (3 );
254+ registry.fill (HIST (" hSelectionStatus" ), 5 ); // passes bach PID
170255 continue ;
171256 }
172257 // if we reach here, the bachelor was neither pion nor kaon
@@ -207,7 +292,8 @@ struct cascadeCorrelations {
207292 {" hLambdaMass" , " hLambdaMass" , {HistType::kTH1F , {{1000 , 0 .0f , 10 .0f , " Inv. Mass (GeV/c^{2})" }}}},
208293
209294 {" hSelectionFlag" , " hSelectionFlag" , {HistType::kTH1I , {selectionFlagAxis}}},
210- {" hAutoCorrelation" , " hAutoCorrelation" , {HistType::kTH1I , {{4 , -0 .5f , 3 .5f , " Types of autocorrelation" }}}},
295+ {" hAutoCorrelation" , " hAutoCorrelation" , {HistType::kTH1I , {{4 , -0 .5f , 3 .5f , " Types of SS autocorrelation" }}}},
296+ {" hAutoCorrelationOS" , " hAutoCorrelationOS" , {HistType::kTH1I , {{2 , -1 .f , 1 .f , " Charge of OS autocorrelated track" }}}},
211297 {" hPhi" , " hPhi" , {HistType::kTH1F , {{100 , 0 , 2 * PI, " #varphi" }}}},
212298 {" hEta" , " hEta" , {HistType::kTH1F , {{100 , -2 , 2 , " #eta" }}}},
213299
@@ -237,7 +323,7 @@ struct cascadeCorrelations {
237323
238324 // Some QA on the cascades
239325 for (auto & casc : Cascades) {
240- if (casc.isSelected () ! = 2 ) { // not exclusively an Omega --> consistent with Xi or both
326+ if (casc.isSelected () < = 2 ) { // not exclusively an Omega --> consistent with Xi or both
241327 if (casc.sign () < 0 ) {
242328 registry.fill (HIST (" hMassXiMinus" ), casc.mXi (), casc.pt ());
243329 } else {
@@ -296,13 +382,39 @@ struct cascadeCorrelations {
296382
297383 // Fill the correct histograms based on same-sign or opposite-sign
298384 if (trigger.sign () * assoc.sign () < 0 ) { // opposite-sign
385+ // check for autocorrelations between mis-identified kaons (omega bach) and protons (lambda daughter) TODO: improve logic?
386+ if (trigger.isSelected () >= 2 ) {
387+ if (trigger.sign () > 0 && trigger.bachelorId () == posIdAssoc) {
388+ // K+ from trigger Omega is the same as proton from assoc lambda
389+ registry.fill (HIST (" hAutoCorrelationOS" ), 1 );
390+ continue ;
391+ }
392+ if (trigger.sign () < 0 && trigger.bachelorId () == negIdAssoc) {
393+ // K- from trigger Omega is the same as antiproton from assoc antilambda
394+ registry.fill (HIST (" hAutoCorrelationOS" ), -1 );
395+ continue ;
396+ }
397+ }
398+ if (assoc.isSelected () >= 2 ) {
399+ if (assoc.sign () > 0 && assoc.bachelorId () == posIdTrigg) {
400+ // K+ from assoc Omega is the same as proton from trigger lambda
401+ registry.fill (HIST (" hAutoCorrelationOS" ), 1 );
402+ continue ;
403+ }
404+ if (assoc.sign () < 0 && assoc.bachelorId () == negIdTrigg) {
405+ // K- from assoc Omega is the same as antiproton from trigger antilambda
406+ registry.fill (HIST (" hAutoCorrelationOS" ), -1 );
407+ continue ;
408+ }
409+ }
410+
299411 registry.fill (HIST (" hDeltaPhiOS" ), dphi);
300412 registry.fill (HIST (" hXiXiOS" ), dphi, deta, trigger.pt (), assoc.pt (), invMassXiTrigg, invMassXiAssoc, trigger.isSelected (), assoc.isSelected (), collision.posZ (), collision.multFT0M ());
301413 registry.fill (HIST (" hXiOmOS" ), dphi, deta, trigger.pt (), assoc.pt (), invMassXiTrigg, invMassOmAssoc, trigger.isSelected (), assoc.isSelected (), collision.posZ (), collision.multFT0M ());
302414 registry.fill (HIST (" hOmXiOS" ), dphi, deta, trigger.pt (), assoc.pt (), invMassOmTrigg, invMassXiAssoc, trigger.isSelected (), assoc.isSelected (), collision.posZ (), collision.multFT0M ());
303415 registry.fill (HIST (" hOmOmOS" ), dphi, deta, trigger.pt (), assoc.pt (), invMassOmTrigg, invMassOmAssoc, trigger.isSelected (), assoc.isSelected (), collision.posZ (), collision.multFT0M ());
304416 } else { // same-sign
305- // make sure to check for autocorrelations - only possible in same-sign correlations
417+ // make sure to check for autocorrelations - only possible in same-sign correlations (if PID is correct)
306418 if (posIdTrigg == posIdAssoc && negIdTrigg == negIdAssoc) {
307419 // LOGF(info, "same v0 in SS correlation! %d %d", v0dataTrigg.v0Id(), v0dataAssoc.v0Id());
308420 registry.fill (HIST (" hAutoCorrelation" ), 0 );
0 commit comments