2020#include " PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h"
2121#include " PWGLF/DataModel/LFStrangenessTables.h"
2222#include " PWGMM/Mult/DataModel/bestCollisionTable.h"
23+ #include " PWGUD/Core/SGSelector.h"
24+ #include " PWGUD/Core/UPCHelpers.h"
2325
2426#include " Common/Core/RecoDecay.h"
2527#include " Common/Core/TrackSelection.h"
@@ -93,6 +95,9 @@ struct LongrangeMaker {
9395 } cfgCcdbParam;
9496
9597 struct : ConfigurableGroup {
98+ Configurable<bool > isApplyTrigTvx{" isApplyTrigTvx" , false , " Enable Ft0a and Ft0c coincidence" };
99+ Configurable<bool > isApplyTfborder{" isApplyTfborder" , false , " Enable TF border cut" };
100+ Configurable<bool > isApplyItsRofborder{" isApplyItsRofborder" , false , " Enable ITS ROF border cut" };
96101 Configurable<bool > isApplySameBunchPileup{" isApplySameBunchPileup" , false , " Enable SameBunchPileup cut" };
97102 Configurable<bool > isApplyGoodZvtxFT0vsPV{" isApplyGoodZvtxFT0vsPV" , false , " Enable GoodZvtxFT0vsPV cut" };
98103 Configurable<bool > isApplyGoodITSLayersAll{" isApplyGoodITSLayersAll" , false , " Enable GoodITSLayersAll cut" };
@@ -105,6 +110,8 @@ struct LongrangeMaker {
105110 Configurable<bool > isApplyCentFT0C{" isApplyCentFT0C" , false , " Centrality based on FT0C" };
106111 Configurable<bool > isApplyCentFV0A{" isApplyCentFV0A" , false , " Centrality based on FV0A" };
107112 Configurable<bool > isApplyCentFT0M{" isApplyCentFT0M" , false , " Centrality based on FT0A + FT0C" };
113+ Configurable<bool > isApplyOccuSelection{" isApplyOccuSelection" , false , " Enable occupancy selection" };
114+ Configurable<int > cfgOccuCut{" cfgOccuCut" , 1000 , " Occupancy selection" };
108115 } cfgevtsel;
109116
110117 struct : ConfigurableGroup {
@@ -174,6 +181,13 @@ struct LongrangeMaker {
174181 std::vector<double > tpcNsigmaCut;
175182 o2::aod::ITSResponse itsResponse;
176183
184+ // Create instance of the selector class which runs the gap selection algorithm
185+ SGSelector sgSelector;
186+ // Create instance of cut holder class to contain the user defined cuts
187+ SGCutParHolder cfgSgCuts = SGCutParHolder();
188+ Configurable<SGCutParHolder> sgCuts{" sgCuts" , {}, " SG event cuts" };
189+ Configurable<int > cfgGapSide{" cfgGapSide" , 2 , " cut on UPC events" };
190+
177191 void init (InitContext&)
178192 {
179193 ccdb->setURL (cfgCcdbParam.cfgURL );
@@ -190,14 +204,18 @@ struct LongrangeMaker {
190204 auto hstat = histos.get <TH1 >(HIST (" EventHist" ));
191205 auto * x = hstat->GetXaxis ();
192206 x->SetBinLabel (1 , " All events" );
193- x->SetBinLabel (2 , " Sel8" );
194- x->SetBinLabel (3 , " ApplySameBunchPileup" );
195- x->SetBinLabel (4 , " ApplyGoodZvtxFT0vsPV" );
196- x->SetBinLabel (5 , " ApplyGoodITSLayersAll" );
197- x->SetBinLabel (6 , " ApplyExtraCorrCut" );
198- x->SetBinLabel (7 , " ApplyNoCollInTimeRangeStandard" );
199- x->SetBinLabel (8 , " ApplyNoCollInRofStandard" );
200- x->SetBinLabel (9 , " ApplyNoHighMultCollInPrevRof" );
207+ x->SetBinLabel (2 , " Apply TriggerTVX" );
208+ x->SetBinLabel (3 , " Apply TF Border" );
209+ x->SetBinLabel (4 , " Apply ITS ROF Border" );
210+ x->SetBinLabel (5 , " ApplySameBunchPileup" );
211+ x->SetBinLabel (6 , " ApplyGoodZvtxFT0vsPV" );
212+ x->SetBinLabel (7 , " ApplyGoodITSLayersAll" );
213+ x->SetBinLabel (8 , " ApplyExtraCorrCut" );
214+ x->SetBinLabel (9 , " ApplyNoCollInTimeRangeStandard" );
215+ x->SetBinLabel (10 , " ApplyNoCollInRofStandard" );
216+ x->SetBinLabel (11 , " ApplyNoHighMultCollInPrevRof" );
217+ x->SetBinLabel (12 , " ApplyOccupancySelection" );
218+ histos.add (" hSelectionResult" , " hSelectionResult" , kTH1I , {{5 , -0.5 , 4.5 }});
201219
202220 myTrackFilter = getGlobalTrackSelectionRun3ITSMatch (TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default);
203221 myTrackFilter.SetPtRange (cfgtrksel.cfgPtCutMin , cfgtrksel.cfgPtCutMax );
@@ -211,6 +229,8 @@ struct LongrangeMaker {
211229 tofNsigmaCut = tofNsigmaPidCut;
212230 itsNsigmaCut = itsNsigmaPidCut;
213231 tpcNsigmaCut = tpcNsigmaPidCut;
232+
233+ cfgSgCuts = (SGCutParHolder)sgCuts;
214234 }
215235
216236 Produces<aod::CollLRTables> collisionLRTable;
@@ -221,14 +241,29 @@ struct LongrangeMaker {
221241 Produces<aod::MftBestTrkLRTables> mftbestLRTable;
222242 Produces<aod::V0TrkLRTables> v0LRTable;
223243
244+ Produces<aod::UpcCollLRTables> outupccol;
245+ Produces<aod::UpcSgCollLRTables> outsgupccol;
246+ Produces<aod::ZdcLRTables> outzdctable;
247+
248+ Produces<aod::TrkLRUpcTables> tracksLRUpcTable;
249+ Produces<aod::Ft0aLRUpcTables> ft0aLRUpcTable;
250+ Produces<aod::Ft0cLRUpcTables> ft0cLRUpcTable;
251+ Produces<aod::MftTrkLRUpcTables> mftLRUpcTable;
252+ Produces<aod::MftBestTrkLRUpcTables> mftbestLRUpcTable;
253+ Produces<aod::V0TrkLRUpcTables> v0LRUpcTable;
254+
224255 Filter fTracksEta = nabs(aod::track::eta) < cfgtrksel.cfgEtaCut;
225256 Filter fTracksPt = (aod::track::pt > cfgtrksel.cfgPtCutMin) && (aod::track::pt < cfgtrksel.cfgPtCutMax);
226257
227258 using CollTable = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Cs, aod::CentFV0As, aod::CentFT0Ms>;
228259 using TrksTable = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFbeta, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr>>;
229260 using MftTrkTable = aod::MFTTracks;
261+ using BCs = soa::Join<aod::BCsWithTimestamps, aod::BcSels, aod::Run3MatchedToBCSparse>;
230262
231- void process (CollTable::iterator const & col, TrksTable const & tracks, aod::FT0s const &, MftTrkTable const & mfttracks, soa::SmallGroups<aod::BestCollisionsFwd> const & retracks, aod::V0Datas const & V0s, aod::BCsWithTimestamps const &)
263+ void processData (CollTable::iterator const & col, TrksTable const & tracks,
264+ aod::FT0s const &, MftTrkTable const & mfttracks,
265+ soa::SmallGroups<aod::BestCollisionsFwd> const & retracks,
266+ aod::V0Datas const & V0s, aod::BCsWithTimestamps const &)
232267 {
233268 if (!isEventSelected (col)) {
234269 return ;
@@ -331,42 +366,187 @@ struct LongrangeMaker {
331366 }
332367 } // process function
333368
369+ void processUpc (CollTable::iterator const & col, BCs const & bcs,
370+ TrksTable const & tracks, aod::Zdcs const &,
371+ aod::FV0As const & fv0as, aod::FT0s const & ft0s,
372+ aod::FDDs const & fdds, MftTrkTable const & mfttracks,
373+ soa::SmallGroups<aod::BestCollisionsFwd> const & retracks,
374+ aod::V0Datas const & V0s)
375+ {
376+ if (!isEventSelected (col)) {
377+ return ;
378+ }
379+
380+ if (!col.has_foundBC ()) {
381+ return ;
382+ }
383+
384+ auto bc = col.template foundBC_as <BCs>();
385+ auto newbc = bc;
386+ // obtain slice of compatible BCs
387+ auto bcRange = udhelpers::compatibleBCs (col, cfgSgCuts.NDtcoll (), bcs, cfgSgCuts.minNBCs ());
388+ auto isSGEvent = sgSelector.IsSelected (cfgSgCuts, col, bcRange, bc);
389+ int issgevent = isSGEvent.value ;
390+ histos.fill (HIST (" hSelectionResult" ), isSGEvent.value );
391+
392+ if (issgevent <= cfgGapSide) {
393+ if (cfgSgCuts.minRgtrwTOF ()) {
394+ if (udhelpers::rPVtrwTOF<true >(tracks, col.numContrib ()) < cfgSgCuts.minRgtrwTOF ())
395+ return ;
396+ }
397+
398+ upchelpers::FITInfo fitInfo{};
399+ udhelpers::getFITinfo (fitInfo, newbc, bcs, ft0s, fv0as, fdds);
400+ auto multiplicity = countNTracks (tracks);
401+ outupccol (bc.globalBC (), bc.runNumber (), col.posZ (), multiplicity, fitInfo.ampFT0A , fitInfo.ampFT0C , fitInfo.timeFV0A );
402+ outsgupccol (issgevent);
403+ if (newbc.has_zdc ()) {
404+ auto zdc = newbc.zdc ();
405+ outzdctable (outupccol.lastIndex (), zdc.energyCommonZNA (), zdc.energyCommonZNC ());
406+ } else {
407+ outzdctable (outupccol.lastIndex (), -999 , -999 );
408+ }
409+
410+ // track loop
411+ for (const auto & track : tracks) {
412+ if (!track.isGlobalTrack ())
413+ continue ;
414+ if (!myTrackFilter.IsSelected (track))
415+ continue ;
416+ tracksLRUpcTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpCharge );
417+ if (getTrackPID (track) == PionTrackN)
418+ tracksLRUpcTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpPion );
419+ if (getTrackPID (track) == KaonTrackN)
420+ tracksLRUpcTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpKaon );
421+ if (getTrackPID (track) == ProtonTrackN)
422+ tracksLRUpcTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpProton );
423+ }
424+
425+ // ft0 loop
426+ if (col.has_foundFT0 ()) {
427+ const auto & ft0 = col.foundFT0 ();
428+ for (std::size_t iCh = 0 ; iCh < ft0.channelA ().size (); iCh++) {
429+ auto chanelid = ft0.channelA ()[iCh];
430+ float ampl = ft0.amplitudeA ()[iCh];
431+ auto phi = getPhiFT0 (chanelid, 0 );
432+ auto eta = getEtaFT0 (chanelid, 0 );
433+ ft0aLRUpcTable (outupccol.lastIndex (), chanelid, ampl, eta, phi);
434+ }
435+ for (std::size_t iCh = 0 ; iCh < ft0.channelC ().size (); iCh++) {
436+ auto chanelid = ft0.channelC ()[iCh];
437+ float ampl = ft0.amplitudeC ()[iCh];
438+ auto phi = getPhiFT0 (chanelid, 1 );
439+ auto eta = getEtaFT0 (chanelid, 1 );
440+ ft0cLRUpcTable (outupccol.lastIndex (), chanelid, ampl, eta, phi);
441+ }
442+ }
443+
444+ // mft loop
445+ for (const auto & track : mfttracks) {
446+ if (!isMftTrackSelected (track))
447+ continue ;
448+ auto phi = track.phi ();
449+ o2::math_utils::bringTo02Pi (phi);
450+ mftLRUpcTable (outupccol.lastIndex (), track.pt (), track.eta (), phi);
451+ }
452+
453+ if (retracks.size () > 0 ) {
454+ for (const auto & retrack : retracks) {
455+ if (std::abs (retrack.bestDCAXY ()) > cfgmfttrksel.cfigMftDcaxy ) {
456+ continue ; // does not point to PV properly
457+ }
458+ auto track = retrack.mfttrack ();
459+ if (!isMftTrackSelected (track)) {
460+ continue ;
461+ }
462+ auto phi = track.phi ();
463+ o2::math_utils::bringTo02Pi (phi);
464+ mftbestLRUpcTable (outupccol.lastIndex (), track.pt (), track.eta (), phi);
465+ }
466+ }
467+
468+ // v0 loop
469+ for (const auto & v0 : V0s) {
470+ if (!isSelectV0Track (v0)) { // Quality selection for V0 prongs
471+ continue ;
472+ }
473+ const auto & posTrack = v0.template posTrack_as <TrksTable>();
474+ const auto & negTrack = v0.template negTrack_as <TrksTable>();
475+ double massV0 = 0.0 ;
476+
477+ // K0short
478+ if (isSelectK0s (col, v0)) { // candidate is K0s
479+ v0LRUpcTable (outupccol.lastIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
480+ v0.pt (), v0.eta (), v0.phi (), v0.mK0Short (), aod::lrcorrtrktable::kSpK0short );
481+ }
482+
483+ // Lambda and Anti-Lambda
484+ bool lambdaTag = isSelectLambda<KindOfV0::kLambda >(col, v0);
485+ bool antilambdaTag = isSelectLambda<KindOfV0::kAntiLambda >(col, v0);
486+
487+ // Note: candidate compatible with Lambda and Anti-Lambda hypothesis are counted twice (once for each hypothesis)
488+ if (lambdaTag) { // candidate is Lambda
489+ massV0 = v0.mLambda ();
490+ v0LRUpcTable (outupccol.lastIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
491+ v0.pt (), v0.eta (), v0.phi (), massV0, aod::lrcorrtrktable::kSpLambda );
492+ }
493+ if (antilambdaTag) { // candidate is Anti-lambda
494+ massV0 = v0.mAntiLambda ();
495+ v0LRUpcTable (outupccol.lastIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
496+ v0.pt (), v0.eta (), v0.phi (), massV0, aod::lrcorrtrktable::kSpALambda );
497+ } // end of Lambda and Anti-Lambda processing
498+ }
499+ } // SG events
500+ }
501+
334502 template <typename CheckCol>
335503 bool isEventSelected (CheckCol const & col)
336504 {
337505 histos.fill (HIST (" EventHist" ), 1 );
338- if (!col.sel8 ( )) {
506+ if (cfgevtsel. isApplyTrigTvx && !col.selection_bit (o2::aod::evsel:: kIsTriggerTVX )) {
339507 return false ;
340508 }
341509 histos.fill (HIST (" EventHist" ), 2 );
342- if (cfgevtsel.isApplySameBunchPileup && !col.selection_bit (o2::aod::evsel::kNoSameBunchPileup )) {
510+ if (cfgevtsel.isApplyTfborder && !col.selection_bit (o2::aod::evsel::kNoTimeFrameBorder )) {
343511 return false ;
344512 }
345513 histos.fill (HIST (" EventHist" ), 3 );
346- if (cfgevtsel.isApplyGoodZvtxFT0vsPV && !col.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV )) {
514+ if (cfgevtsel.isApplyItsRofborder && !col.selection_bit (o2::aod::evsel::kNoITSROFrameBorder )) {
347515 return false ;
348516 }
349517 histos.fill (HIST (" EventHist" ), 4 );
350- if (cfgevtsel.isApplyGoodITSLayersAll && !col.selection_bit (o2::aod::evsel::kIsGoodITSLayersAll )) {
518+ if (cfgevtsel.isApplySameBunchPileup && !col.selection_bit (o2::aod::evsel::kNoSameBunchPileup )) {
351519 return false ;
352520 }
353521 histos.fill (HIST (" EventHist" ), 5 );
354- if (cfgevtsel.isApplyExtraCorrCut && col.multNTracksPV () > cfgevtsel. npvTracksCut && col. multFT0C () < ( 10 * col. multNTracksPV () - cfgevtsel. ft0cCut )) {
522+ if (cfgevtsel.isApplyGoodZvtxFT0vsPV && ! col.selection_bit (o2::aod::evsel:: kIsGoodZvtxFT0vsPV )) {
355523 return false ;
356524 }
357525 histos.fill (HIST (" EventHist" ), 6 );
358- if (cfgevtsel.isApplyNoCollInTimeRangeStandard && !col.selection_bit (o2::aod::evsel::kNoCollInTimeRangeStandard )) {
526+ if (cfgevtsel.isApplyGoodITSLayersAll && !col.selection_bit (o2::aod::evsel::kIsGoodITSLayersAll )) {
359527 return false ;
360528 }
361529 histos.fill (HIST (" EventHist" ), 7 );
362- if (cfgevtsel.isApplyNoCollInRofStandard && ! col.selection_bit (o2::aod::evsel:: kNoCollInRofStandard )) {
530+ if (cfgevtsel.isApplyExtraCorrCut && col.multNTracksPV () > cfgevtsel. npvTracksCut && col. multFT0C () < ( 10 * col. multNTracksPV () - cfgevtsel. ft0cCut )) {
363531 return false ;
364532 }
365533 histos.fill (HIST (" EventHist" ), 8 );
366- if (cfgevtsel.isApplyNoHighMultCollInPrevRof && !col.selection_bit (o2::aod::evsel::kNoHighMultCollInPrevRof )) {
534+ if (cfgevtsel.isApplyNoCollInTimeRangeStandard && !col.selection_bit (o2::aod::evsel::kNoCollInTimeRangeStandard )) {
367535 return false ;
368536 }
369537 histos.fill (HIST (" EventHist" ), 9 );
538+ if (cfgevtsel.isApplyNoCollInRofStandard && !col.selection_bit (o2::aod::evsel::kNoCollInRofStandard )) {
539+ return false ;
540+ }
541+ histos.fill (HIST (" EventHist" ), 10 );
542+ if (cfgevtsel.isApplyNoHighMultCollInPrevRof && !col.selection_bit (o2::aod::evsel::kNoHighMultCollInPrevRof )) {
543+ return false ;
544+ }
545+ histos.fill (HIST (" EventHist" ), 11 );
546+ if (cfgevtsel.isApplyOccuSelection && (col.trackOccupancyInTimeRange () > cfgevtsel.cfgOccuCut )) {
547+ return false ;
548+ }
549+ histos.fill (HIST (" EventHist" ), 12 );
370550 return true ;
371551 }
372552
@@ -582,6 +762,9 @@ struct LongrangeMaker {
582762 }
583763 return true ;
584764 }
765+
766+ PROCESS_SWITCH (LongrangeMaker, processData, " process All collisions" , false );
767+ PROCESS_SWITCH (LongrangeMaker, processUpc, " process UPC collisions" , false );
585768};
586769
587770WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments