1313#include < cmath>
1414#include < string>
1515
16+ #include " Math/Vector4D.h"
17+ #include " Math/GenVector/Boost.h"
1618#include " Common/DataModel/EventSelection.h"
1719#include " Common/DataModel/PIDResponse.h"
1820#include " Common/DataModel/TrackSelectionTables.h"
3739#include " CCDB/BasicCCDBManager.h"
3840#include " DCAFitter/DCAFitterN.h"
3941#include " PWGLF/DataModel/pidTOFGeneric.h"
42+ #include " PWGLF/DataModel/LFStrangenessTables.h"
4043#include " Common/Core/PID/PIDTOF.h"
4144
4245using namespace o2 ;
@@ -47,8 +50,6 @@ namespace
4750{
4851
4952static constexpr int nNuclei{3 };
50- static constexpr int nHyperNuclei{1 };
51- static constexpr int nITStriggers{2 };
5253static constexpr int nCutsPID{5 };
5354static constexpr std::array<float , nNuclei> masses{
5455 constants::physics::MassDeuteron, constants::physics::MassTriton,
@@ -57,7 +58,7 @@ static constexpr std::array<int, nNuclei> charges{1, 1, 2};
5758static const std::vector<std::string> matterOrNot{" Matter" , " Antimatter" };
5859static const std::vector<std::string> nucleiNames{" H2" , " H3" , " Helium" };
5960static const std::vector<std::string> hypernucleiNames{" H3L" }; // 3-body decay case
60- static const std::vector<std::string> columnsNames{o2::aod::filtering::H2::columnLabel (), " fH3 " , o2::aod::filtering::He ::columnLabel (), o2::aod::filtering::H3L3Body::columnLabel (), o2::aod::filtering::ITSmildIonisation::columnLabel (), o2::aod::filtering::ITSextremeIonisation::columnLabel ()};
61+ static const std::vector<std::string> columnsNames{o2::aod::filtering::H2::columnLabel (), o2::aod::filtering::He::columnLabel () , o2::aod::filtering::HeV0 ::columnLabel (), o2::aod::filtering::TritonFemto::columnLabel (), o2::aod::filtering:: H3L3Body::columnLabel (), o2::aod::filtering::Tracked3Body ::columnLabel (), o2::aod::filtering::ITSmildIonisation::columnLabel (), o2::aod::filtering::ITSextremeIonisation::columnLabel ()};
6162static const std::vector<std::string> cutsNames{
6263 " TPCnSigmaMin" , " TPCnSigmaMax" , " TOFnSigmaMin" , " TOFnSigmaMax" , " TOFpidStartPt" };
6364constexpr double betheBlochDefault[nNuclei][6 ]{
@@ -100,13 +101,14 @@ struct nucleiFilter {
100101 Configurable<float > cfgCutNclusTPC{" cfgCutNclusTPC" , 80 , " Minimum number of TPC clusters" };
101102 Configurable<float > cfgCutDCAxy{" cfgCutDCAxy" , 3 , " Max DCAxy" };
102103 Configurable<float > cfgCutDCAz{" cfgCutDCAz" , 10 , " Max DCAz" };
104+ Configurable<float > cfgCutKstar{" cfgCutKstar" , 1 .f , " Kstar cut for triton femto trigger" };
103105
104106 Configurable<LabeledArray<double >> cfgBetheBlochParams{" cfgBetheBlochParams" , {betheBlochDefault[0 ], nNuclei, 6 , nucleiNames, betheBlochParNames}, " TPC Bethe-Bloch parameterisation for light nuclei" };
105107 Configurable<LabeledArray<double >> cfgMomentumScalingBetheBloch{" cfgMomentumScalingBetheBloch" , {bbMomScalingDefault[0 ], nNuclei, 2 , nucleiNames, matterOrNot}, " TPC Bethe-Bloch momentum scaling for light nuclei" };
106108 Configurable<LabeledArray<double >> cfgMinTPCmom{" cfgMinTPCmom" , {minTPCmom[0 ], nNuclei, 2 , nucleiNames, matterOrNot}, " Minimum TPC p/Z for nuclei PID" };
107109
108110 Configurable<LabeledArray<float >> cfgCutsPID{" nucleiCutsPID" , {cutsPID[0 ], nNuclei, nCutsPID, nucleiNames, cutsNames}, " Nuclei PID selections" };
109- Configurable<bool > fixTPCinnerParam{ " fixTPCinnerParam " , false , " Fix TPC inner param" };
111+ Configurable<bool > cfgFixTPCinnerParam{ " cfgFixTPCinnerParam " , false , " Fix TPC inner param" };
110112
111113 // variable/tool for hypertriton 3body decay
112114 int mRunNumber ;
@@ -160,9 +162,9 @@ struct nucleiFilter {
160162 } trgH3L3Body;
161163
162164 HistogramRegistry qaHists{" qaHists" , {}, OutputObjHandlingPolicy::AnalysisObject, true , true };
163- OutputObj<TH1D> hProcessedEvents{TH1D (" hProcessedEvents" , " ;;Number of filtered events" , nNuclei + nHyperNuclei + nITStriggers + 1 , -0.5 , nNuclei + nHyperNuclei + nITStriggers + 0.5 )};
165+ OutputObj<TH1D> hProcessedEvents{TH1D (" hProcessedEvents" , " ;;Number of filtered events" , kNtriggers + 1 , -0.5 , static_cast < double >( kNtriggers ) + 0.5 )};
164166
165- void init (o2::framework:: InitContext&)
167+ void init (InitContext&)
166168 {
167169 std::vector<double > ptBinning = {0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 1.0 , 1.1 , 1.2 , 1.3 , 1.4 , 1.5 , 1.6 , 1.8 , 2.0 , 2.2 , 2.4 , 2.8 , 3.2 , 3.6 , 4 ., 5 .};
168170
@@ -313,27 +315,50 @@ struct nucleiFilter {
313315 bachelorTOFPID.SetParams (mRespParamsV2 );
314316 }
315317
318+ enum {
319+ kH2 = 0 ,
320+ kHe ,
321+ kHeV0 ,
322+ kTritonFemto ,
323+ kH3L3Body ,
324+ kTracked3Body ,
325+ kITSmildIonisation ,
326+ kITSextremeIonisation ,
327+ kNtriggers
328+ } TriggerType;
316329 // void process(soa::Join<aod::Collisions, aod::EvSels>::iterator const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, TrackCandidates const& tracks)
317330 using ColWithEvTime = soa::Join<aod::Collisions, aod::EvSels, aod::EvTimeTOFFT0>;
318- void process (ColWithEvTime::iterator const & collision, aod::Decay3Bodys const & decay3bodys, TrackCandidates const & tracks, aod::BCsWithTimestamps const &)
331+ void process (ColWithEvTime::iterator const & collision, aod::Decay3Bodys const & decay3bodys, TrackCandidates const & tracks, aod::AssignedTracked3Bodys const & tracked3Bodys, aod::V0s const & v0s, aod:: BCsWithTimestamps const &)
319332 {
320333 // collision process loop
321- bool keepEvent[nNuclei + nHyperNuclei + nITStriggers] {false };
334+ std::array< bool , kNtriggers > keepEvent {false };
322335 //
323336 qaHists.fill (HIST (" fCollZpos" ), collision.posZ ());
324337 hProcessedEvents->Fill (0 );
325338 //
326339 if (!collision.selection_bit (aod::evsel::kNoTimeFrameBorder )) {
327- tags (keepEvent[0 ], keepEvent[2 ], keepEvent[3 ], keepEvent[4 ], keepEvent[5 ]);
340+ tags (keepEvent[kH2 ], keepEvent[kHe ], keepEvent[kHeV0 ], keepEvent[kTritonFemto ], keepEvent[kH3L3Body ], keepEvent[ kTracked3Body ], keepEvent[ kITSmildIonisation ], keepEvent[ kITSextremeIonisation ]);
328341 return ;
329342 }
343+
330344 //
331345 const double bgScalings[nNuclei][2 ]{
332346 {charges[0 ] * cfgMomentumScalingBetheBloch->get (0u , 0u ) / masses[0 ], charges[0 ] * cfgMomentumScalingBetheBloch->get (0u , 1u ) / masses[0 ]},
333347 {charges[1 ] * cfgMomentumScalingBetheBloch->get (1u , 0u ) / masses[1 ], charges[1 ] * cfgMomentumScalingBetheBloch->get (1u , 1u ) / masses[1 ]},
334348 {charges[2 ] * cfgMomentumScalingBetheBloch->get (2u , 0u ) / masses[2 ], charges[2 ] * cfgMomentumScalingBetheBloch->get (2u , 1u ) / masses[2 ]}};
335349
336- for (auto & track : tracks) { // start loop over tracks
350+ constexpr int nucleusIndex[nNuclei]{kH2 , -1 , kHe }; // / remap for nuclei triggers
351+ std::vector<int > h3indices;
352+ std::vector<ROOT::Math::PtEtaPhiMVector> h3vectors;
353+
354+ auto getNsigma = [&](const auto & track, int iN, int iC) {
355+ float fixTPCrigidity{(cfgFixTPCinnerParam && (track.pidForTracking () == track::PID::Helium3 || track.pidForTracking () == track::PID::Alpha)) ? 0 .5f : 1 .f };
356+ double expBethe{tpc::BetheBlochAleph (static_cast <double >(track.tpcInnerParam () * fixTPCrigidity * bgScalings[iN][iC]), cfgBetheBlochParams->get (iN, 0u ), cfgBetheBlochParams->get (iN, 1u ), cfgBetheBlochParams->get (iN, 2u ), cfgBetheBlochParams->get (iN, 3u ), cfgBetheBlochParams->get (iN, 4u ))};
357+ double expSigma{expBethe * cfgBetheBlochParams->get (iN, 5u )};
358+ return static_cast <float >((track.tpcSignal () - expBethe) / expSigma);
359+ };
360+
361+ for (const auto & track : tracks) { // start loop over tracks
337362 if (track.itsNCls () >= cfgCutNclusExtremeIonisationITS) {
338363 double avgClsSize{0 .};
339364 double cosL{std::sqrt (1 . / (1 . + track.tgl () * track.tgl ()))};
@@ -342,8 +367,8 @@ struct nucleiFilter {
342367 }
343368 avgClsSize = avgClsSize * cosL / track.itsNCls ();
344369 qaHists.fill (HIST (" fExtremeIonisationITS" ), track.itsNCls (), avgClsSize, track.p ());
345- keepEvent[4 ] = track.p () > cfgMomentumCutExtremeIonisation && avgClsSize > cfgCutClsSizeMildIonisation;
346- keepEvent[5 ] = track.p () > cfgMomentumCutExtremeIonisation && avgClsSize > cfgCutClsSizeExtremeIonisation;
370+ keepEvent[kITSmildIonisation ] = track.p () > cfgMomentumCutExtremeIonisation && avgClsSize > cfgCutClsSizeMildIonisation;
371+ keepEvent[kITSextremeIonisation ] = track.p () > cfgMomentumCutExtremeIonisation && avgClsSize > cfgCutClsSizeExtremeIonisation;
347372 }
348373 if (track.itsNCls () < cfgCutNclusITS ||
349374 track.tpcNClsFound () < cfgCutNclusTPC) {
@@ -354,18 +379,16 @@ struct nucleiFilter {
354379 qaHists.fill (HIST (" fDeuTOFNsigma" ), track.p () * track.sign (), track.tofNSigmaDe ());
355380 }
356381
357- if (track.sign () > 0 && (std::abs (track.dcaXY ()) > cfgCutDCAxy ||
358- std::abs (track.dcaZ ()) > cfgCutDCAz)) {
359- continue ;
360- }
382+ bool passesDCAselection{(track.sign () < 0 || (std::abs (track.dcaXY ()) < cfgCutDCAxy &&
383+ std::abs (track.dcaZ ()) < cfgCutDCAz))};
361384
362385 float nSigmaTPC[nNuclei]{
363386 track.tpcNSigmaDe (), track.tpcNSigmaTr (), track.tpcNSigmaHe ()};
364387 const float nSigmaTOF[nNuclei]{
365388 track.tofNSigmaDe (), track.tofNSigmaTr (), track.tofNSigmaHe ()};
366389 const int iC{track.sign () < 0 };
367390
368- float fixTPCrigidity{(fixTPCinnerParam && (track.pidForTracking () == track::PID::Helium3 || track.pidForTracking () == track::PID::Alpha)) ? 0 .5f : 1 .f };
391+ float fixTPCrigidity{(cfgFixTPCinnerParam && (track.pidForTracking () == track::PID::Helium3 || track.pidForTracking () == track::PID::Alpha)) ? 0 .5f : 1 .f };
369392
370393 // fill QA hist: dEdx for all charged tracks
371394 qaHists.fill (HIST (" fTPCsignalAll" ), track.sign () * track.tpcInnerParam () * fixTPCrigidity, track.tpcSignal ());
@@ -377,9 +400,7 @@ struct nucleiFilter {
377400 }
378401
379402 if (cfgBetheBlochParams->get (iN, 5u ) > 0 .f ) {
380- double expBethe{tpc::BetheBlochAleph (static_cast <double >(track.tpcInnerParam () * fixTPCrigidity * bgScalings[iN][iC]), cfgBetheBlochParams->get (iN, 0u ), cfgBetheBlochParams->get (iN, 1u ), cfgBetheBlochParams->get (iN, 2u ), cfgBetheBlochParams->get (iN, 3u ), cfgBetheBlochParams->get (iN, 4u ))};
381- double expSigma{expBethe * cfgBetheBlochParams->get (iN, 5u )};
382- nSigmaTPC[iN] = static_cast <float >((track.tpcSignal () - expBethe) / expSigma);
403+ nSigmaTPC[iN] = getNsigma (track, iN, iC);
383404 }
384405 h2TPCnSigma[iN]->Fill (track.sign () * track.tpcInnerParam () * fixTPCrigidity, nSigmaTPC[iN]);
385406 if (nSigmaTPC[iN] < cfgCutsPID->get (iN, 0u ) || nSigmaTPC[iN] > cfgCutsPID->get (iN, 1u )) {
@@ -388,12 +409,61 @@ struct nucleiFilter {
388409 if (track.p () > cfgCutsPID->get (iN, 4u ) && (nSigmaTOF[iN] < cfgCutsPID->get (iN, 2u ) || nSigmaTOF[iN] > cfgCutsPID->get (iN, 3u ))) {
389410 continue ;
390411 }
391- keepEvent[iN] = true ;
392- if (keepEvent[iN]) {
412+ if (iN == 1 && passesDCAselection) {
413+ h3indices.push_back (track.globalIndex ());
414+ h3vectors.emplace_back (track.pt (), track.eta (), track.phi (), masses[iN]);
415+ }
416+ if (nucleusIndex[iN] < 0 ) {
417+ continue ;
418+ }
419+ keepEvent[nucleusIndex[iN]] = passesDCAselection;
420+ if (keepEvent[nucleusIndex[iN]]) {
393421 h2TPCsignal[iN]->Fill (track.sign () * track.tpcInnerParam () * fixTPCrigidity, track.tpcSignal ());
394422 }
395423 }
396424
425+ for (const auto & track : tracks) {
426+ if (track.itsNCls () < cfgCutNclusITS ||
427+ track.tpcNClsFound () < cfgCutNclusTPC ||
428+ std::abs (track.dcaXY ()) > cfgCutDCAxy ||
429+ std::abs (track.dcaZ ()) > cfgCutDCAz ||
430+ std::abs (track.eta ()) > cfgCutEta) {
431+ continue ;
432+ }
433+ const ROOT::Math::PtEtaPhiMVector trackVector (track.pt (), track.eta (), track.phi (), constants::physics::MassPiMinus);
434+ for (size_t iH3{0 }; iH3 < h3vectors.size (); ++iH3) {
435+ if (h3indices[iH3] == track.globalIndex ()) {
436+ continue ;
437+ }
438+ const auto & h3vector = h3vectors[iH3];
439+ auto pivector = trackVector;
440+ auto cm = h3vector + trackVector;
441+ const ROOT::Math::Boost boost (cm.BoostToCM ());
442+ boost (pivector);
443+ if (pivector.P () < cfgCutKstar) {
444+ keepEvent[kTritonFemto ] = true ;
445+ break ;
446+ }
447+ }
448+ }
449+
450+ for (const auto & v0 : v0s) {
451+ const auto & posTrack = tracks.rawIteratorAt (v0.posTrackId ());
452+ const auto & negTrack = tracks.rawIteratorAt (v0.negTrackId ());
453+ if ((posTrack.itsNCls () < cfgCutNclusITS || posTrack.tpcNClsFound () < cfgCutNclusTPC) &&
454+ (negTrack.itsNCls () < cfgCutNclusITS || negTrack.tpcNClsFound () < cfgCutNclusTPC)) {
455+ continue ;
456+ }
457+ float nSigmas[2 ]{
458+ cfgBetheBlochParams->get (2 , 5u ) > 0 .f ? getNsigma (posTrack, 2 , 0 ) : posTrack.tpcNSigmaHe (),
459+ cfgBetheBlochParams->get (2 , 5u ) > 0 .f ? getNsigma (negTrack, 2 , 1 ) : negTrack.tpcNSigmaHe ()};
460+ if ((nSigmas[0 ] > cfgCutsPID->get (2 , 0u ) && nSigmas[0 ] < cfgCutsPID->get (2 , 1u )) ||
461+ (nSigmas[1 ] > cfgCutsPID->get (2 , 0u ) && nSigmas[1 ] < cfgCutsPID->get (2 , 1u ))) {
462+ keepEvent[kHeV0 ] = true ;
463+ break ;
464+ }
465+ }
466+
397467 //
398468 // fill QA histograms
399469 //
@@ -531,7 +601,7 @@ struct nucleiFilter {
531601 qaHists.fill (HIST (" fBachDeuTOFNsigma" ), track2.p () * track2.sign (), tofNSigmaDeuteron);
532602 qaHists.fill (HIST (" fH3LDcaVsPt" ), pt3B, dcaDaughters);
533603 qaHists.fill (HIST (" fH3LCosPAVsPt" ), pt3B, vtxCosPA);
534- keepEvent[3 ] = true ;
604+ keepEvent[kH3L3Body ] = true ;
535605 }
536606 }
537607 if (invmassAntiH3L >= trgH3L3Body.h3LMassLowerlimit && invmassAntiH3L <= trgH3L3Body.h3LMassUpperlimit ) {
@@ -541,17 +611,20 @@ struct nucleiFilter {
541611 qaHists.fill (HIST (" fBachDeuTOFNsigma" ), track2.p () * track2.sign (), tofNSigmaDeuteron);
542612 qaHists.fill (HIST (" fH3LDcaVsPt" ), pt3B, dcaDaughters);
543613 qaHists.fill (HIST (" fH3LCosPAVsPt" ), pt3B, vtxCosPA);
544- keepEvent[3 ] = true ;
614+ keepEvent[kH3L3Body ] = true ;
545615 }
546616 }
547617 }
548618
549- for (int iDecision{0 }; iDecision < nNuclei + nHyperNuclei + nITStriggers; ++iDecision) {
619+ keepEvent[kTracked3Body ] = tracked3Bodys.size () > 0 ;
620+
621+ for (int iDecision{0 }; iDecision < kNtriggers ; ++iDecision) {
550622 if (keepEvent[iDecision]) {
551623 hProcessedEvents->Fill (iDecision + 1 );
552624 }
553625 }
554- tags (keepEvent[0 ], keepEvent[2 ], keepEvent[3 ], keepEvent[4 ], keepEvent[5 ]);
626+
627+ tags (keepEvent[kH2 ], keepEvent[kHe ], keepEvent[kHeV0 ], keepEvent[kTritonFemto ], keepEvent[kH3L3Body ], keepEvent[kTracked3Body ], keepEvent[kITSmildIonisation ], keepEvent[kITSextremeIonisation ]);
555628 }
556629};
557630
0 commit comments