1515// / \author Omar Vazquez (omar.vazquez.rueda@cern.ch)
1616// / \since January 29, 2025
1717
18- #include < CCDB/BasicCCDBManager.h>
19-
20- #include < chrono>
21- #include < cmath>
22- #include < cstddef>
23- #include < cstdint>
24- #include < cstdlib>
25- #include < string>
26- #include < string_view>
27- #include < vector>
28- #include < TRandom.h>
29-
3018#include " Common/CCDB/EventSelectionParams.h"
3119#include " Common/CCDB/TriggerAliases.h"
3220#include " Common/Core/TrackSelection.h"
3321#include " Common/DataModel/Centrality.h"
3422#include " Common/DataModel/EventSelection.h"
3523#include " Common/DataModel/Multiplicity.h"
3624#include " Common/DataModel/TrackSelectionTables.h"
25+
3726#include " CommonConstants/MathConstants.h"
3827#include " CommonConstants/ZDCConstants.h"
3928#include " Framework/ASoAHelpers.h" // required for Filter op.
4433#include " Framework/runDataProcessing.h"
4534#include " ReconstructionDataFormats/GlobalTrackID.h"
4635#include " ReconstructionDataFormats/Track.h"
36+ #include < CCDB/BasicCCDBManager.h>
37+
4738#include " TPDGCode.h"
39+ #include < TRandom.h>
40+
41+ #include < chrono>
42+ #include < cmath>
43+ #include < cstddef>
44+ #include < cstdint>
45+ #include < cstdlib>
46+ #include < numeric>
47+ #include < string>
48+ #include < string_view>
49+ #include < vector>
4850
4951using namespace std ;
5052using namespace o2 ;
@@ -81,6 +83,7 @@ struct UccZdc {
8183 Configurable<bool > isZEMcut{" isZEMcut" , true , " Use ZEM cut" };
8284 Configurable<bool > useMidRapNchSel{" useMidRapNchSel" , true , " Use mid-rapidit Nch selection" };
8385 Configurable<bool > applyEff{" applyEff" , true , " Apply track-by-track efficiency correction" };
86+ Configurable<bool > correctNch{" correctNch" , true , " Correct also Nch" };
8487
8588 // Event selection
8689 Configurable<float > posZcut{" posZcut" , +10.0 , " z-vertex position cut" };
@@ -126,7 +129,8 @@ struct UccZdc {
126129 ConfigurableAxis binsCent{" binsCent" , {VARIABLE_WIDTH, 0 ., 10 ., 20 ., 30 ., 40 ., 50 ., 60 ., 70 ., 80 ., 90 ., 100 .}, " T0C binning" };
127130
128131 // CCDB paths
129- Configurable<std::string> paTH{" paTH" , " Users/o/omvazque/TrackingEfficiency" , " base path to the ccdb object" };
132+ Configurable<std::string> paTHEff{" paTHEff" , " Users/o/omvazque/MCcorrection/perTimeStamp/TrackingEff" , " base path to the ccdb object" };
133+ Configurable<std::string> paTHFD{" paTHFD" , " Users/o/omvazque/MCcorrection/perTimeStamp/FeedDown" , " base path to the ccdb object" };
130134 Configurable<std::string> paTHmeanNch{" paTHmeanNch" , " Users/o/omvazque/FitMeanNch_9May2025" , " base path to the ccdb object" };
131135 Configurable<std::string> paTHsigmaNch{" paTHsigmaNch" , " Users/o/omvazque/FitSigmaNch_9May2025" , " base path to the ccdb object" };
132136 Configurable<int64_t > ccdbNoLaterThan{" ccdbNoLaterThan" , std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count (), " latest acceptable timestamp of creation for the object" };
@@ -238,6 +242,9 @@ struct UccZdc {
238242 registry.add (" NchVsThreeParCorr" , " MC closure;#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(3)}]#GT" , kTProfile , {{nBinsNch, minNch, maxNch}});
239243 registry.add (" NchVsFourParCorr" , " MC closure;#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(4)}]#GT" , kTProfile , {{nBinsNch, minNch, maxNch}});
240244 // Corrections
245+ registry.add (" NchRec" , " Corrections;#it{N}_{ch} (|#eta| < 0.8);Entries;" , kTH1F , {{nBinsNch, minNch, maxNch}});
246+ registry.add (" NchTrue" , " Corrections;#it{N}_{ch} (|#eta| < 0.8);Entries;" , kTH1F , {{nBinsNch, minNch, maxNch}});
247+
241248 registry.add (" zPosMC" , " Filled at MC closure + Corrections;;Entries;" , kTH1F , {axisZpos});
242249 registry.add (" hEventCounterMC" , " Event counter" , kTH1F , {axisEvent});
243250 registry.add (" nRecColvsCent" , " " , kTH2F , {{6 , -0.5 , 5.5 }, {{axisCent}}});
@@ -292,8 +299,11 @@ struct UccZdc {
292299
293300 LOG (info) << " \t ccdbNoLaterThan=" << ccdbNoLaterThan.value ;
294301 LOG (info) << " \t applyEff=" << applyEff.value ;
295- LOG (info) << " \t paTH=" << paTH.value ;
302+ LOG (info) << " \t correctNch=" << correctNch.value ;
303+ LOG (info) << " \t paTHEff=" << paTHEff.value ;
304+ LOG (info) << " \t paTHFD=" << paTHFD.value ;
296305 LOG (info) << " \t useMidRapNchSel=" << useMidRapNchSel.value ;
306+ LOG (info) << " \t nSigmaNchCut=" << nSigmaNchCut.value ;
297307 LOG (info) << " \t paTHmeanNch=" << paTHmeanNch.value ;
298308 LOG (info) << " \t paTHsigmaNch=" << paTHsigmaNch.value ;
299309 LOG (info) << " \t minPt=" << minPt.value ;
@@ -681,48 +691,55 @@ struct UccZdc {
681691 }
682692 }
683693
694+ // Skip event based on number of Nch sigmas
684695 if (!skipEvent) {
685696 return ;
686697 }
687698
688- auto efficiency = ccdb->getForTimeStamp <TH1F>(paTH .value , foundBC.timestamp ());
689- // auto efficiency = ccdb->getForRun <TH1F>(paTH .value, foundBC.runNumber ());
690- if (!efficiency) {
699+ auto efficiency = ccdb->getForTimeStamp <TH1F>(paTHEff .value , foundBC.timestamp ());
700+ auto fd = ccdb->getForTimeStamp <TH1F>(paTHFD .value , foundBC.timestamp ());
701+ if (!efficiency || !fd ) {
691702 return ;
692703 }
693704
694705 std::vector<float > pTs;
695- std::vector<float > wIs;
696- // Calculates the event weight, W_k
706+ std::vector<float > vecFD;
707+ std::vector<float > vecOneOverEff;
708+
709+ // Calculates the Nch multiplicity
697710 for (const auto & track : tracks) {
698711 // Track Selection
699712 if (!track.isGlobalTrack ()) {
700713 continue ;
701714 }
702- if ((track.pt () < minPt) || (track.pt () > maxPtSpectra )) {
715+ if ((track.pt () < minPt) || (track.pt () > maxPt )) {
703716 continue ;
704717 }
705718
706719 float pt{track.pt ()};
707- double weight {1 .};
720+ float effValue {1.0 };
708721 if (applyEff) {
709- weight = efficiency->GetBinContent (efficiency->FindBin (pt));
722+ effValue = efficiency->GetBinContent (efficiency->FindBin (pt));
710723 }
711- if (weight > 0 .) {
712- pTs.emplace_back (pt);
713- wIs.emplace_back (weight);
724+ if (effValue > 0 .) {
725+ vecOneOverEff.emplace_back (1 . / effValue);
714726 }
715727 }
716728
717- double p1, p2, p3, p4, w1, w2, w3, w4;
718- p1 = p2 = p3 = p4 = w1 = w2 = w3 = w4 = 0.0 ;
719- getPTpowers (pTs, wIs, p1, w1, p2, w2, p3, w3, p4, w4);
720- const double nch{static_cast <double >(pTs.size ())};
721- if (nch < minNchSel) {
729+ double nchMult{0 .};
730+ nchMult = std::accumulate (vecOneOverEff.begin (), vecOneOverEff.end (), 0 );
731+ if (!applyEff)
732+ nchMult = static_cast <double >(glbTracks);
733+ if (applyEff && !correctNch)
734+ nchMult = static_cast <double >(glbTracks);
735+ if (nchMult < minNchSel) {
722736 return ;
723737 }
724738
725- // To calculate event-averaged <pt>
739+ // Fill vectors for [pT] measurement
740+ pTs.clear ();
741+ vecFD.clear ();
742+ vecOneOverEff.clear ();
726743 for (const auto & track : tracks) {
727744 // Track Selection
728745 if (!track.isGlobalTrack ()) {
@@ -731,9 +748,27 @@ struct UccZdc {
731748 if ((track.pt () < minPt) || (track.pt () > maxPtSpectra)) {
732749 continue ;
733750 }
734- registry.fill (HIST (" NchVsZNVsPt" ), w1, sumZNs, track.pt ());
751+
752+ float pt{track.pt ()};
753+ float effValue{1 .};
754+ float fdValue{1 .};
755+ if (applyEff) {
756+ effValue = efficiency->GetBinContent (efficiency->FindBin (pt));
757+ fdValue = fd->GetBinContent (fd->FindBin (pt));
758+ }
759+ if ((effValue > 0 .) && (fdValue > 0 .)) {
760+ pTs.emplace_back (pt);
761+ vecOneOverEff.emplace_back (1 . / effValue);
762+ vecFD.emplace_back (fdValue);
763+ }
764+ // To calculate event-averaged <pt>
765+ registry.fill (HIST (" NchVsZNVsPt" ), nchMult, sumZNs, track.pt ());
735766 }
736767
768+ double p1, p2, p3, p4, w1, w2, w3, w4;
769+ p1 = p2 = p3 = p4 = w1 = w2 = w3 = w4 = 0.0 ;
770+ getPTpowers (pTs, vecOneOverEff, vecFD, p1, w1, p2, w2, p3, w3, p4, w4);
771+
737772 // EbE one-particle pT correlation
738773 double oneParCorr{p1 / w1};
739774
@@ -752,20 +787,20 @@ struct UccZdc {
752787 double numFourParCorr{std::pow (p1, 4 .) - 6 . * p2 * std::pow (p1, 2 .) + 3 . * std::pow (p2, 2 .) + 8 * p3 * p1 - 6 . * p4};
753788 double fourParCorr{numFourParCorr / denFourParCorr};
754789
755- registry.fill (HIST (" Nch" ), w1 );
790+ registry.fill (HIST (" Nch" ), nchMult );
756791 registry.fill (HIST (" ZNamp" ), sumZNs);
757- registry.fill (HIST (" NchVsZN" ), w1 , sumZNs);
758- registry.fill (HIST (" NchVsZP" ), w1 , sumZPs);
792+ registry.fill (HIST (" NchVsZN" ), nchMult , sumZNs);
793+ registry.fill (HIST (" NchVsZP" ), nchMult , sumZPs);
759794 registry.fill (HIST (" NITSTacksVsZN" ), itsTracks, sumZNs);
760795 registry.fill (HIST (" NITSTacksVsZP" ), itsTracks, sumZPs);
761796 registry.fill (HIST (" T0MVsZN" ), normT0M, sumZNs);
762797 registry.fill (HIST (" T0MVsZP" ), normT0M, sumZPs);
763798 registry.fill (HIST (" NchUncorrected" ), glbTracks);
764- registry.fill (HIST (" NchVsOneParCorr" ), w1 , oneParCorr, w1);
765- registry.fill (HIST (" NchVsOneParCorrVsZN" ), w1 , sumZNs, oneParCorr, w1);
766- registry.fill (HIST (" NchVsTwoParCorrVsZN" ), w1 , sumZNs, twoParCorr, denTwoParCorr);
767- registry.fill (HIST (" NchVsThreeParCorrVsZN" ), w1 , sumZNs, threeParCorr, denThreeParCorr);
768- registry.fill (HIST (" NchVsFourParCorrVsZN" ), w1 , sumZNs, fourParCorr, denFourParCorr);
799+ registry.fill (HIST (" NchVsOneParCorr" ), nchMult , oneParCorr, w1);
800+ registry.fill (HIST (" NchVsOneParCorrVsZN" ), nchMult , sumZNs, oneParCorr, w1);
801+ registry.fill (HIST (" NchVsTwoParCorrVsZN" ), nchMult , sumZNs, twoParCorr, denTwoParCorr);
802+ registry.fill (HIST (" NchVsThreeParCorrVsZN" ), nchMult , sumZNs, threeParCorr, denThreeParCorr);
803+ registry.fill (HIST (" NchVsFourParCorrVsZN" ), nchMult , sumZNs, fourParCorr, denFourParCorr);
769804 }
770805 PROCESS_SWITCH (UccZdc, processZdcCollAss, " Process ZDC W/Coll Ass." , true );
771806
@@ -774,7 +809,6 @@ struct UccZdc {
774809 TRandom* randPointer = new TRandom();
775810 void processMCclosure (aod::McCollisions::iterator const & mccollision, soa::SmallGroups<o2::aod::SimCollisions> const & collisions, o2::aod::BCsRun3 const & /* bcs*/ , aod::McParticles const & mcParticles, TheFilteredSimTracks const & simTracks)
776811 {
777-
778812 float rndNum = randPointer->Uniform (0.0 , 1.0 );
779813 registry.fill (HIST (" RandomNumber" ), rndNum);
780814
@@ -809,14 +843,17 @@ struct UccZdc {
809843
810844 // To use run-by-run efficiency
811845 const auto & foundBC = collision.foundBC_as <o2::aod::BCsRun3>();
812- // auto efficiency = ccdb->getForTimeStamp<TH1F>(paTH .value, foundBC.timestamp());
813- auto efficiency = ccdb->getForRun <TH1F>(paTH .value , foundBC.runNumber ());
814- if (!efficiency) {
815- continue ;
846+ auto efficiency = ccdb->getForTimeStamp <TH1F>(paTHEff .value , foundBC.timestamp ());
847+ auto fd = ccdb->getForTimeStamp <TH1F>(paTHFD .value , foundBC.timestamp ());
848+ if (!efficiency || !fd ) {
849+ return ;
816850 }
817851
852+ int nchRaw{0 };
818853 std::vector<float > pTs;
819- std::vector<float > wIs;
854+ std::vector<float > vecFD;
855+ std::vector<float > vecOneOverEff;
856+ // std::vector<float> wIs;
820857 const auto & groupedTracks{simTracks.sliceBy (perCollision, collision.globalIndex ())};
821858 // Calculates the event weight, W_k
822859 for (const auto & track : groupedTracks) {
@@ -826,22 +863,29 @@ struct UccZdc {
826863 }
827864
828865 float pt{track.pt ()};
829- double weight{efficiency->GetBinContent (efficiency->FindBin (pt))};
830- if (!(weight > 0 .)) {
831- continue ;
866+ float effValue{1 .};
867+ float fdValue{1 .};
868+ nchRaw++;
869+ if (applyEff) {
870+ effValue = efficiency->GetBinContent (efficiency->FindBin (pt));
871+ fdValue = fd->GetBinContent (fd->FindBin (pt));
872+ }
873+ if ((effValue > 0 .) && (fdValue > 0 .)) {
874+ pTs.emplace_back (pt);
875+ vecOneOverEff.emplace_back (1 . / effValue);
876+ vecFD.emplace_back (fdValue);
832877 }
833- pTs.emplace_back (pt);
834- wIs.emplace_back (weight);
835878 }
836879
837- const double nch{static_cast <double >(pTs.size ())};
838- if (nch < minNchSel) {
839- continue ;
880+ double nchMult{0 .};
881+ nchMult = std::accumulate (vecOneOverEff.begin (), vecOneOverEff.end (), 0 );
882+ if (nchMult < minNchSel) {
883+ return ;
840884 }
841885
842886 double p1, p2, p3, p4, w1, w2, w3, w4;
843887 p1 = p2 = p3 = p4 = w1 = w2 = w3 = w4 = 0.0 ;
844- getPTpowers (pTs, wIs , p1, w1, p2, w2, p3, w3, p4, w4);
888+ getPTpowers (pTs, vecOneOverEff, vecFD , p1, w1, p2, w2, p3, w3, p4, w4);
845889
846890 const double denTwoParCorr{std::pow (w1, 2 .) - w2};
847891 const double numTwoParCorr{std::pow (p1, 2 .) - p2};
@@ -855,16 +899,18 @@ struct UccZdc {
855899 const double threeParCorr{numThreeParCorr / denThreeParCorr};
856900 const double fourParCorr{numFourParCorr / denFourParCorr};
857901
858- registry.fill (HIST (" Nch" ), w1 );
859- registry.fill (HIST (" NchUncorrected" ), nch );
860- registry.fill (HIST (" NchVsOneParCorr" ), w1 , oneParCorr, w1);
861- registry.fill (HIST (" NchVsTwoParCorr" ), w1 , twoParCorr, denTwoParCorr);
862- registry.fill (HIST (" NchVsThreeParCorr" ), w1 , threeParCorr, denThreeParCorr);
863- registry.fill (HIST (" NchVsFourParCorr" ), w1 , fourParCorr, denFourParCorr);
902+ registry.fill (HIST (" Nch" ), nchMult );
903+ registry.fill (HIST (" NchUncorrected" ), nchRaw );
904+ registry.fill (HIST (" NchVsOneParCorr" ), nchMult , oneParCorr, w1);
905+ registry.fill (HIST (" NchVsTwoParCorr" ), nchMult , twoParCorr, denTwoParCorr);
906+ registry.fill (HIST (" NchVsThreeParCorr" ), nchMult , threeParCorr, denThreeParCorr);
907+ registry.fill (HIST (" NchVsFourParCorr" ), nchMult , fourParCorr, denFourParCorr);
864908
865909 // --------------------------- Generated MC ---------------------------
866910 std::vector<float > pTsMC;
867- std::vector<float > wIsMC;
911+ std::vector<float > vecFullEff;
912+ std::vector<float > vecFDEqualOne;
913+
868914 // Calculates the event weight, W_k
869915 for (const auto & particle : mcParticles) {
870916 if (particle.eta () < minEta || particle.eta () > maxEta) {
@@ -879,17 +925,19 @@ struct UccZdc {
879925
880926 float pt{particle.pt ()};
881927 pTsMC.emplace_back (pt);
882- wIsMC.emplace_back (1 .);
928+ vecFullEff.emplace_back (1 .);
929+ vecFDEqualOne.emplace_back (1 .);
883930 }
884931
885- const double nchMC{static_cast <double >(pTsMC.size ())};
932+ double nchMC{0 };
933+ nchMult = std::accumulate (vecFullEff.begin (), vecFullEff.end (), 0 );
886934 if (nchMC < minNchSel) {
887935 continue ;
888936 }
889937
890938 double p1MC, p2MC, p3MC, p4MC, w1MC, w2MC, w3MC, w4MC;
891939 p1MC = p2MC = p3MC = p4MC = w1MC = w2MC = w3MC = w4MC = 0.0 ;
892- getPTpowers (pTsMC, wIsMC , p1MC, w1MC, p2MC, w2MC, p3MC, w3MC, p4MC, w4MC);
940+ getPTpowers (pTsMC, vecFullEff, vecFDEqualOne , p1MC, w1MC, p2MC, w2MC, p3MC, w3MC, p4MC, w4MC);
893941
894942 const double denTwoParCorrMC{std::pow (w1MC, 2 .) - w2MC};
895943 const double numTwoParCorrMC{std::pow (p1MC, 2 .) - p2MC};
@@ -911,6 +959,8 @@ struct UccZdc {
911959 } else { // Correction with the remaining half of the sample
912960 registry.fill (HIST (" EvtsDivided" ), 1 );
913961 // ----- MC reconstructed -----//
962+ int nchTrue{0 };
963+ int nchRec{0 };
914964 const auto & groupedTracks{simTracks.sliceBy (perCollision, collision.globalIndex ())};
915965 for (const auto & track : groupedTracks) {
916966 // Track Selection
@@ -932,6 +982,7 @@ struct UccZdc {
932982 continue ;
933983 }
934984
985+ nchRec++;
935986 registry.fill (HIST (" Pt_ch" ), cent, track.pt ());
936987 if (particle.pdgCode () == PDG_t::kPiPlus || particle.pdgCode () == PDG_t::kPiMinus ) {
937988 registry.fill (HIST (" Pt_pi" ), cent, track.pt ());
@@ -960,6 +1011,7 @@ struct UccZdc {
9601011 continue ;
9611012 }
9621013
1014+ nchTrue++;
9631015 registry.fill (HIST (" PtMC_ch" ), cent, particle.pt ());
9641016 if (particle.pdgCode () == PDG_t::kPiPlus || particle.pdgCode () == PDG_t::kPiMinus ) { // pion
9651017 registry.fill (HIST (" PtMC_pi" ), cent, particle.pt ());
@@ -975,18 +1027,23 @@ struct UccZdc {
9751027 registry.fill (HIST (" PtMC_re" ), cent, particle.pt ());
9761028 }
9771029 }
1030+
1031+ registry.fill (HIST (" NchRec" ), nchRec);
1032+ registry.fill (HIST (" NchTrue" ), nchTrue);
9781033 } // Half of statistics for corrections
9791034 } // Collisions
9801035 }
9811036 PROCESS_SWITCH (UccZdc, processMCclosure, " Process MC closure" , false );
9821037
9831038 template <typename T, typename U>
984- void getPTpowers (const T& pTs, const T& wIs , U& pOne, U& wOne, U& pTwo, U& wTwo, U& pThree, U& wThree, U& pFour, U& wFour)
1039+ void getPTpowers (const T& pTs, const T& vecOneOverEff, const T& vecFD , U& pOne, U& wOne, U& pTwo, U& wTwo, U& pThree, U& wThree, U& pFour, U& wFour)
9851040 {
9861041 pOne = wOne = pTwo = wTwo = pThree = wThree = pFour = wFour = 0 .;
9871042 for (std::size_t i = 0 ; i < pTs.size (); ++i) {
9881043 const float pTi{pTs.at (i)};
989- const float wEighti{wIs.at (i)};
1044+ const float eFFi{vecOneOverEff.at (i)};
1045+ const float fDi {vecFD.at (i)};
1046+ const float wEighti{eFFi * fDi };
9901047 pOne += wEighti * pTi;
9911048 wOne += wEighti;
9921049 pTwo += std::pow (wEighti * pTi, 2 .);
0 commit comments