Skip to content

Commit d310cbd

Browse files
Change generic method name to jet_reconstruct
There is no need to have the prefix `generic` Update the README to show how to ruin reconstruction using the "Best" strategy (should be the default way) Add also a note on sorting (which is super trivial in Julia, so no need to support specific methods for `Vector{PseudoJet}` as fastjet does)
1 parent 8526406 commit d310cbd

File tree

6 files changed

+75
-42
lines changed

6 files changed

+75
-42
lines changed

README.md

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,66 @@ Algorithms used are based on the C++ FastJet package (<https://fastjet.fr>,
1010
[hep-ph/0512210](https://arxiv.org/abs/hep-ph/0512210),
1111
[arXiv:1111.6097](https://arxiv.org/abs/1111.6097)), reimplemented natively in Julia.
1212

13-
One algorithm is the plain N2 approach `N2Plain`, the other uses the FastJet tiling
14-
approach, `N2Tiled`.
13+
The algorithms include anti-${k}_\text{T}$, Cambridge/Achen and inclusive $k_\text{T}$.
1514

1615
### Interface
1716

18-
To use the package one should call the appropriate API interface of the desired algorithm
17+
The simplest interface is to call:
1918

2019
```julia
21-
# N2Plain
22-
plain_jet_reconstruct(particles::Vector{T}; p = -1, R = 1.0, recombine = +, ptmin = 0.0)
23-
```
24-
25-
```julia
26-
# N2Tiled
27-
tiled_jet_reconstruct(particles::Vector{T}; p = -1, R = 1.0, recombine = +, ptmin = 0.0)
20+
cs = jet_reconstruct(particles::Vector{T}; p = -1, R = 1.0, recombine = +, strategy = JetRecoStrategy.Best)
2821
```
2922

3023
- `particles` - a vector of input particles for the clustering
3124
- Any type that supplies the methods `pt2()`, `phi()`, `rapidity()`, `px()`, `py()`, `pz()`, `energy()` can be used
3225
- These methods have to be defined in the namespace of this package, i.e., `JetReconstruction.pt2(::T)`
3326
- The `PseudoJet` type from this package, or a 4-vector from `LorentzVectorHEP` are suitable (and have the appropriate definitions)
3427
- `p` - the transverse momentum power used in the $d_{ij}$ metric for deciding on closest jets, as $k^{2p}_\text{T}$
35-
- `-1` gives anti-${k}_\text{T}$ clustering
28+
- `-1` gives anti-${k}_\text{T}$ clustering (default)
3629
- `0` gives Cambridge/Achen
3730
- `1` gives inclusive $k_\text{T}$
38-
- `R` - the cone size parameter (no particles more geometrically distance than `R` will be merged)
39-
- `recombine` - the function used to merge two pseudojets (by default this is simple 4-vector addition of $(E, \mathbf{p})$)
40-
- `ptmin` - only jets of transverse momentum greater than or equal to `ptmin` will be returned
31+
- `R` - the cone size parameter; no particles more geometrically distance than `R` will be merged (default 1.0)
32+
- `recombine` - the function used to merge two pseudojets (default is a simple 4-vector addition of $(E, \mathbf{p})$)
33+
- `strategy` - the algorithm strategy to adopt, as described below (default `JetRecoStrategy.Best`)
34+
35+
The object returned is a `ClusterSequence`, which internally tracks all merge steps.
36+
37+
To obtain the final inclusive jets, use the `inclusive_jets` method:
38+
39+
```julia
40+
final_jets = inclusive_jets(cs::ClusterSequence; ptmin=0.0)
41+
```
42+
43+
Only jets passing the cut $p_T > p_{Tmin}$ will be returned. The result is returned as a `Vector{LorentzVectorHEP}`.
44+
45+
#### Sorting
46+
47+
As sorting vectors is trivial in Julia, no special sorting methods are provided. As an example, to sort exclusive jets of $>5.0$ (usually GeV, depending on your EDM) from highest energy to lowest:
4148

42-
Both of these functions return tuple of `(jets, seq)`, where these are a vector of `JetReconstruction.PseudoJet` objects and cluster sequencing information, respectively.
49+
```julia
50+
sorted_jets = sort!(inclusive_jets(cs::ClusterSequence; ptmin=5.0), by=JetReconstruction.energy, rev=true)
51+
```
52+
53+
#### Strategy
54+
55+
Three strategies are available for the different algorithms:
56+
57+
| Strategy Name | Notes | Interface |
58+
|---|---|---|
59+
| `JetRecoStrategy.Best` | Dynamically switch strategy based on input particle density | `jet_reconstruct` |
60+
| `JetRecoStrategy.N2Plain` | Global matching of particles at each interation (works well for low $N$) | `plain_jet_reconstruct` |
61+
| `JetRecoStrategy.N2Tiled` | Use tiles of radius $R$ to limit search space (works well for higher $N$) | `tiled_jet_reconstruct` |
62+
63+
Generally one can use the `jet_reconstruct` interface, shown above, as the *Best* strategy safely as the overhead is extremely low. That interface supports a `strategy` option to switch to a different option.
64+
65+
Another option, if one wishes to use a specific strategy, is to call that strategy's interface directly, e.g.,
66+
67+
```julia
68+
# N2Plain
69+
plain_jet_reconstruct(particles::Vector{T}; p = -1, R = 1.0, recombine = +)
70+
```
4371

44-
Note that the `N2Plain` algorithm is usually faster at low densities, $\lessapprox 50$ input particles, otherwise the tiled algorithm is faster.
72+
Note that there is no `strategy` option in these interfaces.
4573

4674
### Example
4775

examples/jetreco.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ end
5959
"""
6060
Top level call funtion for demonstrating the use of jet reconstruction
6161
62-
This uses the "generic_jet_reconstruct" wrapper, so algorithm swutching
62+
This uses the "jet_reconstruct" wrapper, so algorithm switching
6363
happens inside the JetReconstruction package itself.
6464
6565
Some other ustilities are also supported here, such as profiling and
@@ -88,19 +88,19 @@ function jet_process(
8888
if nsamples > 1 || !isnothing(profile)
8989
@info "Doing initial warm-up run"
9090
for event in events
91-
_ = inclusive_jets(generic_jet_reconstruct(event, R = distance, p = power, strategy = strategy), ptmin)
91+
_ = inclusive_jets(jet_reconstruct(event, R = distance, p = power, strategy = strategy), ptmin)
9292
end
9393
end
9494

9595
if !isnothing(profile)
96-
profile_code(profile, generic_jet_reconstruct, events, nsamples, R = distance, p = power, strategy = strategy)
96+
profile_code(profile, jet_reconstruct, events, nsamples, R = distance, p = power, strategy = strategy)
9797
return nothing
9898
end
9999

100100
if alloc
101101
println("Memory allocation statistics:")
102102
@timev for event in events
103-
_ = inclusive_jets(generic_jet_reconstruct(event, R = distance, p = power, strategy = strategy), ptmin)
103+
_ = inclusive_jets(jet_reconstruct(event, R = distance, p = power, strategy = strategy), ptmin)
104104
end
105105
return nothing
106106
end
@@ -114,7 +114,7 @@ function jet_process(
114114
gcoff && GC.enable(false)
115115
t_start = time_ns()
116116
for (ievt, event) in enumerate(events)
117-
finaljets = inclusive_jets(generic_jet_reconstruct(event, R = distance, p = power, strategy = strategy), ptmin)
117+
finaljets = inclusive_jets(jet_reconstruct(event, R = distance, p = power, strategy = strategy), ptmin)
118118
# Only print the jet content once
119119
if irun == 1
120120
@info begin

src/ClusterSequence.jl

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,25 +76,6 @@ struct ClusterSequence
7676
Qtot
7777
end
7878

79-
"""Return all inclusive jets of a ClusterSequence with pt > ptmin"""
80-
function inclusive_jets(clusterseq::ClusterSequence, ptmin = 0.0)
81-
dcut = ptmin * ptmin
82-
jets_local = Vector{LorentzVectorCyl}(undef, 0)
83-
# sizehint!(jets_local, length(clusterseq.jets))
84-
# For inclusive jets with a plugin algorithm, we make no
85-
# assumptions about anything (relation of dij to momenta,
86-
# ordering of the dij, etc.)
87-
# for elt in Iterators.reverse(clusterseq.history)
88-
for elt in clusterseq.history
89-
elt.parent2 == BeamJet || continue
90-
iparent_jet = clusterseq.history[elt.parent1].jetp_index
91-
jet = clusterseq.jets[iparent_jet]
92-
if pt2(jet) >= dcut
93-
push!(jets_local, LorentzVectorCyl(pt(jet), rapidity(jet), phi(jet), mass(jet)))
94-
end
95-
end
96-
jets_local
97-
end
9879

9980
"""Add a new jet's history into the recombination sequence"""
10081
add_step_to_history!(clusterseq::ClusterSequence, parent1, parent2, jetp_index, dij) = begin
@@ -133,3 +114,24 @@ add_step_to_history!(clusterseq::ClusterSequence, parent1, parent2, jetp_index,
133114
clusterseq.jets[jetp_index]._cluster_hist_index = local_step
134115
end
135116
end
117+
118+
"""Return all inclusive jets of a ClusterSequence with pt > ptmin"""
119+
function inclusive_jets(clusterseq::ClusterSequence, ptmin = 0.0)
120+
dcut = ptmin * ptmin
121+
jets_local = Vector{LorentzVectorCyl}(undef, 0)
122+
# sizehint!(jets_local, length(clusterseq.jets))
123+
# For inclusive jets with a plugin algorithm, we make no
124+
# assumptions about anything (relation of dij to momenta,
125+
# ordering of the dij, etc.)
126+
# for elt in Iterators.reverse(clusterseq.history)
127+
for elt in clusterseq.history
128+
elt.parent2 == BeamJet || continue
129+
iparent_jet = clusterseq.history[elt.parent1].jetp_index
130+
jet = clusterseq.jets[iparent_jet]
131+
if pt2(jet) >= dcut
132+
push!(jets_local, LorentzVectorCyl(pt(jet), rapidity(jet), phi(jet), mass(jet)))
133+
end
134+
end
135+
jets_local
136+
end
137+

src/GenericAlgo.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# switch based on the strategy, or based on the event density
33
# if the "Best" strategy is to be employed
44

5-
function generic_jet_reconstruct(particles; p = -1, R = 1.0, recombine = +, strategy = JetRecoStrategy.Best)
5+
function jet_reconstruct(particles; p = -1, R = 1.0, recombine = +, strategy = JetRecoStrategy.Best)
66
# Either map to the fixed algorithm corresponding to the strategy
77
# or to an optimal choice based on the density of initial particles
88

src/JetReconstruction.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export tiled_jet_reconstruct
4848

4949
## Generic algorithm, which can switch strategy dynamically
5050
include("GenericAlgo.jl")
51-
export generic_jet_reconstruct
51+
export jet_reconstruct
5252

5353
# Simple HepMC3 reader
5454
include("HepMC3.jl")

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ function do_test_compare_to_fastjet(strategy::JetRecoStrategy.Strategy, fastjet_
9191
elseif (strategy == JetRecoStrategy.N2Tiled)
9292
jet_reconstruction = tiled_jet_reconstruct
9393
strategy_name = "N2Tiled"
94+
elseif (strategy == JetRecoStrategy.Best)
95+
jet_reconstruction = jet_reconstruct
96+
strategy_name = "Best"
9497
else
9598
throw(ErrorException("Strategy not yet implemented"))
9699
end

0 commit comments

Comments
 (0)