@@ -45,36 +45,27 @@ Base.@propagate_inbounds function valencia_distance(eereco, i, j, R)
4545end
4646
4747"""
48- valencia_beam_distance(eereco, i, γ) -> Float64
48+ valencia_beam_distance(eereco, i, γ, β ) -> Float64
4949
50- Calculate the Valencia beam distance for jet `i` using the formula
51- ``E_i^{2β} * sin(θ_i)^{2γ}``, where `sin(θ_i) = pt / sqrt(pt^2 + pz^2)`.
52- This matches the FastJet contrib::ValenciaPlugin implementation.
50+ Calculate the Valencia beam distance for jet `i` using the FastJet ValenciaPlugin
51+ definition: ``d_iB = E_i^{2β} * (sin θ_i)^{2γ}``, where ``cos θ_i = nz``
52+ for unit direction cosines. Since ``sin^2 θ = 1 - nz^2``, we implement
53+ ``d_iB = E_i^{2β} * (1 - nz^2)^γ``.
5354
5455# Arguments
5556- `eereco`: The array of `EERecoJet` objects.
5657- `i`: The jet index.
5758- `γ`: The angular exponent parameter used in the Valencia beam distance.
59+ - `β`: The energy exponent (same as `p` in our implementation).
5860
5961# Returns
6062- `Float64`: The Valencia beam distance for jet `i`.
61-
62- # Details
63- The Valencia beam distance is used in the Valencia jet algorithm for e⁺e⁻ collisions.
64- It generalizes the beam distance by including an angular exponent γ, allowing for
65- flexible jet finding. The formula is:
66-
67- d_beam = E_i^{2β} * [pt / sqrt(pt^2 + pz^2)]^{2γ}
68-
69- where β is the energy exponent (typically set via the algorithm parameters).
7063"""
7164@inline function valencia_beam_distance (eereco, i, γ, β)
72- # Since nx, ny, nz are normalized direction vectors (px/E, py/E, pz/E),
73- # sin(θ) = pt/sqrt(pt^2 + pz^2) = sqrt(nx^2 + ny^2)
74- nx = eereco[i]. nx
75- ny = eereco[i]. ny
76- sin_theta = sqrt (nx^ 2 + ny^ 2 )
77- @inbounds eereco[i]. E2p * sin_theta^ (2 γ)
65+ nz = @inbounds eereco[i]. nz
66+ # sin^2(theta) = 1 - nz^2; beam distance independent of R
67+ sin2 = 1 - nz * nz
68+ @inbounds eereco[i]. E2p * sin2^ γ
7869end
7970
8071"""
10899function get_angular_nearest_neighbours! (eereco, algorithm, dij_factor, p, γ = 1.0 , R = 4.0 )
109100 # Get the initial nearest neighbours for each jet
110101 N = length (eereco)
111- # this_dist_vector = Vector{Float64}(undef, N)
112- # Nearest neighbour geometric distance
102+ # For Valencia, nearest-neighbour must be chosen on the full dij metric (FastJet NNH behaviour)
103+ if algorithm == JetAlgorithm. Valencia
104+ @inbounds for i in 1 : N
105+ eereco. nndist[i] = Inf
106+ eereco. nni[i] = i
107+ end
108+ end
109+ # Nearest neighbour search
113110 @inbounds for i in 1 : N
114- # TODO : Replace the 'j' loop with a vectorised operation over the appropriate array elements?
115- # this_dist_vector .= 1.0 .- eereco.nx[i:N] .* eereco[i + 1:end].nx .-
116- # eereco[i].ny .* eereco[i + 1:end].ny .- eereco[i].nz .* eereco[i + 1:end].nz
117- # The problem here will be avoiding allocations for the array outputs, which would easily
118- # kill performance
119111 @inbounds for j in (i + 1 ): N
120- # Always use angular distance for nearest neighbor search
121- this_nndist = angular_distance (eereco, i, j)
112+ # Metric used to pick the nearest neighbour
113+ this_metric = algorithm == JetAlgorithm. Valencia ?
114+ valencia_distance (eereco, i, j, R) :
115+ angular_distance (eereco, i, j)
122116
123117 # Using these ternary operators is faster than the if-else block
124- better_nndist_i = this_nndist < eereco[i]. nndist
125- eereco. nndist[i] = better_nndist_i ? this_nndist : eereco. nndist[i]
118+ better_nndist_i = this_metric < eereco[i]. nndist
119+ eereco. nndist[i] = better_nndist_i ? this_metric : eereco. nndist[i]
126120 eereco. nni[i] = better_nndist_i ? j : eereco. nni[i]
127- better_nndist_j = this_nndist < eereco[j]. nndist
128- eereco. nndist[j] = better_nndist_j ? this_nndist : eereco. nndist[j]
121+ better_nndist_j = this_metric < eereco[j]. nndist
122+ eereco. nndist[j] = better_nndist_j ? this_metric : eereco. nndist[j]
129123 eereco. nni[j] = better_nndist_j ? i : eereco. nni[j]
130124 end
131125 end
@@ -157,14 +151,16 @@ end
157151
158152# Update the nearest neighbour for jet i, w.r.t. all other active jets
159153function update_nn_no_cross! (eereco, i, N, algorithm, dij_factor, β = 1.0 , γ = 1.0 , R = 4.0 )
160- eereco. nndist[i] = large_distance
154+ eereco. nndist[i] = algorithm == JetAlgorithm . Valencia ? Inf : large_distance
161155 eereco. nni[i] = i
162156 @inbounds for j in 1 : N
163157 if j != i
164- # Always use angular distance for nearest neighbor search
165- this_nndist = angular_distance (eereco, i, j)
166- better_nndist_i = this_nndist < eereco[i]. nndist
167- eereco. nndist[i] = better_nndist_i ? this_nndist : eereco. nndist[i]
158+ # Metric for nearest neighbour selection
159+ this_metric = algorithm == JetAlgorithm. Valencia ?
160+ valencia_distance (eereco, i, j, R) :
161+ angular_distance (eereco, i, j)
162+ better_nndist_i = this_metric < eereco[i]. nndist
163+ eereco. nndist[i] = better_nndist_i ? this_metric : eereco. nndist[i]
168164 eereco. nni[i] = better_nndist_i ? j : eereco. nni[i]
169165 end
170166 end
@@ -188,17 +184,19 @@ end
188184function update_nn_cross! (eereco, i, N, algorithm, dij_factor, β = 1.0 , γ = 1.0 , R = 4.0 )
189185 # Update the nearest neighbour for jet i, w.r.t. all other active jets
190186 # also doing the cross check for the other jet
191- eereco. nndist[i] = large_distance
187+ eereco. nndist[i] = algorithm == JetAlgorithm . Valencia ? Inf : large_distance
192188 eereco. nni[i] = i
193189 @inbounds for j in 1 : N
194190 if j != i
195- # Always use angular distance for nearest neighbor search
196- this_nndist = angular_distance (eereco, i, j)
197- better_nndist_i = this_nndist < eereco[i]. nndist
198- eereco. nndist[i] = better_nndist_i ? this_nndist : eereco. nndist[i]
191+ # Metric for nearest neighbour selection
192+ this_metric = algorithm == JetAlgorithm. Valencia ?
193+ valencia_distance (eereco, i, j, R) :
194+ angular_distance (eereco, i, j)
195+ better_nndist_i = this_metric < eereco[i]. nndist
196+ eereco. nndist[i] = better_nndist_i ? this_metric : eereco. nndist[i]
199197 eereco. nni[i] = better_nndist_i ? j : eereco. nni[i]
200- if this_nndist < eereco[j]. nndist
201- eereco. nndist[j] = this_nndist
198+ if this_metric < eereco[j]. nndist
199+ eereco. nndist[j] = this_metric
202200 eereco. nni[j] = i
203201 # j will not be revisited, so update metric distance here
204202 if algorithm == JetAlgorithm. Valencia
0 commit comments