1717#include < Framework/Configurable.h>
1818#include < Math/GenVector/Boost.h>
1919#include < Math/Vector4D.h>
20+ #include < TLorentzVector.h>
2021#include < TMath.h>
2122#include < fairlogger/Logger.h>
2223#include < iostream>
2324#include < iterator>
2425#include < string>
25-
26+ #include < vector>
27+ #include " DataFormatsParameters/GRPMagField.h"
28+ #include " DataFormatsParameters/GRPObject.h"
29+ #include " ReconstructionDataFormats/Track.h"
30+ #include " ReconstructionDataFormats/TrackParametrization.h"
31+ #include " Common/Core/RecoDecay.h"
32+ #include " Common/Core/trackUtilities.h"
2633#include " ../filterTables.h"
2734#include " Framework/ASoAHelpers.h"
2835#include " Framework/AnalysisDataModel.h"
3643#include " Common/DataModel/Multiplicity.h"
3744#include " Common/DataModel/PIDResponse.h"
3845#include " PWGLF/DataModel/LFStrangenessTables.h"
46+ #include " PWGLF/Utils/strangenessBuilderHelper.h"
47+ #include " PWGLF/DataModel/LFParticleIdentification.h"
3948#include " CommonConstants/PhysicsConstants.h"
4049#include " DataFormatsTPC/BetheBlochAleph.h"
4150#include " CCDB/BasicCCDBManager.h"
@@ -151,8 +160,22 @@ struct filterf1proton {
151160 },
152161 OutputObjHandlingPolicy::AnalysisObject};
153162
163+ // helper object
164+ o2::pwglf::strangenessBuilderHelper mStraHelper ;
165+ int mRunNumber = 0 ;
166+ float mBz = 0 .;
167+
154168 void init (o2::framework::InitContext&)
155169 {
170+ // set V0 parameters in the helper
171+ mStraHelper .v0selections .minCrossedRows = ConfDaughTPCnclsMin;
172+ mStraHelper .v0selections .dcanegtopv = ConfDaughDCAMin;
173+ mStraHelper .v0selections .dcapostopv = ConfDaughDCAMin; // get the minimum one
174+ mStraHelper .v0selections .v0cospa = ConfV0CPAMin;
175+ mStraHelper .v0selections .dcav0dau = ConfV0DCADaughMax;
176+ mStraHelper .v0selections .v0radius = ConfV0TranRadV0Min;
177+ mStraHelper .v0selections .maxDaughterEta = ConfDaughEta;
178+
156179 ccdb->setURL (url.value );
157180 ccdbApi.init (url);
158181 ccdb->setCaching (true );
@@ -163,6 +186,26 @@ struct filterf1proton {
163186 hProcessedEvents->GetXaxis ()->SetBinLabel (3 , aod::filtering::TriggerEventF1Proton::columnLabel ());
164187 }
165188
189+ void initCCDB (int run)
190+ {
191+ if (run != mRunNumber ) {
192+ mRunNumber = run;
193+ o2::parameters::GRPMagField* grpmag = ccdb->getForRun <o2::parameters::GRPMagField>(" GLO/Config/GRPMagField" , run);
194+ o2::base::Propagator::initFieldFromGRP (grpmag);
195+ mBz = static_cast <float >(grpmag->getNominalL3Field ());
196+ mStraHelper .fitter .setBz (mBz );
197+ }
198+ if (!mStraHelper .lut ) { // / done only once
199+ ccdb->setURL (url.value );
200+ ccdb->setCaching (true );
201+ ccdb->setLocalObjectValidityChecking ();
202+ ccdb->setFatalWhenNull (true );
203+ auto * lut = o2::base::MatLayerCylSet::rectifyPtrFromFile (ccdb->get <o2::base::MatLayerCylSet>(" GLO/Param/MatLUT" ));
204+ o2::base::Propagator::Instance ()->setMatLUT (lut);
205+ mStraHelper .lut = lut;
206+ }
207+ }
208+
166209 template <typename T>
167210 bool isSelectedEvent (T const & col)
168211 {
@@ -257,10 +300,10 @@ struct filterf1proton {
257300 bool isSelectedV0Daughter (T const & track, float charge, double nsigmaV0Daughter)
258301 {
259302 const auto eta = track.eta ();
260- const auto tpcNClsF = track.tpcNClsFound ();
303+ // const auto tpcNClsF = track.tpcNClsFound();
304+ const auto tpcNClsF = track.tpcNClsCrossedRows ();
261305 const auto dcaXY = track.dcaXY ();
262306 const auto sign = track.sign ();
263-
264307 if (charge < 0 && sign > 0 ) {
265308 return false ;
266309 }
@@ -276,7 +319,6 @@ struct filterf1proton {
276319 if (std::abs (dcaXY) < ConfDaughDCAMin) {
277320 return false ;
278321 }
279-
280322 if (std::abs (nsigmaV0Daughter) > ConfDaughPIDCuts) {
281323 return false ;
282324 }
@@ -435,7 +477,7 @@ struct filterf1proton {
435477 // using EventCandidates = soa::Join<aod::Collisions, aod::EvSels, aod::Mults>;
436478 using EventCandidates = aod::Collisions;
437479 using ResoV0s = aod::V0Datas;
438- using PrimaryTrackCandidates = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection,
480+ using PrimaryTrackCandidates = soa::Filtered<soa::Join<aod::Tracks, aod::TracksCovIU, aod::TracksIU, aod:: TracksExtra, aod::TracksDCA, aod::TrackSelection,
439481 aod::pidTPCFullPi, aod::pidTOFFullPi,
440482 aod::pidTPCFullKa, aod::pidTOFFullKa,
441483 aod::pidTPCFullPr, aod::pidTOFFullPr>>;
@@ -572,8 +614,8 @@ struct filterf1proton {
572614 if (!SelectionV0 (collision, v0)) {
573615 continue ;
574616 }
575- auto postrack = v0.template posTrack_as <PrimaryTrackCandidates>();
576- auto negtrack = v0.template negTrack_as <PrimaryTrackCandidates>();
617+ auto postrack = v0.posTrack_as <PrimaryTrackCandidates>();
618+ auto negtrack = v0.negTrack_as <PrimaryTrackCandidates>();
577619 double nTPCSigmaPos[1 ]{postrack.tpcNSigmaPi ()};
578620 double nTPCSigmaNeg[1 ]{negtrack.tpcNSigmaPi ()};
579621 if (ConfUseManualPIDdaughterPion) {
@@ -655,7 +697,254 @@ struct filterf1proton {
655697 }
656698 tags (keepEventF1Proton);
657699 }
658- PROCESS_SWITCH (filterf1proton, processF1Proton, " Process for trigger" , true );
700+ PROCESS_SWITCH (filterf1proton, processF1Proton, " Process for trigger" , false );
701+ TLorentzVector v0Dummy;
702+ void processF1ProtonHelper (EventCandidates::iterator const & collision, aod::BCsWithTimestamps const &, PrimaryTrackCandidates const & tracks, aod::V0s const & V0s)
703+ {
704+ initCCDB (collision.bc ().runNumber ());
705+ bool keepEventF1Proton = false ;
706+ int numberF1 = 0 ;
707+ if (isSelectedEvent (collision)) {
708+ if (ConfUseManualPIDproton || ConfUseManualPIDkaon || ConfUseManualPIDpion) {
709+ currentRunNumber = collision.bc_as <aod::BCsWithTimestamps>().runNumber ();
710+ if (currentRunNumber != lastRunNumber) {
711+ auto bc = collision.bc_as <aod::BCsWithTimestamps>();
712+ if (ConfUseManualPIDproton) {
713+ BBProton = setValuesBB (ccdbApi, bc, ConfPIDBBProton);
714+ BBAntiproton = setValuesBB (ccdbApi, bc, ConfPIDBBAntiProton);
715+ }
716+ if (ConfUseManualPIDpion) {
717+ BBPion = setValuesBB (ccdbApi, bc, ConfPIDBBPion);
718+ BBAntipion = setValuesBB (ccdbApi, bc, ConfPIDBBAntiPion);
719+ }
720+ if (ConfUseManualPIDkaon) {
721+ BBKaon = setValuesBB (ccdbApi, bc, ConfPIDBBKaon);
722+ BBAntikaon = setValuesBB (ccdbApi, bc, ConfPIDBBAntiKaon);
723+ }
724+ lastRunNumber = currentRunNumber;
725+ }
726+ }
727+
728+ // keep track of indices
729+ std::vector<int > PionIndex = {};
730+ std::vector<int > KaonIndex = {};
731+ std::vector<int > ProtonIndex = {};
732+
733+ // keep charge of track
734+ std::vector<float > PionCharge = {};
735+ std::vector<float > KaonCharge = {};
736+ std::vector<float > ProtonCharge = {};
737+
738+ // Prepare vectors for different species
739+ std::vector<ROOT::Math::PtEtaPhiMVector> protons, kaons, pions, kshorts;
740+ float kstar = 999 .f ;
741+
742+ for (auto & track : tracks) {
743+
744+ if (!isSelectedTrack (track))
745+ continue ;
746+ qaRegistry.fill (HIST (" hDCAxy" ), track.dcaXY ());
747+ qaRegistry.fill (HIST (" hDCAz" ), track.dcaZ ());
748+ qaRegistry.fill (HIST (" hEta" ), track.eta ());
749+ qaRegistry.fill (HIST (" hPhi" ), track.phi ());
750+ double nTPCSigmaP[3 ]{track.tpcNSigmaPi (), track.tpcNSigmaKa (), track.tpcNSigmaPr ()};
751+ double nTPCSigmaN[3 ]{track.tpcNSigmaPi (), track.tpcNSigmaKa (), track.tpcNSigmaPr ()};
752+ if (ConfUseManualPIDproton) {
753+ auto bgScalingProton = 1 / massPr; // momentum scaling?
754+ if (BBProton.size () == 6 )
755+ nTPCSigmaP[2 ] = updatePID (track, bgScalingProton, BBProton);
756+ if (BBAntiproton.size () == 6 )
757+ nTPCSigmaN[2 ] = updatePID (track, bgScalingProton, BBAntiproton);
758+ }
759+ if (ConfUseManualPIDkaon) {
760+ auto bgScalingKaon = 1 / massKa; // momentum scaling?
761+ if (BBKaon.size () == 6 )
762+ nTPCSigmaP[1 ] = updatePID (track, bgScalingKaon, BBKaon);
763+ if (BBAntikaon.size () == 6 )
764+ nTPCSigmaN[1 ] = updatePID (track, bgScalingKaon, BBAntikaon);
765+ }
766+ if (ConfUseManualPIDpion) {
767+ auto bgScalingPion = 1 / massPi; // momentum scaling?
768+ if (BBPion.size () == 6 )
769+ nTPCSigmaP[0 ] = updatePID (track, bgScalingPion, BBPion);
770+ if (BBAntipion.size () == 6 )
771+ nTPCSigmaN[0 ] = updatePID (track, bgScalingPion, BBAntipion);
772+ }
773+
774+ if ((track.sign () > 0 && SelectionPID (track, strategyPIDPion, 0 , nTPCSigmaP[0 ])) || (track.sign () < 0 && SelectionPID (track, strategyPIDPion, 0 , nTPCSigmaN[0 ]))) {
775+ ROOT::Math::PtEtaPhiMVector temp (track.pt (), track.eta (), track.phi (), massPi);
776+ pions.push_back (temp);
777+ PionIndex.push_back (track.globalIndex ());
778+ PionCharge.push_back (track.sign ());
779+ if (track.sign () > 0 ) {
780+ qaRegistry.fill (HIST (" hNsigmaPtpionTPC" ), nTPCSigmaP[0 ], track.pt ());
781+ }
782+ if (track.sign () < 0 ) {
783+ qaRegistry.fill (HIST (" hNsigmaPtpionTPC" ), nTPCSigmaN[0 ], track.pt ());
784+ }
785+ if (track.hasTOF ()) {
786+ qaRegistry.fill (HIST (" hNsigmaPtpionTOF" ), track.tofNSigmaPi (), track.pt ());
787+ }
788+ }
789+
790+ if ((track.pt () > cMinKaonPt && track.sign () > 0 && SelectionPID (track, strategyPIDKaon, 1 , nTPCSigmaP[1 ])) || (track.pt () > cMinKaonPt && track.sign () < 0 && SelectionPID (track, strategyPIDKaon, 1 , nTPCSigmaN[1 ]))) {
791+ ROOT::Math::PtEtaPhiMVector temp (track.pt (), track.eta (), track.phi (), massKa);
792+ kaons.push_back (temp);
793+ KaonIndex.push_back (track.globalIndex ());
794+ KaonCharge.push_back (track.sign ());
795+ if (track.sign () > 0 ) {
796+ qaRegistry.fill (HIST (" hNsigmaPtkaonTPC" ), nTPCSigmaP[1 ], track.pt ());
797+ }
798+ if (track.sign () < 0 ) {
799+ qaRegistry.fill (HIST (" hNsigmaPtkaonTPC" ), nTPCSigmaN[1 ], track.pt ());
800+ }
801+ if (track.hasTOF ()) {
802+ qaRegistry.fill (HIST (" hNsigmaPtkaonTOF" ), track.tofNSigmaKa (), track.pt ());
803+ }
804+ }
805+
806+ if ((track.pt () < cMaxProtonPt && track.sign () > 0 && SelectionPID (track, strategyPIDProton, 2 , nTPCSigmaP[2 ])) || (track.pt () < cMaxProtonPt && track.sign () < 0 && SelectionPID (track, strategyPIDProton, 2 , nTPCSigmaN[2 ]))) {
807+ ROOT::Math::PtEtaPhiMVector temp (track.pt (), track.eta (), track.phi (), massPr);
808+ qaRegistry.fill (HIST (" hMommentumCorr" ), track.p () / track.sign (), track.p () - track.tpcInnerParam ());
809+ if (ConfFakeProton && !isFakeProton (track)) {
810+ protons.push_back (temp);
811+ ProtonIndex.push_back (track.globalIndex ());
812+ ProtonCharge.push_back (track.sign ());
813+ }
814+ if (track.sign () > 0 ) {
815+ qaRegistry.fill (HIST (" hNsigmaPtprotonTPC" ), nTPCSigmaP[2 ], track.pt ());
816+ }
817+ if (track.sign () < 0 ) {
818+ qaRegistry.fill (HIST (" hNsigmaPtprotonTPC" ), nTPCSigmaN[2 ], track.pt ());
819+ }
820+ if (track.hasTOF ()) {
821+ qaRegistry.fill (HIST (" hNsigmaPtprotonTOF" ), track.tofNSigmaPr (), track.pt ());
822+ }
823+ }
824+ } // track loop end
825+
826+ // keep track of daugher indices to avoid selfcorrelations
827+ std::vector<int > KshortPosDaughIndex = {};
828+ std::vector<int > KshortNegDaughIndex = {};
829+
830+ for (auto & v0 : V0s) {
831+
832+ auto postrack = v0.template posTrack_as <PrimaryTrackCandidates>();
833+ auto negtrack = v0.template negTrack_as <PrimaryTrackCandidates>();
834+ auto trackparpos = getTrackParCov (postrack);
835+ auto trackparneg = getTrackParCov (negtrack);
836+ if (!mStraHelper .buildV0Candidate (v0.collisionId (), collision.posX (), collision.posY (), collision.posZ (), postrack, negtrack, trackparpos, trackparneg)) {
837+ continue ;
838+ }
839+
840+ if (fabs (mStraHelper .v0 .dcaToPV ) > cMaxV0DCA) {
841+ continue ;
842+ }
843+ auto v0px = mStraHelper .v0 .momentum [0 ];
844+ auto v0py = mStraHelper .v0 .momentum [1 ];
845+ auto v0pz = mStraHelper .v0 .momentum [2 ];
846+ auto pT = std::sqrt (v0px * v0px + v0py * v0py);
847+ if (pT < ConfV0PtMin) {
848+ continue ;
849+ }
850+ if (std::hypot (mStraHelper .v0 .position [0 ], mStraHelper .v0 .position [1 ]) < ConfV0TranRadV0Min) {
851+ continue ;
852+ }
853+ if (std::hypot (mStraHelper .v0 .position [0 ], mStraHelper .v0 .position [1 ]) > ConfV0TranRadV0Max) {
854+ continue ;
855+ }
856+ double distovertotmom = std::hypot (mStraHelper .v0 .position [0 ] - collision.posX (), mStraHelper .v0 .position [1 ] - collision.posY (), mStraHelper .v0 .position [2 ] - collision.posZ ()) / (std::hypot (mStraHelper .v0 .momentum [0 ], mStraHelper .v0 .momentum [1 ], mStraHelper .v0 .momentum [2 ]) + 1e-13 );
857+ if (distovertotmom * o2::constants::physics::MassK0Short > cMaxV0LifeTime) {
858+ continue ;
859+ }
860+ float lowmasscutks0 = 0.497 - 2.0 * cSigmaMassKs0;
861+ float highmasscutks0 = 0.497 + 2.0 * cSigmaMassKs0;
862+ if (mStraHelper .v0 .massK0Short < lowmasscutks0 || mStraHelper .v0 .massK0Short > highmasscutks0) {
863+ continue ;
864+ }
865+ double nTPCSigmaPos[1 ]{postrack.tpcNSigmaPi ()};
866+ double nTPCSigmaNeg[1 ]{negtrack.tpcNSigmaPi ()};
867+ if (ConfUseManualPIDdaughterPion) {
868+ auto bgScalingPion = 1 / massPi; // momentum scaling?
869+ if (BBPion.size () == 6 )
870+ nTPCSigmaPos[0 ] = updatePID (postrack, bgScalingPion, BBPion);
871+ if (BBAntipion.size () == 6 )
872+ nTPCSigmaNeg[0 ] = updatePID (negtrack, bgScalingPion, BBAntipion);
873+ }
874+ if (!isSelectedV0Daughter (postrack, 1 , nTPCSigmaPos[0 ])) {
875+ continue ;
876+ }
877+ if (!isSelectedV0Daughter (negtrack, -1 , nTPCSigmaNeg[0 ])) {
878+ continue ;
879+ }
880+ v0Dummy.SetXYZM (v0px, v0py, v0pz, mStraHelper .v0 .massK0Short );
881+ qaRegistry.fill (HIST (" hInvMassk0" ), v0Dummy.M (), pT);
882+ ROOT::Math::PtEtaPhiMVector temp (pT, v0Dummy.Eta (), v0Dummy.Phi (), mStraHelper .v0 .massK0Short );
883+ kshorts.push_back (temp);
884+ KshortPosDaughIndex.push_back (postrack.globalIndex ());
885+ KshortNegDaughIndex.push_back (negtrack.globalIndex ());
886+ }
887+
888+ if (pions.size () != 0 && kaons.size () != 0 && kshorts.size () != 0 ) {
889+ for (auto ipion = pions.begin (); ipion != pions.end (); ++ipion) {
890+ for (auto ikaon = kaons.begin (); ikaon != kaons.end (); ++ikaon) {
891+ auto i1 = std::distance (pions.begin (), ipion);
892+ auto i2 = std::distance (kaons.begin (), ikaon);
893+ // if(PionCharge.at(i1)*KaonCharge.at(i2)>0)continue;
894+ if (PionIndex.at (i1) == KaonIndex.at (i2))
895+ continue ;
896+ for (auto ikshort = kshorts.begin (); ikshort != kshorts.end (); ++ikshort) {
897+ auto i3 = std::distance (kshorts.begin (), ikshort);
898+ if (PionIndex.at (i1) == KshortPosDaughIndex.at (i3))
899+ continue ;
900+ if (PionIndex.at (i1) == KshortNegDaughIndex.at (i3))
901+ continue ;
902+ KKs0Vector = kaons.at (i2) + kshorts.at (i3);
903+ if (KKs0Vector.M () > cMaxMassKKs0)
904+ continue ;
905+ F1Vector = KKs0Vector + pions.at (i1);
906+ if (F1Vector.M () > cMaxMassF1)
907+ continue ;
908+ if (F1Vector.Pt () < cMinF1Pt)
909+ continue ;
910+ if (PionCharge.at (i1) * KaonCharge.at (i2) > 0 ) {
911+ qaRegistry.fill (HIST (" hInvMassf1Like" ), F1Vector.M (), F1Vector.Pt ());
912+ continue ;
913+ }
914+ qaRegistry.fill (HIST (" hInvMassf1" ), F1Vector.M (), F1Vector.Pt ());
915+ numberF1 = numberF1 + 1 ;
916+ for (auto iproton = protons.begin (); iproton != protons.end (); ++iproton) {
917+ auto i4 = std::distance (protons.begin (), iproton);
918+ if (ProtonIndex.at (i4) == PionIndex.at (i1))
919+ continue ;
920+ if (ProtonIndex.at (i4) == KaonIndex.at (i2))
921+ continue ;
922+ if (ProtonIndex.at (i4) == KshortPosDaughIndex.at (i3))
923+ continue ;
924+ if (ProtonIndex.at (i4) == KshortNegDaughIndex.at (i3))
925+ continue ;
926+ kstar = getkstar (F1Vector, *iproton);
927+ qaRegistry.fill (HIST (" hkstarDist" ), kstar);
928+ if (kstar > cMaxRelMom)
929+ continue ;
930+ qaRegistry.fill (HIST (" hInvMassf1kstar" ), F1Vector.M (), F1Vector.Pt (), kstar);
931+ keepEventF1Proton = true ;
932+ }
933+ }
934+ }
935+ }
936+ }
937+ }
938+ hProcessedEvents->Fill (0.5 );
939+ if (numberF1 > 0 ) {
940+ hProcessedEvents->Fill (1.5 );
941+ }
942+ if (keepEventF1Proton) {
943+ hProcessedEvents->Fill (2.5 );
944+ }
945+ tags (keepEventF1Proton);
946+ }
947+ PROCESS_SWITCH (filterf1proton, processF1ProtonHelper, " Process for trigger with helper v0 task" , true );
659948};
660949
661950WorkflowSpec defineDataProcessing (ConfigContext const & cfg)
0 commit comments