1212// / \file antinucleiInJets.cxx
1313// /
1414// / \brief task for analysis of antinuclei in jets using Fastjet
15- // / \author Alberto Caliva (alberto.caliva@cern.ch), Chiara Pinto (chiara.pinto@cern.ch)
15+ // / \author Alberto Caliva (alberto.caliva@cern.ch), Chiara Pinto (chiara.pinto@cern.ch), Francesca Casillo (francesca.casillo@cern.ch)
1616// / \since February 13, 2025
1717
1818#include " PWGJE/Core/JetBkgSubUtils.h"
@@ -111,14 +111,14 @@ struct AntinucleiInJets {
111111 Configurable<double > ptLeadingMin{" ptLeadingMin" , 5.0 , " pt Leading Min" };
112112 Configurable<double > rJet{" rJet" , 0.3 , " Jet resolution parameter R" };
113113 Configurable<double > zVtx{" zVtx" , 10.0 , " Maximum zVertex" };
114- Configurable<bool > applyAreaCut{" applyAreaCut" , false , " apply area cut" };
115- Configurable<double > maxNormalizedJetArea{" maxNormalizedJetArea" , 0.6 , " area cut" };
114+ Configurable<bool > applyAreaCut{" applyAreaCut" , true , " apply area cut" };
115+ Configurable<double > maxNormalizedJetArea{" maxNormalizedJetArea" , 1.0 , " area cut" };
116116 Configurable<double > deltaEtaEdge{" deltaEtaEdge" , 0.05 , " eta gap from the edge" };
117117 Configurable<int > nSyst{" nSyst" , 50 , " number of systematic variations" };
118118
119119 // Track quality, kinematic, and PID selection parameters
120120 Configurable<bool > requirePvContributor{" requirePvContributor" , false , " require that the track is a PV contributor" };
121- Configurable<bool > applyItsPid{" applyItsPid" , true , " apply ITS PID" };
121+ Configurable<bool > applyItsPid{" applyItsPid" , false , " apply ITS PID" };
122122 Configurable<int > minItsNclusters{" minItsNclusters" , 5 , " minimum number of ITS clusters" };
123123 Configurable<int > minTpcNcrossedRows{" minTpcNcrossedRows" , 100 , " minimum number of TPC crossed pad rows" };
124124 Configurable<double > minChiSquareTpc{" minChiSquareTpc" , 0.0 , " minimum TPC chi^2/Ncls" };
@@ -138,18 +138,21 @@ struct AntinucleiInJets {
138138 Configurable<double > ptMaxItsPidHel{" ptMaxItsPidHel" , 1.0 , " maximum pt for ITS PID for helium" };
139139 Configurable<double > nSigmaItsMin{" nSigmaItsMin" , -3.0 , " nSigmaITS min" };
140140 Configurable<double > nSigmaItsMax{" nSigmaItsMax" , +3.0 , " nSigmaITS max" };
141- Configurable<bool > setMCDefaultItsParams{" setMCDefaultItsParams" , false , " set MC default parameters" };
141+ Configurable<bool > setMCDefaultItsParams{" setMCDefaultItsParams" , true , " set MC default parameters" };
142142 Configurable<bool > cfgCompensatePIDinTracking{" cfgCompensatePIDinTracking" , false , " If true, divide tpcInnerParam by the electric charge" };
143143 Configurable<std::array<double , 5 >> cfgBetheBlochParams{" cfgBetheBlochParams" , {0.6539 , 1.591 , 0.8225 , 2.363 , 0.09 }, " TPC Bethe-Bloch parameterisation for He3" };
144144
145145 // Configuration parameters for CCDB access and reweighting input files
146+ Configurable<bool > applyReweighting{" applyReweighting" , true , " enable reweighting for efficiency" };
146147 Configurable<std::string> urlToCcdb{" urlToCcdb" , " http://alice-ccdb.cern.ch" , " url of the personal ccdb" };
147- Configurable<std::string> pathToFile{" pathToFile" , " Users/a/alcaliva/PrimaryFractionAntip " , " path to file with reweighting " };
148+ Configurable<std::string> pathToFile{" pathToFile" , " Users/a/alcaliva/reweightingHistogramsAntipInJet " , " path to file" };
148149 Configurable<std::string> weightsProton{" weightsProton" , " " , " weightsProton" };
149150 Configurable<std::string> weightsLambda{" weightsLambda" , " " , " weightsLambda" };
150151 Configurable<std::string> weightsSigma{" weightsSigma" , " " , " weightsSigma" };
151152 Configurable<std::string> weightsXi{" weightsXi" , " " , " weightsXi" };
152153 Configurable<std::string> weightsOmega{" weightsOmega" , " " , " weightsOmega" };
154+ Configurable<std::string> weightsJet{" weightsJet" , " " , " weightsJet" };
155+ Configurable<std::string> weightsUe{" weightsUe" , " " , " weightsUe" };
153156
154157 // Number of events
155158 Configurable<int > shrinkInterval{" shrinkInterval" , 1000 , " variable that controls how often shrinking happens" };
@@ -160,6 +163,8 @@ struct AntinucleiInJets {
160163 TH1F* primaryAntiSigma;
161164 TH1F* primaryAntiXi;
162165 TH1F* primaryAntiOmega;
166+ TH1F* antiprotonsInsideJets;
167+ TH1F* antiprotonsPerpCone;
163168
164169 // CCDB manager service for accessing condition data
165170 Service<o2::ccdb::BasicCCDBManager> ccdb;
@@ -205,7 +210,7 @@ struct AntinucleiInJets {
205210 ccdb->setLocalObjectValidityChecking ();
206211 ccdb->setCreatedNotAfter (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ());
207212 ccdb->setFatalWhenNull (false );
208- getReweightingHistograms (ccdb, TString (pathToFile), TString (weightsProton), TString (weightsLambda), TString (weightsSigma), TString (weightsXi), TString (weightsOmega));
213+ getReweightingHistograms (ccdb, TString (pathToFile), TString (weightsProton), TString (weightsLambda), TString (weightsSigma), TString (weightsXi), TString (weightsOmega), TString (weightsJet), TString (weightsUe) );
209214 }
210215
211216 // Binning
@@ -295,6 +300,9 @@ struct AntinucleiInJets {
295300 registryMC.add (" genEvents" , " number of generated events in mc" , HistType::kTH1F , {{10 , 0 , 10 , " counter" }});
296301 registryMC.add (" genJets" , " number of generated jets" , HistType::kTH1F , {{10 , 0 , 10 , " counter" }});
297302
303+ // Size of particle array
304+ registryMC.add (" sizeParticleArray" , " number of particles" , HistType::kTH1F , {{1000 , 0 , 1000 , " #it{N}_{part}" }});
305+
298306 // Generated spectra of antiprotons
299307 registryMC.add (" antiproton_gen_jet" , " antiproton_gen_jet" , HistType::kTH1F , {{nbins, min, max, " #it{p}_{T} (GeV/#it{c})" }});
300308 registryMC.add (" antiproton_gen_ue" , " antiproton_gen_ue" , HistType::kTH1F , {{nbins, min, max, " #it{p}_{T} (GeV/#it{c})" }});
@@ -485,22 +493,30 @@ struct AntinucleiInJets {
485493 }
486494 }
487495
488- void getReweightingHistograms (o2::framework::Service<o2::ccdb::BasicCCDBManager> const & ccdbObj, TString filepath, TString antip, TString antilambda, TString antisigma, TString antixi, TString antiomega)
496+ void getReweightingHistograms (o2::framework::Service<o2::ccdb::BasicCCDBManager> const & ccdbObj, TString filepath, TString antip, TString antilambda, TString antisigma, TString antixi, TString antiomega, TString jet, TString ue )
489497 {
490498 TList* list = ccdbObj->get <TList>(filepath.Data ());
491499 if (!list) {
492500 LOGP (error, " Could not retrieve the list from CCDB" );
493501 return ;
494502 }
495503
504+ // Get reweighting histograms for primary fraction
496505 primaryAntiprotons = static_cast <TH1F*>(list->FindObject (antip));
497506 primaryAntiLambda = static_cast <TH1F*>(list->FindObject (antilambda));
498507 primaryAntiSigma = static_cast <TH1F*>(list->FindObject (antisigma));
499508 primaryAntiXi = static_cast <TH1F*>(list->FindObject (antixi));
500509 primaryAntiOmega = static_cast <TH1F*>(list->FindObject (antiomega));
501510
502511 if (!primaryAntiprotons || !primaryAntiSigma || !primaryAntiLambda || !primaryAntiXi || !primaryAntiOmega) {
503- LOGP (error, " Missing one or more reweighting histograms in CCDB list" );
512+ LOGP (error, " Missing one or more reweighting histograms for primary fraction in CCDB list" );
513+ }
514+
515+ // Get reweighting histograms for efficiency
516+ antiprotonsInsideJets = static_cast <TH1F*>(list->FindObject (jet));
517+ antiprotonsPerpCone = static_cast <TH1F*>(list->FindObject (ue));
518+ if (!antiprotonsInsideJets || !antiprotonsPerpCone) {
519+ LOGP (error, " Missing one or more reweighting histograms for efficiency in CCDB list" );
504520 }
505521
506522 LOGP (info, " Successfully loaded reweighting histograms from CCDB path" );
@@ -533,6 +549,27 @@ struct AntinucleiInJets {
533549 return current;
534550 }
535551
552+ // Check if particle is a physical primary or a decay product of a heavy-flavor hadron
553+ bool isPhysicalPrimaryOrFromHF (aod::McParticle const & particle, aod::McParticles const & mcParticles)
554+ {
555+ // Keep only pi, K, p, e, mu
556+ int pdg = std::abs (particle.pdgCode ());
557+ if (!(pdg == 211 || pdg == 321 || pdg == 2212 || pdg == 11 || pdg == 13 ))
558+ return false ;
559+
560+ // Check if particle is from heavy-flavor decay
561+ bool fromHF = false ;
562+ if (particle.has_mothers ()) {
563+ auto mother = mcParticles.iteratorAt (particle.mothersIds ()[0 ]);
564+ int motherPdg = std::abs (mother.pdgCode ());
565+ fromHF = (motherPdg / 100 == 4 || motherPdg / 100 == 5 || motherPdg / 1000 == 4 || motherPdg / 1000 == 5 );
566+ }
567+
568+ // Select only physical primary particles or from heavy-flavor
569+ return (particle.isPhysicalPrimary () || fromHF);
570+ }
571+
572+ /*
536573 // Compute two unit vectors perpendicular to p
537574 void getPerpendicularAxis(const TVector3& p, TVector3& u, double sign)
538575 {
@@ -584,6 +621,70 @@ struct AntinucleiInJets {
584621 double uy = (-pz2 - px * ux) / py;
585622 u.SetXYZ(ux, uy, pz);
586623 }
624+ */
625+
626+ // Compute two transverse directions orthogonal to vector p
627+ void getPerpendicularDirections (const TVector3& p, TVector3& u1, TVector3& u2)
628+ {
629+ // Get momentum components
630+ double px = p.X ();
631+ double py = p.Y ();
632+ double pz = p.Z ();
633+
634+ // Precompute squared terms
635+ double px2 = px * px;
636+ double py2 = py * py;
637+ double pz2 = pz * pz;
638+ double pz4 = pz2 * pz2;
639+
640+ // Case 1: vector along z-axis -> undefined perpendiculars
641+ if (px == 0 && py == 0 ) {
642+ u1.SetXYZ (0 , 0 , 0 );
643+ u2.SetXYZ (0 , 0 , 0 );
644+ return ;
645+ }
646+
647+ // Case 2: px = 0 -> avoid division by zero
648+ if (px == 0 && py != 0 ) {
649+ double ux = std::sqrt (py2 - pz4 / py2);
650+ double uy = -pz2 / py;
651+ u1.SetXYZ (ux, uy, pz);
652+ u2.SetXYZ (-ux, uy, pz);
653+ return ;
654+ }
655+
656+ // Case 3: py = 0 -> avoid division by zero
657+ if (py == 0 && px != 0 ) {
658+ double ux = -pz2 / px;
659+ double uy = std::sqrt (px2 - pz4 / px2);
660+ u1.SetXYZ (ux, uy, pz);
661+ u2.SetXYZ (ux, -uy, pz);
662+ return ;
663+ }
664+
665+ // General case: solve quadratic for perpendicular vectors
666+ double a = px2 + py2;
667+ double b = 2.0 * px * pz2;
668+ double c = pz4 - py2 * py2 - px2 * py2;
669+ double delta = b * b - 4.0 * a * c;
670+
671+ // Invalid or degenerate solutions
672+ if (delta < 0 || a == 0 ) {
673+ u1.SetXYZ (0 , 0 , 0 );
674+ u2.SetXYZ (0 , 0 , 0 );
675+ return ;
676+ }
677+
678+ // Solution 1
679+ double u1x = (-b + std::sqrt (delta)) / (2.0 * a);
680+ double u1y = (-pz2 - px * u1x) / py;
681+ u1.SetXYZ (u1x, u1y, pz);
682+
683+ // Solution 2
684+ double u2x = (-b - std::sqrt (delta)) / (2.0 * a);
685+ double u2y = (-pz2 - px * u2x) / py;
686+ u2.SetXYZ (u2x, u2y, pz);
687+ }
587688
588689 // Compute delta phi
589690 double getDeltaPhi (double a1, double a2)
@@ -917,10 +1018,11 @@ struct AntinucleiInJets {
9171018 // Perpendicular cones
9181019 double coneRadius = std::sqrt (jet.area () / PI);
9191020 TVector3 jetAxis (jet.px (), jet.py (), jet.pz ());
920- TVector3 ueAxis1 (0 , 0 , 0 );
921- TVector3 ueAxis2 (0 , 0 , 0 );
922- getPerpendicularAxis (jetAxis, ueAxis1, +1 );
923- getPerpendicularAxis (jetAxis, ueAxis2, -1 );
1021+ TVector3 ueAxis1 (0 , 0 , 0 ), ueAxis2 (0 , 0 , 0 );
1022+ getPerpendicularDirections (jetAxis, ueAxis1, ueAxis2);
1023+ if (ueAxis1.Mag () == 0 || ueAxis2.Mag () == 0 ) {
1024+ continue ;
1025+ }
9241026
9251027 // Fill histogram with jet effective area / piR^2
9261028 registryData.fill (HIST (" jetEffectiveAreaOverPiR2" ), jet.area () / (PI * rJet * rJet));
@@ -1274,10 +1376,11 @@ struct AntinucleiInJets {
12741376 std::vector<fastjet::PseudoJet> jetConstituents = jet.constituents ();
12751377 TVector3 jetAxis (jet.px (), jet.py (), jet.pz ());
12761378 double coneRadius = std::sqrt (jet.area () / PI);
1277- TVector3 ueAxis1 (0 , 0 , 0 );
1278- TVector3 ueAxis2 (0 , 0 , 0 );
1279- getPerpendicularAxis (jetAxis, ueAxis1, +1 );
1280- getPerpendicularAxis (jetAxis, ueAxis2, -1 );
1379+ TVector3 ueAxis1 (0 , 0 , 0 ), ueAxis2 (0 , 0 , 0 );
1380+ getPerpendicularDirections (jetAxis, ueAxis1, ueAxis2);
1381+ if (ueAxis1.Mag () == 0 || ueAxis2.Mag () == 0 ) {
1382+ continue ;
1383+ }
12811384
12821385 registryQC.fill (HIST (" NchJetCone" ), static_cast <int >(jetConstituents.size ()));
12831386
@@ -1656,9 +1759,11 @@ struct AntinucleiInJets {
16561759 // Loop over MC particles
16571760 for (const auto & particle : mcParticles) {
16581761
1659- // Select physical primaries within acceptance
1660- if (!particle. isPhysicalPrimary ( ))
1762+ // Select physical primary particles or HF decay products
1763+ if (!isPhysicalPrimaryOrFromHF (particle,mcParticles ))
16611764 continue ;
1765+
1766+ // Select particles within acceptance
16621767 static constexpr double MinPtParticle = 0.1 ;
16631768 if (particle.eta () < minEta || particle.eta () > maxEta || particle.pt () < MinPtParticle)
16641769 continue ;
@@ -1681,6 +1786,9 @@ struct AntinucleiInJets {
16811786 continue ;
16821787 registryMC.fill (HIST (" genEvents" ), 2.5 );
16831788
1789+ // Size of particle array
1790+ registryMC.fill (HIST (" sizeParticleArray" ), fjParticles.size ());
1791+
16841792 // Cluster MC particles into jets using anti-kt algorithm
16851793 fastjet::ClusterSequenceArea cs (fjParticles, jetDef, areaDef);
16861794 std::vector<fastjet::PseudoJet> jets = fastjet::sorted_by_pt (cs.inclusive_jets ());
@@ -1721,19 +1829,28 @@ struct AntinucleiInJets {
17211829 // Fill normalization histogram
17221830 registryMC.fill (HIST (" antiproton_deltay_deltaphi_jet" ), particle.eta () - jet.eta (), getDeltaPhi (particle.phi (), jet.phi ()));
17231831
1832+ // Calculate weight
1833+ double weightJet (1.0 );
1834+ if (applyReweighting && particle.pt () < antiprotonsInsideJets->GetXaxis ()->GetXmax ()) {
1835+ int ipt = antiprotonsInsideJets->FindBin (particle.pt ());
1836+ weightJet = antiprotonsInsideJets->GetBinContent (ipt);
1837+ }
1838+
17241839 // Fill histogram for generated antiprotons
1725- registryMC.fill (HIST (" antiproton_gen_jet" ), particle.pt ());
1840+ registryMC.fill (HIST (" antiproton_gen_jet" ), particle.pt (), weightJet );
17261841
17271842 // Fill 2d (pt,eta) distribution of antiprotons
1728- registryMC.fill (HIST (" antiproton_eta_pt_jet" ), particle.pt (), particle.eta ());
1843+ registryMC.fill (HIST (" antiproton_eta_pt_jet" ), particle.pt (), particle.eta (), weightJet );
17291844 }
17301845
17311846 // Set up two perpendicular cone axes for underlying event estimation
17321847 TVector3 jetAxis (jet.px (), jet.py (), jet.pz ());
17331848 double coneRadius = std::sqrt (jet.area () / PI);
17341849 TVector3 ueAxis1 (0 , 0 , 0 ), ueAxis2 (0 , 0 , 0 );
1735- getPerpendicularAxis (jetAxis, ueAxis1, +1 );
1736- getPerpendicularAxis (jetAxis, ueAxis2, -1 );
1850+ getPerpendicularDirections (jetAxis, ueAxis1, ueAxis2);
1851+ if (ueAxis1.Mag () == 0 || ueAxis2.Mag () == 0 ) {
1852+ continue ;
1853+ }
17371854
17381855 // Loop over MC particles to analyze underlying event region
17391856 for (const auto & protonVec : protonMomentum) {
@@ -1757,18 +1874,21 @@ struct AntinucleiInJets {
17571874 continue ;
17581875
17591876 // Fill normalization histogram
1760- if (deltaRUe1 < maxConeRadius) {
1761- registryMC.fill (HIST (" antiproton_deltay_deltaphi_ue" ), protonVec.Eta () - ueAxis1.Eta (), getDeltaPhi (protonVec.Phi (), ueAxis1.Phi ()));
1762- }
1763- if (deltaRUe2 < maxConeRadius) {
1764- registryMC.fill (HIST (" antiproton_deltay_deltaphi_ue" ), protonVec.Eta () - ueAxis2.Eta (), getDeltaPhi (protonVec.Phi (), ueAxis2.Phi ()));
1877+ registryMC.fill (HIST (" antiproton_deltay_deltaphi_ue" ), protonVec.Eta () - ueAxis1.Eta (), getDeltaPhi (protonVec.Phi (), ueAxis1.Phi ()));
1878+ registryMC.fill (HIST (" antiproton_deltay_deltaphi_ue" ), protonVec.Eta () - ueAxis2.Eta (), getDeltaPhi (protonVec.Phi (), ueAxis2.Phi ()));
1879+
1880+ // Calculate weight
1881+ double weightUe (1.0 );
1882+ if (applyReweighting && protonVec.Pt () < antiprotonsPerpCone->GetXaxis ()->GetXmax ()) {
1883+ int ipt = antiprotonsPerpCone->FindBin (protonVec.Pt ());
1884+ weightUe = antiprotonsPerpCone->GetBinContent (ipt);
17651885 }
17661886
17671887 // Fill histogram for antiprotons in the UE
1768- registryMC.fill (HIST (" antiproton_gen_ue" ), protonVec.Pt ());
1888+ registryMC.fill (HIST (" antiproton_gen_ue" ), protonVec.Pt (), weightUe );
17691889
17701890 // Fill 2d (pt,eta) distribution of antiprotons
1771- registryMC.fill (HIST (" antiproton_eta_pt_ue" ), protonVec.Pt (), protonVec.Eta ());
1891+ registryMC.fill (HIST (" antiproton_eta_pt_ue" ), protonVec.Pt (), protonVec.Eta (), weightUe );
17721892 }
17731893 }
17741894 if (isAtLeastOneJetSelected) {
@@ -1910,8 +2030,10 @@ struct AntinucleiInJets {
19102030 double coneRadius = std::sqrt (jet.area () / PI);
19112031 TVector3 jetAxis (jet.px (), jet.py (), jet.pz ());
19122032 TVector3 ueAxis1 (0 , 0 , 0 ), ueAxis2 (0 , 0 , 0 );
1913- getPerpendicularAxis (jetAxis, ueAxis1, +1 );
1914- getPerpendicularAxis (jetAxis, ueAxis2, -1 );
2033+ getPerpendicularDirections (jetAxis, ueAxis1, ueAxis2);
2034+ if (ueAxis1.Mag () == 0 || ueAxis2.Mag () == 0 ) {
2035+ continue ;
2036+ }
19152037
19162038 // Get jet constituents
19172039 std::vector<fastjet::PseudoJet> jetConstituents = jet.constituents ();
@@ -1981,11 +2103,18 @@ struct AntinucleiInJets {
19812103 // Fill antiproton spectrum for physical primaries
19822104 registryMC.fill (HIST (" antiproton_prim_jet" ), pt);
19832105
2106+ // Calculate weight
2107+ double weightJet (1.0 );
2108+ if (applyReweighting && mcparticle.pt () < antiprotonsInsideJets->GetXaxis ()->GetXmax ()) {
2109+ int ipt = antiprotonsInsideJets->FindBin (mcparticle.pt ());
2110+ weightJet = antiprotonsInsideJets->GetBinContent (ipt);
2111+ }
2112+
19842113 // Fill histograms (TPC and TOF) only for selected candidates
19852114 if (passedItsPidProt && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) {
1986- registryMC.fill (HIST (" antiproton_rec_tpc_jet" ), pt);
2115+ registryMC.fill (HIST (" antiproton_rec_tpc_jet" ), pt, weightJet );
19872116 if (track.hasTOF () && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) {
1988- registryMC.fill (HIST (" antiproton_rec_tof_jet" ), pt);
2117+ registryMC.fill (HIST (" antiproton_rec_tof_jet" ), pt, weightJet );
19892118 }
19902119 }
19912120 }
@@ -2056,11 +2185,18 @@ struct AntinucleiInJets {
20562185 // Fill antiproton spectrum for physical primaries
20572186 registryMC.fill (HIST (" antiproton_prim_ue" ), pt);
20582187
2188+ // Calculate weight
2189+ double weightUe (1.0 );
2190+ if (applyReweighting && mcparticle.pt () < antiprotonsPerpCone->GetXaxis ()->GetXmax ()) {
2191+ int ipt = antiprotonsPerpCone->FindBin (mcparticle.pt ());
2192+ weightUe = antiprotonsPerpCone->GetBinContent (ipt);
2193+ }
2194+
20592195 // Fill histograms (TPC and TOF) only for selected candidates
20602196 if (passedItsPidProt && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) {
2061- registryMC.fill (HIST (" antiproton_rec_tpc_ue" ), pt);
2197+ registryMC.fill (HIST (" antiproton_rec_tpc_ue" ), pt, weightUe );
20622198 if (track.hasTOF () && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) {
2063- registryMC.fill (HIST (" antiproton_rec_tof_ue" ), pt);
2199+ registryMC.fill (HIST (" antiproton_rec_tof_ue" ), pt, weightUe );
20642200 }
20652201 }
20662202 }
@@ -2624,10 +2760,11 @@ struct AntinucleiInJets {
26242760 // Perpendicular cones
26252761 double coneRadius = std::sqrt (jet.area () / PI);
26262762 TVector3 jetAxis (jet.px (), jet.py (), jet.pz ());
2627- TVector3 ueAxis1 (0 , 0 , 0 );
2628- TVector3 ueAxis2 (0 , 0 , 0 );
2629- getPerpendicularAxis (jetAxis, ueAxis1, +1 );
2630- getPerpendicularAxis (jetAxis, ueAxis2, -1 );
2763+ TVector3 ueAxis1 (0 , 0 , 0 ), ueAxis2 (0 , 0 , 0 );
2764+ getPerpendicularDirections (jetAxis, ueAxis1, ueAxis2);
2765+ if (ueAxis1.Mag () == 0 || ueAxis2.Mag () == 0 ) {
2766+ continue ;
2767+ }
26312768
26322769 // Get jet constituents
26332770 std::vector<fastjet::PseudoJet> jetConstituents = jet.constituents ();
0 commit comments