3030#include " Framework/ASoA.h"
3131#include " Framework/AnalysisDataModel.h"
3232#include " Framework/HistogramRegistry.h"
33- #include < CommonConstants/MathConstants.h>
3433#include < Framework/AnalysisTask.h>
3534#include < Framework/ConfigContext.h>
3635#include < Framework/Configurable.h>
4241#include " TVector3.h"
4342
4443#include < cmath>
45- #include < cstdlib>
4644#include < string>
4745#include < vector>
4846
@@ -67,6 +65,12 @@ DECLARE_SOA_COLUMN(HfY, hfY, float);
6765DECLARE_SOA_COLUMN (HfMlScore0, hfMlScore0, float );
6866DECLARE_SOA_COLUMN (HfMlScore1, hfMlScore1, float );
6967DECLARE_SOA_COLUMN (HfMlScore2, hfMlScore2, float );
68+
69+ // extra
70+ DECLARE_SOA_COLUMN (JetMass, jetMass, float );
71+ DECLARE_SOA_COLUMN (JetGirth, jetGirth, float );
72+ DECLARE_SOA_COLUMN (JetThrust, jetThrust, float ); // lambda_2^1
73+ DECLARE_SOA_COLUMN (JetLambda11, jetLambda11, float ); // lambda_1^1
7074} // namespace jet_distance
7175
7276DECLARE_SOA_TABLE (JetDistanceTable, " AOD" , " JETDISTTABLE" ,
@@ -82,59 +86,130 @@ DECLARE_SOA_TABLE(JetDistanceTable, "AOD", "JETDISTTABLE",
8286 jet_distance::HfY,
8387 jet_distance::HfMlScore0,
8488 jet_distance::HfMlScore1,
85- jet_distance::HfMlScore2);
89+ jet_distance::HfMlScore2,
90+ jet_distance::JetMass,
91+ jet_distance::JetGirth,
92+ jet_distance::JetThrust,
93+ jet_distance::JetLambda11);
8694} // namespace o2::aod
8795
8896struct JetDsSpecSubs {
89- HistogramRegistry registry{" registry" ,
90- {{" h_collisions" , " event status;event status;entries" , {HistType::kTH1F , {{4 , 0.0 , 4.0 }}}},
91- {" h_track_pt" , " track pT;#it{p}_{T,track} (GeV/#it{c});entries" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
92- {" h_track_eta" , " track #eta;#eta_{track};entries" , {HistType::kTH1F , {{100 , -1.0 , 1.0 }}}},
93- {" h_track_phi" , " track #varphi;#varphi_{track};entries" , {HistType::kTH1F , {{80 , -1.0 , 7 .}}}},
94- {" h_jet_pt" , " jet pT;#it{p}_{T,jet} (GeV/#it{c});entries" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
95- {" h_jet_eta" , " jet #eta;#eta_{jet};entries" , {HistType::kTH1F , {{100 , -1.0 , 1.0 }}}},
96- {" h_jet_phi" , " jet #phi;#phi_{jet};entries" , {HistType::kTH1F , {{80 , -1.0 , 7 .}}}},
97- {" h_collision_counter" , " # of collisions;" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
98- {" h_jet_counter" , " ;# of D_{S} jets;" , {HistType::kTH1F , {{6 , 0 ., 3.0 }}}},
99- {" h_ds_jet_projection" , " ;z^{D_{S},jet}_{||};dN/dz^{D_{S},jet}_{||}" , {HistType::kTH1F , {{1000 , 0 ., 2 .}}}},
100- {" h_ds_jet_distance_vs_projection" , " ;#DeltaR_{D_{S},jet};z^{D_{S},jet}_{||}" , {HistType::kTH2F , {{1000 , 0 ., 1 .}, {1000 , 0 ., 2 .}}}},
101- {" h_ds_jet_distance" , " ;#DeltaR_{D_{S},jet};dN/d(#DeltaR)" , {HistType::kTH1F , {{1000 , 0 ., 1 .}}}},
102- {" h_ds_jet_pt" , " ;p_{T,D_{S} jet};dN/dp_{T,D_{S} jet}" , {HistType::kTH1F , {{1000 , 0 ., 100 .}}}},
103- {" h_ds_jet_eta" , " ;#eta_{T,D_{S} jet};dN/d#eta_{D_{S} jet}" , {HistType::kTH1F , {{250 , -1 ., 1 .}}}},
104- {" h_ds_jet_phi" , " ;#phi_{T,D_{S} jet};dN/d#phi_{D_{S} jet}" , {HistType::kTH1F , {{250 , -1 ., 7 .}}}},
105- {" h_ds_mass" , " ;m_{D_{S}} (GeV/c^{2});dN/dm_{D_{S}}" , {HistType::kTH1F , {{1000 , 0 ., 6 .}}}},
106- {" h_ds_eta" , " ;#eta_{D_{S}} (GeV/c^{2});dN/d#eta_{D_{S}}" , {HistType::kTH1F , {{250 , -1 ., 1 .}}}},
107- {" h_ds_phi" , " ;#phi_{D_{S}} (GeV/c^{2});dN/d#phi_{D_{S}}" , {HistType::kTH1F , {{250 , -1 ., 7 .}}}}}};
108- Configurable<float > vertexZCut{" vertexZCut" , 10 .0f , " Accepted z-vertex range" };
97+ HistogramRegistry registry{
98+ " registry" ,
99+ {
100+ {" h_collisions" , " event status;event status;entries" , {HistType::kTH1F , {{4 , 0.0 , 4.0 }}}},
101+ {" h_track_pt" , " track pT;#it{p}_{T,track} (GeV/#it{c});entries" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
102+ {" h_track_eta" , " track #eta;#eta_{track};entries" , {HistType::kTH1F , {{100 , -1.0 , 1.0 }}}},
103+ {" h_track_phi" , " track #varphi;#varphi_{track};entries" , {HistType::kTH1F , {{80 , -1.0 , 7 .}}}},
104+ {" h_jet_pt" , " jet pT;#it{p}_{T,jet} (GeV/#it{c});entries" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
105+ {" h_jet_eta" , " jet #eta;#eta_{jet};entries" , {HistType::kTH1F , {{100 , -1.0 , 1.0 }}}},
106+ {" h_jet_phi" , " jet #phi;#phi_{jet};entries" , {HistType::kTH1F , {{80 , -1.0 , 7 .}}}},
107+ {" h_collision_counter" , " # of collisions;" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
108+ {" h_jet_counter" , " ;# of D_{S} jets;" , {HistType::kTH1F , {{6 , 0 ., 3.0 }}}},
109+ {" h_ds_jet_projection" , " ;z^{D_{S},jet}_{||};dN/dz^{D_{S},jet}_{||}" , {HistType::kTH1F , {{1000 , 0 ., 2 .}}}},
110+ {" h_ds_jet_distance_vs_projection" , " ;#DeltaR_{D_{S},jet};z^{D_{S},jet}_{||}" , {HistType::kTH2F , {{1000 , 0 ., 1 .}, {1000 , 0 ., 2 .}}}},
111+ {" h_ds_jet_distance" , " ;#DeltaR_{D_{S},jet};dN/d(#DeltaR)" , {HistType::kTH1F , {{1000 , 0 ., 1 .}}}},
112+ {" h_ds_jet_pt" , " ;p_{T,D_{S} jet};dN/dp_{T,D_{S} jet}" , {HistType::kTH1F , {{1000 , 0 ., 100 .}}}},
113+ {" h_ds_jet_eta" , " ;#eta_{D_{S} jet};entries" , {HistType::kTH1F , {{250 , -1 ., 1 .}}}},
114+ {" h_ds_jet_phi" , " ;#phi_{D_{S} jet};entries" , {HistType::kTH1F , {{250 , -1 ., 7 .}}}},
115+ {" h_ds_mass" , " ;m_{D_{S}} (GeV/c^{2});entries" , {HistType::kTH1F , {{1000 , 0 ., 6 .}}}},
116+ {" h_ds_eta" , " ;#eta_{D_{S}};entries" , {HistType::kTH1F , {{250 , -1 ., 1 .}}}},
117+ {" h_ds_phi" , " ;#phi_{D_{S}};entries" , {HistType::kTH1F , {{250 , -1 ., 7 .}}}},
118+ {" h_ds_jet_mass" , " ;m_{jet}^{ch} (GeV/#it{c}^{2});entries" , {HistType::kTH1F , {{200 , 0 ., 50 .}}}},
119+ {" h_ds_jet_lambda11" , " ;#lambda_{1}^{1};entries" , {HistType::kTH1F , {{200 , 0 ., 1.0 }}}},
120+ {" h_ds_jet_lambda12" , " ;#lambda_{2}^{1} (thrust);entries" , {HistType::kTH1F , {{200 , 0 ., 1.0 }}}},
121+ {" h_ds_jet_girth" , " ;g (#equiv #lambda_{1}^{1}R);entries" , {HistType::kTH1F , {{200 , 0 ., 0.5 }}}},
122+ {" h2_dsjet_pt_lambda11" , " ;#it{p}_{T,jet} (GeV/#it{c});#lambda_{1}^{1}" , {HistType::kTH2F , {{100 , 0 ., 100 .}, {200 , 0 ., 1.0 }}}},
123+ {" h2_dsjet_pt_lambda12" , " ;#it{p}_{T,jet} (GeV/#it{c});#lambda_{2}^{1}" , {HistType::kTH2F , {{100 , 0 ., 100 .}, {200 , 0 ., 1.0 }}}},
124+ {" h2_dsjet_pt_mass" , " ;#it{p}_{T,jet} (GeV/#it{c});m_{jet}^{ch} (GeV/#it{c}^{2})" , {HistType::kTH2F , {{100 , 0 ., 100 .}, {200 , 0 ., 50.0 }}}},
125+ {" h2_dsjet_pt_girth" , " ;#it{p}_{T,jet} (GeV/#it{c});g" , {HistType::kTH2F , {{100 , 0 ., 100 .}, {200 , 0 ., 0.5 }}}},
126+ {" h_ds_jet_lambda_extra" , " ;#lambda_{#alpha}^{#kappa};entries" , {HistType::kTH1F , {{200 , 0 ., 1.0 }}}},
127+ {" h2_dsjet_pt_lambda_extra" , " ;#it{p}_{T,jet} (GeV/#it{c});#lambda_{#alpha}^{#kappa}" , {HistType::kTH2F , {{100 , 0 ., 100 .}, {200 , 0 ., 1.0 }}}},
128+ }};
109129
130+ Configurable<float > vertexZCut{" vertexZCut" , 10 .0f , " Accepted z-vertex range" };
110131 Configurable<float > jetPtMin{" jetPtMin" , 5.0 , " minimum jet pT cut" };
111132 Configurable<float > jetR{" jetR" , 0.4 , " jet resolution parameter" };
112133
113134 Configurable<std::string> eventSelections{" eventSelections" , " sel8" , " choose event selection" };
114135 Configurable<std::string> trackSelections{" trackSelections" , " globalTracks" , " set track selections" };
115136
137+ // extra angularity knob
138+ Configurable<float > kappa{" kappa" , 1 .0f , " angularity kappa" };
139+ Configurable<float > alpha{" alpha" , 1 .0f , " angularity alpha" };
140+
141+ bool doExtraAngularity = false ;
142+
116143 std::vector<int > eventSelectionBits;
117144 int trackSelection = -1 ;
118145
119146 Produces<aod::JetDistanceTable> distJetTable;
120147
148+ template <typename JET, typename TRACKS>
149+ float computeLambda (JET const & jet, TRACKS const & tracks, float a, float k)
150+ {
151+ if (jet.pt () <= 0 .f ) {
152+ return -1 .f ;
153+ }
154+ float sum = 0 .f ;
155+ for (auto const & trk : tracks) {
156+ const float dr = jetutilities::deltaR (jet, trk);
157+ sum += std::pow (trk.pt (), k) * std::pow (dr, a);
158+ }
159+ const float R = jet.r () / 100 .f ;
160+ const float denom = std::pow (jet.pt (), k) * std::pow (R, a);
161+ if (denom <= 0 .f ) {
162+ return -1 .f ;
163+ }
164+ return sum / denom;
165+ }
166+
167+ template <typename TRACKS>
168+ float computeJetMassFromTracksMass (TRACKS const & tracks)
169+ {
170+ double sumPx = 0.0 , sumPy = 0.0 , sumPz = 0.0 , sumE = 0.0 ;
171+
172+ for (auto const & trk : tracks) {
173+ const double pt = trk.pt ();
174+ const double phi = trk.phi ();
175+ const double eta = trk.eta ();
176+
177+ const double px = pt * std::cos (phi);
178+ const double py = pt * std::sin (phi);
179+ const double pz = pt * std::sinh (eta);
180+ const double p = std::sqrt (px * px + py * py + pz * pz);
181+
182+ sumPx += px;
183+ sumPy += py;
184+ sumPz += pz;
185+ sumE += p; // massless
186+ }
187+
188+ const double m2 = sumE * sumE - (sumPx * sumPx + sumPy * sumPy + sumPz * sumPz);
189+ return (m2 > 0.0 ) ? static_cast <float >(std::sqrt (m2)) : 0 .f ;
190+ }
191+
121192 void init (o2::framework::InitContext&)
122193 {
123194 eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits (static_cast <std::string>(eventSelections));
124195 trackSelection = jetderiveddatautilities::initialiseTrackSelection (static_cast <std::string>(trackSelections));
196+
197+ const bool is11 = (std::abs (kappa.value - 1 .f ) < 1e-6f ) && (std::abs (alpha.value - 1 .f ) < 1e-6f );
198+ const bool is12 = (std::abs (kappa.value - 1 .f ) < 1e-6f ) && (std::abs (alpha.value - 2 .f ) < 1e-6f );
199+ doExtraAngularity = !(is11 || is12);
125200 }
126201
127202 Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100 .0f );
128203 Filter collisionFilter = nabs(aod::jcollision::posZ) < vertexZCut;
129204
130205 void processCollisions (aod::JetCollision const & collision, aod::JetTracks const & tracks)
131206 {
132-
133207 registry.fill (HIST (" h_collisions" ), 0.5 );
134208 if (!jetderiveddatautilities::selectCollision (collision, eventSelectionBits)) {
135209 return ;
136210 }
137211 registry.fill (HIST (" h_collisions" ), 1.5 );
212+
138213 for (auto const & track : tracks) {
139214 if (!jetderiveddatautilities::selectTrack (track, trackSelection)) {
140215 continue ;
@@ -146,12 +221,12 @@ struct JetDsSpecSubs {
146221 }
147222 PROCESS_SWITCH (JetDsSpecSubs, processCollisions, " process JE collisions" , false );
148223
149- void processDataCharged (soa::Filtered<aod::JetCollisions>::iterator const & collision, soa::Filtered<aod::ChargedJets> const & jets)
224+ void processDataCharged (soa::Filtered<aod::JetCollisions>::iterator const & collision,
225+ soa::Filtered<aod::ChargedJets> const & jets)
150226 {
151227 if (!jetderiveddatautilities::selectCollision (collision, eventSelectionBits)) {
152228 return ;
153229 }
154- // jets -> charged jet
155230 for (auto & jet : jets) {
156231 registry.fill (HIST (" h_jet_pt" ), jet.pt ());
157232 registry.fill (HIST (" h_jet_eta" ), jet.eta ());
@@ -165,31 +240,24 @@ struct JetDsSpecSubs {
165240 aod::CandidatesDsData const &,
166241 aod::JetTracks const &)
167242 {
168- // apply event selection and fill histograms for sanity check
169243 registry.fill (HIST (" h_collision_counter" ), 2.0 );
170- if (!jetderiveddatautilities::selectCollision (collision, eventSelectionBits) || !(std::abs (collision.posZ ()) < vertexZCut)) {
244+ if (!jetderiveddatautilities::selectCollision (collision, eventSelectionBits) ||
245+ !(std::abs (collision.posZ ()) < vertexZCut)) {
171246 return ;
172247 }
173248 registry.fill (HIST (" h_collision_counter" ), 3.0 );
174- // jets -> charged jet with Ds
249+
175250 for (const auto & jet : jets) {
176- // number of charged jets with Ds
177251 registry.fill (HIST (" h_jet_counter" ), 0.5 );
178- // obtaining jet 3-vector
252+
179253 TVector3 jetVector (jet.px (), jet.py (), jet.pz ());
180254
181255 for (const auto & dsCandidate : jet.candidates_as <aod::CandidatesDsData>()) {
182-
183- // obtaining jet 3-vector
184256 TVector3 dsVector (dsCandidate.px (), dsCandidate.py (), dsCandidate.pz ());
185257
186- // calculating fraction of the jet momentum carried by the Ds along the direction of the jet axis
187- double zParallel = (jetVector * dsVector) / (jetVector * jetVector);
188-
189- // calculating angular distance in eta-phi plane
190- double axisDistance = jetutilities::deltaR (jet, dsCandidate);
258+ const double zParallel = (jetVector * dsVector) / (jetVector * jetVector);
259+ const double axisDistance = jetutilities::deltaR (jet, dsCandidate);
191260
192- // filling histograms
193261 registry.fill (HIST (" h_ds_jet_projection" ), zParallel);
194262 registry.fill (HIST (" h_ds_jet_distance_vs_projection" ), axisDistance, zParallel);
195263 registry.fill (HIST (" h_ds_jet_distance" ), axisDistance);
@@ -200,25 +268,56 @@ struct JetDsSpecSubs {
200268 registry.fill (HIST (" h_ds_eta" ), dsCandidate.eta ());
201269 registry.fill (HIST (" h_ds_phi" ), dsCandidate.phi ());
202270
203- // Retrieve ML scores safely
204- auto scores = dsCandidate.mlScores ();
271+ auto jetTracks = jet.tracks_as <aod::JetTracks>();
272+
273+ const float lambda11 = computeLambda (jet, jetTracks, 1 .f , 1 .f );
274+ const float lambda12 = computeLambda (jet, jetTracks, 2 .f , 1 .f ); // thrust = λ_2^1
275+ const float mjet = computeJetMassFromTracksMass (jetTracks);
205276
206- float s0 = (scores.size () > 0 ) ? scores[0 ] : -999 .f ;
207- float s1 = (scores.size () > 1 ) ? scores[1 ] : -999 .f ;
208- float s2 = (scores.size () > 2 ) ? scores[2 ] : -999 .f ;
277+ const float R = jet.r () / 100 .f ;
278+ const float girth = (lambda11 >= 0 .f ) ? (lambda11 * R) : -1 .f ;
209279
210- distJetTable (axisDistance,
280+ if (lambda11 >= 0 .f ) {
281+ registry.fill (HIST (" h_ds_jet_lambda11" ), lambda11);
282+ registry.fill (HIST (" h2_dsjet_pt_lambda11" ), jet.pt (), lambda11);
283+ }
284+ if (lambda12 >= 0 .f ) {
285+ registry.fill (HIST (" h_ds_jet_lambda12" ), lambda12);
286+ registry.fill (HIST (" h2_dsjet_pt_lambda12" ), jet.pt (), lambda12);
287+ }
288+ registry.fill (HIST (" h_ds_jet_mass" ), mjet);
289+ registry.fill (HIST (" h2_dsjet_pt_mass" ), jet.pt (), mjet);
290+
291+ if (girth >= 0 .f ) {
292+ registry.fill (HIST (" h_ds_jet_girth" ), girth);
293+ registry.fill (HIST (" h2_dsjet_pt_girth" ), jet.pt (), girth);
294+ }
295+
296+ if (doExtraAngularity) {
297+ const float lambdaExtra = computeLambda (jet, jetTracks, alpha.value , kappa.value );
298+ if (lambdaExtra >= 0 .f ) {
299+ registry.fill (HIST (" h_ds_jet_lambda_extra" ), lambdaExtra);
300+ registry.fill (HIST (" h2_dsjet_pt_lambda_extra" ), jet.pt (), lambdaExtra);
301+ }
302+ }
303+
304+ auto scores = dsCandidate.mlScores ();
305+ const float s0 = (scores.size () > 0 ) ? scores[0 ] : -999 .f ;
306+ const float s1 = (scores.size () > 1 ) ? scores[1 ] : -999 .f ;
307+ const float s2 = (scores.size () > 2 ) ? scores[2 ] : -999 .f ;
308+
309+ distJetTable (static_cast <float >(axisDistance),
211310 jet.pt (), jet.eta (), jet.phi (),
212- static_cast <int >(jet. tracks_as <aod::JetTracks>() .size ()),
311+ static_cast <int >(jetTracks .size ()),
213312 dsCandidate.pt (), dsCandidate.eta (), dsCandidate.phi (),
214313 dsCandidate.m (), dsCandidate.y (),
215- s0, s1, s2);
216- break ; // get out of candidates' loop after first HF particle is found in jet
217- } // end of DS candidates loop
314+ s0, s1, s2,
315+ mjet, girth, lambda12, lambda11);
218316
219- } // end of jets loop
220-
221- } // end of process function
317+ break ; // only first Ds per jet
318+ }
319+ }
320+ }
222321 PROCESS_SWITCH (JetDsSpecSubs, processDataChargedSubstructure, " charged HF jet substructure" , false );
223322};
224323
0 commit comments