@@ -44,6 +44,18 @@ enum LambdaPid { kLambda = 0,
4444// #define FLOAT_PRECISION 0xFFFFFFF0
4545#define O2_DEFINE_CONFIGURABLE (NAME, TYPE, DEFAULT, HELP ) Configurable<TYPE> NAME{#NAME, DEFAULT, HELP};
4646
47+ namespace o2 ::aod
48+ {
49+ namespace cfmultiplicity
50+ {
51+ DECLARE_SOA_COLUMN (Multiplicity, multiplicity, float );
52+ }
53+ DECLARE_SOA_TABLE (CFMultiplicities, " AOD" , " CFMULTIPLICITY" , cfmultiplicity::Multiplicity);
54+
55+ using CFMultiplicity = CFMultiplicities::iterator;
56+ } // namespace o2::aod
57+
58+
4759struct Filter2Prong {
4860 SliceCache cache;
4961 struct MixEvent {
@@ -791,126 +803,108 @@ struct Filter2Prong {
791803 } // end of loop over first track
792804 }
793805 PROCESS_SWITCH (Filter2Prong, processDataPhiV0, " Process data Phi and V0 candidates with invariant mass method" , false );
806+
794807
795- using MixCollisions = aod::CFCollisions;
796- Preslice<aod::CFTrackRefs> perCollisionCFTrackRef = aod::track::collisionId;
797- void processDataPhiMixed (aod::CFCollisions const & collisions,
798- aod::CFCollRefs const & cfcollrefs,
799- aod::CFTrackRefs const & cftracks,
800- Filter2Prong::PIDTrack const & tracks)
808+ using DerivedCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::CFMultiplicities>;
809+ void processDataPhiMixedFM (DerivedCollisions const & collisions, Filter2Prong::PIDTrack const & tracksP, aod::CFTrackRefs const & cftracks)
801810 {
802- const int nMixBins = AxisSpec (axisVertexMix).getNbins () * AxisSpec (axisMultiplicityMix).getNbins ();
803- if (mixingPools.empty ()) {
804- mixingPools.resize (nMixBins);
805- }
806-
807- using BinningTypeDerived = ColumnBinningPolicy<aod::collision::PosZ, aod::cfcollision::Multiplicity>;
808- BinningTypeDerived configurableBinning{{axisVertexMix, axisMultiplicityMix}, true };
811+ auto getMultiplicity = [](auto const & col) {
812+ return col.multiplicity ();
813+ };
814+ using BinningTypeDerived = FlexibleBinningPolicy<std::tuple<decltype (getMultiplicity)>, aod::collision::PosZ, decltype (getMultiplicity)>;
815+ BinningTypeDerived configurableBinningDerived{{getMultiplicity},{axisVertexMix, axisMultiplicityMix},true };
816+ auto tracksTuple = std::make_tuple (cftracks, cftracks);
817+ using TA = std::tuple_element<0 , decltype (tracksTuple)>::type;
818+ using TB = std::tuple_element<std::tuple_size_v<decltype (tracksTuple)> - 1 , decltype (tracksTuple)>::type;
819+ Pair<DerivedCollisions, TA, TB, BinningTypeDerived> pairs{configurableBinningDerived, cfgNoMixedEvents, -1 , collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip
809820
810821 o2::aod::ITSResponse itsResponse;
811-
812- for (const auto & collision : collisions) {
813- // int reducedCollisionId = collision.globalIndex();
814-
815- int redIdx = collision.globalIndex () - collisions.begin ().globalIndex ();
816- const auto & collRef = cfcollrefs.iteratorAt (redIdx);
817- int originalCollisionId = collRef.collisionId ();
818- int collRefGlobalIndex = collRef.globalIndex ();
819-
820- float zvtx = collision.posZ ();
821- float mult = collision.multiplicity ();
822- int mixBin = configurableBinning.getBin ({zvtx, mult});
823- if (mixBin < 0 || mixBin >= nMixBins) {
824- continue ;
825- }
826-
827- auto tracksCurrentRefs = cftracks.sliceBy (perCollisionCFTrackRef, originalCollisionId);
828-
829- for (const auto & prevEvent : mixingPools[mixBin]) {
830- if (prevEvent.originalCollisionId == originalCollisionId) {
831- continue ;
832- }
833- auto tracksMixedRefs = cftracks.sliceBy (perCollisionCFTrackRef, prevEvent.originalCollisionId );
834-
835- for (const auto & cftrack1 : tracksCurrentRefs) {
836- const auto & p1 = tracks.iteratorAt (cftrack1.trackId () - tracks.begin ().globalIndex ());
837-
838- if (p1.sign () != 1 ) {
839- continue ;
840- }
841- if (!selectionTrack (p1)) {
842- continue ;
843- }
844- if (grpPhi.ITSPIDSelection &&
845- p1.p () < grpPhi.ITSPIDPthreshold .value &&
846- !(itsResponse.nSigmaITS <o2::track::PID::Kaon>(p1) > grpPhi.lowITSPIDNsigma .value &&
847- itsResponse.nSigmaITS <o2::track::PID::Kaon>(p1) < grpPhi.highITSPIDNsigma .value )) {
848- continue ;
849- }
850- if (grpPhi.removefaketrack && isFakeTrack (p1)) {
851- continue ;
852- }
853-
854- for (const auto & cftrack2 : tracksMixedRefs) {
855- const auto & p2 = tracks.iteratorAt (cftrack2.trackId () - tracks.begin ().globalIndex ());
856-
857- if (p2.sign () != -1 ) {
858- continue ;
859- }
860- if (!selectionTrack (p2)) {
861- continue ;
862- }
863- if (grpPhi.ITSPIDSelection &&
864- p2.p () < grpPhi.ITSPIDPthreshold .value &&
865- !(itsResponse.nSigmaITS <o2::track::PID::Kaon>(p2) > grpPhi.lowITSPIDNsigma .value &&
866- itsResponse.nSigmaITS <o2::track::PID::Kaon>(p2) < grpPhi.highITSPIDNsigma .value )) {
867- continue ;
868- }
869- if (grpPhi.removefaketrack && isFakeTrack (p2)) {
870- continue ;
871- }
872- if (!selectionPair (p1, p2)) {
873- continue ;
874- }
875-
876- if (selectionPID3 (p1) && selectionPID3 (p2)) {
877- if (selectionSys (p1, false , false ) && selectionSys (p2, false , false )) {
878-
879- ROOT::Math::PtEtaPhiMVector vec1 (p1.pt (), p1.eta (), p1.phi (), cfgImPart1Mass);
880- ROOT::Math::PtEtaPhiMVector vec2 (p2.pt (), p2.eta (), p2.phi (), cfgImPart2Mass);
881- ROOT::Math::PtEtaPhiMVector s = vec1 + vec2;
882-
883- if (s.M () < grpPhi.ImMinInvMassPhiMeson || s.M () > grpPhi.ImMaxInvMassPhiMeson ) {
884- continue ;
885- }
886-
887- float phi = RecoDecay::constrainAngle (s.Phi (), 0 .0f );
888-
889- outputMixedPhiTracks (collRefGlobalIndex,
890- prevEvent.collRefGlobalIndex ,
891- cftrack1.globalIndex (),
892- cftrack2.globalIndex (),
893- p1.phi (),
894- p2.phi (),
895- s.pt (),
896- s.eta (),
897- phi,
898- s.M ());
899- }
900- }
901- }
902- }
903- }
904-
905- mixingPools[mixBin].push_back ({collRefGlobalIndex, originalCollisionId});
906-
907- if ((int )mixingPools[mixBin].size () > cfgNoMixedEvents) {
908- mixingPools[mixBin].erase (mixingPools[mixBin].begin ());
822+
823+ for (auto it = pairs.begin (); it != pairs.end (); it++) {
824+ auto & [collision1, tracks1, collision2, tracks2] = *it;
825+ // float multiplicity = getMultiplicity(collision1);
826+ // int bin = configurableBinningDerived.getBin(std::tuple(collision1.posZ(), multiplicity));
827+ // float eventWeight = 1.0f / it.currentWindowNeighbours();
828+ if (!(collision1.sel8 () &&
829+ collision1.selection_bit (aod::evsel::kNoSameBunchPileup ) &&
830+ collision1.selection_bit (aod::evsel::kIsGoodZvtxFT0vsPV ) &&
831+ collision1.selection_bit (aod::evsel::kIsGoodITSLayersAll ))) {
832+ continue ;
833+ }
834+
835+ if (!(collision2.sel8 () &&
836+ collision2.selection_bit (aod::evsel::kNoSameBunchPileup ) &&
837+ collision2.selection_bit (aod::evsel::kIsGoodZvtxFT0vsPV ) &&
838+ collision2.selection_bit (aod::evsel::kIsGoodITSLayersAll ))) {
839+ continue ;
840+ }
841+
842+ for (const auto & cftrack1 : tracks1) {
843+ const auto & p1 = tracksP.iteratorAt (cftrack1.trackId () - tracksP.begin ().globalIndex ());
844+
845+ if (p1.sign () != 1 ) {
846+ continue ;
847+ }
848+ if (!selectionTrack (p1)) {
849+ continue ;
850+ }
851+ if (grpPhi.ITSPIDSelection &&
852+ p1.p () < grpPhi.ITSPIDPthreshold .value &&
853+ !(itsResponse.nSigmaITS <o2::track::PID::Kaon>(p1) > grpPhi.lowITSPIDNsigma .value &&
854+ itsResponse.nSigmaITS <o2::track::PID::Kaon>(p1) < grpPhi.highITSPIDNsigma .value )) {
855+ continue ;
856+ }
857+ if (grpPhi.removefaketrack && isFakeTrack (p1)) {
858+ continue ;
859+ }
860+
861+ for (const auto & cftrack2 : tracks2) {
862+ const auto & p2 = tracksP.iteratorAt (cftrack2.trackId () - tracksP.begin ().globalIndex ());
863+
864+ if (p2.sign () != -1 ) {
865+ continue ;
866+ }
867+ if (!selectionTrack (p2)) {
868+ continue ;
869+ }
870+ if (grpPhi.ITSPIDSelection &&
871+ p2.p () < grpPhi.ITSPIDPthreshold .value &&
872+ !(itsResponse.nSigmaITS <o2::track::PID::Kaon>(p2) > grpPhi.lowITSPIDNsigma .value &&
873+ itsResponse.nSigmaITS <o2::track::PID::Kaon>(p2) < grpPhi.highITSPIDNsigma .value )) {
874+ continue ;
875+ }
876+ if (grpPhi.removefaketrack && isFakeTrack (p2)) {
877+ continue ;
878+ }
879+ if (!selectionPair (p1, p2)) {
880+ continue ;
881+ }
882+
883+ ROOT::Math::PtEtaPhiMVector vec1 (p1.pt (), p1.eta (), p1.phi (), cfgImPart1Mass);
884+ ROOT::Math::PtEtaPhiMVector vec2 (p2.pt (), p2.eta (), p2.phi (), cfgImPart2Mass);
885+ ROOT::Math::PtEtaPhiMVector s = vec1 + vec2;
886+
887+ if (s.M () < grpPhi.ImMinInvMassPhiMeson || s.M () > grpPhi.ImMaxInvMassPhiMeson ) {
888+ continue ;
889+ }
890+
891+ float phi = RecoDecay::constrainAngle (s.Phi (), 0 .0f );
892+
893+ if (selectionPID3 (p1) && selectionPID3 (p2)) {
894+ if (selectionSys (p1, false , false ) && selectionSys (p2, false , false )) {
895+ output2ProngTracks (collision1.globalIndex (),
896+ cftrack1.globalIndex (), cftrack2.globalIndex (),
897+ s.pt (), s.eta (), phi, s.M (),
898+ aod::cf2prongtrack::PhiToKKPID3Mixed);
899+ }
900+ }
901+ }
909902 }
910903 }
911904 }
912- PROCESS_SWITCH (Filter2Prong, processDataPhiMixed, " Process mixed-event phi candidates" , false );
913905
906+ PROCESS_SWITCH (Filter2Prong, processDataPhiMixedFM, " Process mixed-event phi candidates using O2 framework" , false );
907+
914908 // Phi and V0s invariant mass method candidate finder. Only works for non-identical daughters of opposite charge for now.
915909 void processDataV0 (aod::Collisions::iterator const & collision, aod::BCsWithTimestamps const &, aod::CFCollRefs const & cfcollisions, aod::CFTrackRefs const & cftracks, Filter2Prong::PIDTrack const &, aod::V0Datas const & V0s)
916910 {
0 commit comments