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,12 @@ 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+
177190 void init (InitContext&)
178191 {
179192 ccdb->setURL (cfgCcdbParam.cfgURL );
@@ -190,14 +203,18 @@ struct LongrangeMaker {
190203 auto hstat = histos.get <TH1>(HIST (" EventHist" ));
191204 auto * x = hstat->GetXaxis ();
192205 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" );
206+ x->SetBinLabel (2 , " Apply TriggerTVX" );
207+ x->SetBinLabel (3 , " Apply TF Border" );
208+ x->SetBinLabel (4 , " Apply ITS ROF Border" );
209+ x->SetBinLabel (5 , " ApplySameBunchPileup" );
210+ x->SetBinLabel (6 , " ApplyGoodZvtxFT0vsPV" );
211+ x->SetBinLabel (7 , " ApplyGoodITSLayersAll" );
212+ x->SetBinLabel (8 , " ApplyExtraCorrCut" );
213+ x->SetBinLabel (9 , " ApplyNoCollInTimeRangeStandard" );
214+ x->SetBinLabel (10 , " ApplyNoCollInRofStandard" );
215+ x->SetBinLabel (11 , " ApplyNoHighMultCollInPrevRof" );
216+ x->SetBinLabel (12 , " ApplyOccupancySelection" );
217+ histos.add (" hSelectionResult" , " hSelectionResult" , kTH1I , {{5 , -0.5 , 4.5 }});
201218
202219 myTrackFilter = getGlobalTrackSelectionRun3ITSMatch (TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default);
203220 myTrackFilter.SetPtRange (cfgtrksel.cfgPtCutMin , cfgtrksel.cfgPtCutMax );
@@ -211,6 +228,8 @@ struct LongrangeMaker {
211228 tofNsigmaCut = tofNsigmaPidCut;
212229 itsNsigmaCut = itsNsigmaPidCut;
213230 tpcNsigmaCut = tpcNsigmaPidCut;
231+
232+ cfgSgCuts = (SGCutParHolder)SGCuts;
214233 }
215234
216235 Produces<aod::CollLRTables> collisionLRTable;
@@ -221,14 +240,22 @@ struct LongrangeMaker {
221240 Produces<aod::MftBestTrkLRTables> mftbestLRTable;
222241 Produces<aod::V0TrkLRTables> v0LRTable;
223242
243+ Produces<aod::UpcCollLRTables> outupccol;
244+ Produces<aod::UpcSgCollLRTables> outsgupccol;
245+ Produces<aod::zdcLRTables> outzdctable;
246+
224247 Filter fTracksEta = nabs(aod::track::eta) < cfgtrksel.cfgEtaCut;
225248 Filter fTracksPt = (aod::track::pt > cfgtrksel.cfgPtCutMin) && (aod::track::pt < cfgtrksel.cfgPtCutMax);
226249
227250 using CollTable = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Cs, aod::CentFV0As, aod::CentFT0Ms>;
228251 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>>;
229252 using MftTrkTable = aod::MFTTracks;
253+ using BCs = soa::Join<aod::BCsWithTimestamps, aod::BcSels, aod::Run3MatchedToBCSparse>;
230254
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 &)
255+ void processData (CollTable::iterator const & col, TrksTable const & tracks,
256+ aod::FT0s const &, MftTrkTable const & mfttracks,
257+ soa::SmallGroups<aod::BestCollisionsFwd> const & retracks,
258+ aod::V0Datas const & V0s, aod::BCsWithTimestamps const &)
232259 {
233260 if (!isEventSelected (col)) {
234261 return ;
@@ -331,42 +358,187 @@ struct LongrangeMaker {
331358 }
332359 } // process function
333360
361+ void processUpc (CollTable::iterator const & col, BCs const & bcs,
362+ TrksTable const & tracks, aod::Zdcs const &,
363+ aod::FV0As const & fv0as, aod::FT0s const & ft0s,
364+ aod::FDDs const & fdds, MftTrkTable const & mfttracks,
365+ soa::SmallGroups<aod::BestCollisionsFwd> const & retracks,
366+ aod::V0Datas const & V0s)
367+ {
368+ if (!isEventSelected (col)) {
369+ return ;
370+ }
371+
372+ if (!col.has_foundBC ()) {
373+ return ;
374+ }
375+
376+ auto bc = col.template foundBC_as <BCs>();
377+ auto newbc = bc;
378+ // obtain slice of compatible BCs
379+ auto bcRange = udhelpers::compatibleBCs (col, cfgSgCuts.NDtcoll (), bcs, cfgSgCuts.minNBCs ());
380+ auto isSGEvent = sgSelector.IsSelected (cfgSgCuts, col, bcRange, bc);
381+ int issgevent = isSGEvent.value ;
382+ histos.fill (HIST (" hSelectionResult" ), isSGEvent.value );
383+
384+ if (issgevent <= 2 ) {
385+ if (cfgSgCuts.minRgtrwTOF ()) {
386+ if (udhelpers::rPVtrwTOF<true >(tracks, col.numContrib ()) < cfgSgCuts.minRgtrwTOF ())
387+ return ;
388+ }
389+
390+ upchelpers::FITInfo fitInfo{};
391+ udhelpers::getFITinfo (fitInfo, newbc, bcs, ft0s, fv0as, fdds);
392+ auto multiplicity = countNTracks (tracks);
393+ outupccol (bc.globalBC (), bc.runNumber (), col.posZ (), multiplicity, fitInfo.ampFT0A , fitInfo.ampFT0C , fitInfo.timeFV0A );
394+ outsgupccol (issgevent);
395+ if (newbc.has_zdc ()) {
396+ auto zdc = newbc.zdc ();
397+ outzdctable (outupccol.lastIndex (), zdc.energyCommonZNA (), zdc.energyCommonZNC ());
398+ } else {
399+ outzdctable (outupccol.lastIndex (), -999 , -999 );
400+ }
401+
402+ // track loop
403+ for (const auto & track : tracks) {
404+ if (!track.isGlobalTrack ())
405+ continue ;
406+ if (!myTrackFilter.IsSelected (track))
407+ continue ;
408+ tracksLRTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpCharge );
409+ if (getTrackPID (track) == PionTrackN)
410+ tracksLRTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpPion );
411+ if (getTrackPID (track) == KaonTrackN)
412+ tracksLRTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpKaon );
413+ if (getTrackPID (track) == ProtonTrackN)
414+ tracksLRTable (outupccol.lastIndex (), track.pt (), track.eta (), track.phi (), aod::lrcorrtrktable::kSpProton );
415+ }
416+
417+ // ft0 loop
418+ if (col.has_foundFT0 ()) {
419+ const auto & ft0 = col.foundFT0 ();
420+ for (std::size_t iCh = 0 ; iCh < ft0.channelA ().size (); iCh++) {
421+ auto chanelid = ft0.channelA ()[iCh];
422+ float ampl = ft0.amplitudeA ()[iCh];
423+ auto phi = getPhiFT0 (chanelid, 0 );
424+ auto eta = getEtaFT0 (chanelid, 0 );
425+ ft0aLRTable (outupccol.lastIndex (), chanelid, ampl, eta, phi);
426+ }
427+ for (std::size_t iCh = 0 ; iCh < ft0.channelC ().size (); iCh++) {
428+ auto chanelid = ft0.channelC ()[iCh];
429+ float ampl = ft0.amplitudeC ()[iCh];
430+ auto phi = getPhiFT0 (chanelid, 1 );
431+ auto eta = getEtaFT0 (chanelid, 1 );
432+ ft0cLRTable (outupccol.lastIndex (), chanelid, ampl, eta, phi);
433+ }
434+ }
435+
436+ // mft loop
437+ for (const auto & track : mfttracks) {
438+ if (!isMftTrackSelected (track))
439+ continue ;
440+ auto phi = track.phi ();
441+ o2::math_utils::bringTo02Pi (phi);
442+ mftLRTable (outupccol.lastIndex (), track.pt (), track.eta (), phi);
443+ }
444+
445+ if (retracks.size () > 0 ) {
446+ for (const auto & retrack : retracks) {
447+ if (std::abs (retrack.bestDCAXY ()) > cfgmfttrksel.cfigMftDcaxy ) {
448+ continue ; // does not point to PV properly
449+ }
450+ auto track = retrack.mfttrack ();
451+ if (!isMftTrackSelected (track)) {
452+ continue ;
453+ }
454+ auto phi = track.phi ();
455+ o2::math_utils::bringTo02Pi (phi);
456+ mftbestLRTable (outupccol.lastIndex (), track.pt (), track.eta (), phi);
457+ }
458+ }
459+
460+ // v0 loop
461+ for (const auto & v0 : V0s) {
462+ if (!isSelectV0Track (v0)) { // Quality selection for V0 prongs
463+ continue ;
464+ }
465+ const auto & posTrack = v0.template posTrack_as <TrksTable>();
466+ const auto & negTrack = v0.template negTrack_as <TrksTable>();
467+ double massV0 = 0.0 ;
468+
469+ // K0short
470+ if (isSelectK0s (col, v0)) { // candidate is K0s
471+ v0LRTable (outupccol.lastIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
472+ v0.pt (), v0.eta (), v0.phi (), v0.mK0Short (), aod::lrcorrtrktable::kSpK0short );
473+ }
474+
475+ // Lambda and Anti-Lambda
476+ bool lambdaTag = isSelectLambda<KindOfV0::kLambda >(col, v0);
477+ bool antilambdaTag = isSelectLambda<KindOfV0::kAntiLambda >(col, v0);
478+
479+ // Note: candidate compatible with Lambda and Anti-Lambda hypothesis are counted twice (once for each hypothesis)
480+ if (lambdaTag) { // candidate is Lambda
481+ massV0 = v0.mLambda ();
482+ v0LRTable (outupccol.lastIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
483+ v0.pt (), v0.eta (), v0.phi (), massV0, aod::lrcorrtrktable::kSpLambda );
484+ }
485+ if (antilambdaTag) { // candidate is Anti-lambda
486+ massV0 = v0.mAntiLambda ();
487+ v0LRTable (outupccol.lastIndex (), posTrack.globalIndex (), negTrack.globalIndex (),
488+ v0.pt (), v0.eta (), v0.phi (), massV0, aod::lrcorrtrktable::kSpALambda );
489+ } // end of Lambda and Anti-Lambda processing
490+ }
491+ } // SG events
492+ }
493+
334494 template <typename CheckCol>
335495 bool isEventSelected (CheckCol const & col)
336496 {
337497 histos.fill (HIST (" EventHist" ), 1 );
338- if (!col.sel8 ( )) {
498+ if (cfgevtsel. isApplyTrigTvx && !col.selection_bit (o2::aod::evsel:: kIsTriggerTVX )) {
339499 return false ;
340500 }
341501 histos.fill (HIST (" EventHist" ), 2 );
342- if (cfgevtsel.isApplySameBunchPileup && !col.selection_bit (o2::aod::evsel::kNoSameBunchPileup )) {
502+ if (cfgevtsel.isApplyTfborder && !col.selection_bit (o2::aod::evsel::kNoTimeFrameBorder )) {
343503 return false ;
344504 }
345505 histos.fill (HIST (" EventHist" ), 3 );
346- if (cfgevtsel.isApplyGoodZvtxFT0vsPV && !col.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV )) {
506+ if (cfgevtsel.isApplyItsRofborder && !col.selection_bit (o2::aod::evsel::kNoITSROFrameBorder )) {
347507 return false ;
348508 }
349509 histos.fill (HIST (" EventHist" ), 4 );
350- if (cfgevtsel.isApplyGoodITSLayersAll && !col.selection_bit (o2::aod::evsel::kIsGoodITSLayersAll )) {
510+ if (cfgevtsel.isApplySameBunchPileup && !col.selection_bit (o2::aod::evsel::kNoSameBunchPileup )) {
351511 return false ;
352512 }
353513 histos.fill (HIST (" EventHist" ), 5 );
354- if (cfgevtsel.isApplyExtraCorrCut && col.multNTracksPV () > cfgevtsel. npvTracksCut && col. multFT0C () < ( 10 * col. multNTracksPV () - cfgevtsel. ft0cCut )) {
514+ if (cfgevtsel.isApplyGoodZvtxFT0vsPV && ! col.selection_bit (o2::aod::evsel:: kIsGoodZvtxFT0vsPV )) {
355515 return false ;
356516 }
357517 histos.fill (HIST (" EventHist" ), 6 );
358- if (cfgevtsel.isApplyNoCollInTimeRangeStandard && !col.selection_bit (o2::aod::evsel::kNoCollInTimeRangeStandard )) {
518+ if (cfgevtsel.isApplyGoodITSLayersAll && !col.selection_bit (o2::aod::evsel::kIsGoodITSLayersAll )) {
359519 return false ;
360520 }
361521 histos.fill (HIST (" EventHist" ), 7 );
362- if (cfgevtsel.isApplyNoCollInRofStandard && ! col.selection_bit (o2::aod::evsel:: kNoCollInRofStandard )) {
522+ if (cfgevtsel.isApplyExtraCorrCut && col.multNTracksPV () > cfgevtsel. npvTracksCut && col. multFT0C () < ( 10 * col. multNTracksPV () - cfgevtsel. ft0cCut )) {
363523 return false ;
364524 }
365525 histos.fill (HIST (" EventHist" ), 8 );
366- if (cfgevtsel.isApplyNoHighMultCollInPrevRof && !col.selection_bit (o2::aod::evsel::kNoHighMultCollInPrevRof )) {
526+ if (cfgevtsel.isApplyNoCollInTimeRangeStandard && !col.selection_bit (o2::aod::evsel::kNoCollInTimeRangeStandard )) {
367527 return false ;
368528 }
369529 histos.fill (HIST (" EventHist" ), 9 );
530+ if (cfgevtsel.isApplyNoCollInRofStandard && !col.selection_bit (o2::aod::evsel::kNoCollInRofStandard )) {
531+ return false ;
532+ }
533+ histos.fill (HIST (" EventHist" ), 10 );
534+ if (cfgevtsel.isApplyNoHighMultCollInPrevRof && !col.selection_bit (o2::aod::evsel::kNoHighMultCollInPrevRof )) {
535+ return false ;
536+ }
537+ histos.fill (HIST (" EventHist" ), 11 );
538+ if (cfgevtsel.isApplyOccuSelection && (col.trackOccupancyInTimeRange () > cfgevtsel.cfgOccuCut )) {
539+ return false ;
540+ }
541+ histos.fill (HIST (" EventHist" ), 12 );
370542 return true ;
371543 }
372544
@@ -582,6 +754,9 @@ struct LongrangeMaker {
582754 }
583755 return true ;
584756 }
757+
758+ PROCESS_SWITCH (LongrangeMaker, processData, " process All collisions" , false );
759+ PROCESS_SWITCH (LongrangeMaker, processUpc, " process UPC collisions" , false );
585760};
586761
587762WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments