diff --git a/src/Substructure.jl b/src/Substructure.jl index 58eb0c0..cd84de9 100644 --- a/src/Substructure.jl +++ b/src/Substructure.jl @@ -1,17 +1,39 @@ -# function to see if a jet has parent jets -function has_parents(jet, history) +""" + has_parents(p, history) -> (boolean, Int64, Int64) + +Checks if the jet `p` is a child of two other jets, after clustering + +# Arguments +- `p`: The jet to check. +- `history`: The vector of history element obtained from the cluster sequence after clustering. + +# Returns +- (boolean, Int64, Int64): true or false depending on if the jet has a parent or not. If the jet has a parent, returns the indices of the parent jets in the history element. Otherwise, returns -2 (NonexistentParent). +""" +function has_parents(p::PseudoJet, history::Vector{HistoryElement}) - N = jet._cluster_hist_index + N = p._cluster_hist_index p1 = history[N].parent1 p2 = history[N].parent2 p1 == p2 == NonexistentParent ? result = false : result = true - return result, p1, p2 + return (result, p1, p2) end -# Function to calculate ΔR -function delta_R(jet1, jet2) +""" + delta_R(jet1, jet2) -> Float64 + +Function to calculate the distance in the y-ϕ plane between two jets `jet1` and `jet2` + +# Arguments +- `jet1`: The first jet. +- `jet2`: The second jet. + +# Returns +- Float64: The Euclidean distance in the y-ϕ plane for the two jets. +""" +function delta_R(jet1::PseudoJet, jet2::PseudoJet) eta1, phi1 = rapidity(jet1), phi(jet1) eta2, phi2 = rapidity(jet2), phi(jet2) @@ -33,7 +55,20 @@ function kt_distance(jet1::PseudoJet, jet2::PseudoJet, R = 1) return min(p1, p2) * (d_R^2 / R^2) end; -# Function to recluster the constituents of a jet in a different method +""" + recluster(jet, clusterseq, rad, mtd) -> ClusterSequence + +Reclusters the constituents of a given jet `jet` with a different clustering method `mtd` and different jet radius `rad`. + +# Arguments +- `jet`: The jet whose constituents are to be reclustered. +- `clusterseq`: The cluster sequence from which the original jet is obtained. +- `rad`: The new jet radius. +- `mtd`: The new clustering method. + +# Returns +- ClusterSequence: The new cluster sequence. +""" function recluster(jet::PseudoJet, clusterseq::ClusterSequence, rad = 1.0, mtd = 0) cons = constituents(jet, clusterseq) new_clusterseq = jet_reconstruct(cons; p = mtd, R = rad, strategy = RecoStrategy.N2Plain) @@ -58,28 +93,83 @@ function join(jets::Vector{PseudoJet}) end # Defining suitable structures to be used for jet grooming and tagging +""" + struct MassDropTagger -struct MassDropTagger +Used for tagging jets that undergo mass drop, a common technique in jet substructure. + +Fields: +- mu: Maximum allowed mass ratio for a jet to pass tagging +- y: Minimum kT distance threshold for parent separation +""" + +mutable struct MassDropTagger mu::Float64 y::Float64 end -struct SoftDropTagger +""" + struct SoftDropTagger + +Applies a soft-drop condition on jets, trimming away soft, wide-angle radiation. + +Fields: +- zcut: Minimum allowed energy fraction for subjets +- b: Angular exponent controlling soft radiation suppression +""" + +mutable struct SoftDropTagger zcut::Float64 b::Float64 end -struct Filter +""" + struct Filter + +Filters jets based on radius and number of hardest subjets, reducing contamination. + +Fields: +- filterRadius: Radius parameter to recluster subjets +- numHardestJets: Number of hardest jets to retain in the filtered result +""" + +mutable struct Filter filterRadius::Float64 numHardestJets::Int end -struct Trim +""" + struct Trim + +Trims soft, large-angle components from jets based on fraction and radius. + +Fields: +- trimRadius: Radius used for reclustering in trimming +- trimFraction: Minimum momentum fraction for retained subjets +- reclusterMethod: Method identifier for reclustering +""" + +mutable struct Trim trimRadius::Float64 trimFraction::Float64 reclusterMethod::Int end +""" + massDrop(jet, clusterseq, tag) -> PseudoJet + +Identifies subjets in a jet that pass the mass drop tagging condition. +The method stops at the first jet satisfying the mass and distance thresholds. + +Arguments: +- jet: PseudoJet instance representing the jet to tag +- clusterseq: ClusterSequence with jet clustering history +- tag: MassDropTagger instance providing mass drop parameters + +Returns: +- PseudoJet: The jet (or subjet) satisfying the mass drop conditions, if tagging is successful, otherwise a zero-momentum PseudoJet +""" + function massDrop(jet::PseudoJet, clusterseq::ClusterSequence, tag::MassDropTagger) allJets = clusterseq.jets hist = clusterseq.history @@ -110,6 +200,22 @@ function massDrop(jet::PseudoJet, clusterseq::ClusterSequence, tag::MassDropTagg end +""" + softDrop(jet, clusterseq, rad, tag) -> PseudoJet + +Applies soft-drop grooming to remove soft, wide-angle radiation from jets. +This function reclusters the jet and iteratively checks the soft-drop condition on subjets. + +Arguments: +- jet: PseudoJet instance to groom +- clusterseq: ClusterSequence containing jet history +- rad: Radius parameter for reclustering +- tag: SoftDropTagger instance with soft-drop parameters + +Returns: +- PseudoJet: Groomed jet or zero-momentum PseudoJet if grooming fails +""" + function softDrop(jet::PseudoJet, clusterseq::ClusterSequence, rad::Float64, tag::SoftDropTagger) new_clusterseq = recluster(jet, clusterseq, rad, 0) new_jet = inclusive_jets(new_clusterseq; T = PseudoJet)[1] @@ -146,6 +252,20 @@ function softDrop(jet::PseudoJet, clusterseq::ClusterSequence, rad::Float64, tag end +""" + jetFilter(jet, clusterseq, filter) -> PseudoJet + +Filters a jet to retain only the hardest subjets based on a specified radius and number. + +Arguments: +- jet: PseudoJet instance representing the jet to filter +- clusterseq: ClusterSequence containing jet history +- filter: Filter instance specifying radius and number of subjets + +Returns: +- PseudoJet: Filtered jet composed of the hardest subjets + +""" function jetFilter(jet::PseudoJet, clusterseq::ClusterSequence, filter::Filter) rad = filter.filterRadius; new_clusterseq = recluster(jet, clusterseq, rad, 0) @@ -159,6 +279,20 @@ function jetFilter(jet::PseudoJet, clusterseq::ClusterSequence, filter::Filter) filtered end +""" + jetTrim(jet, clusterseq, trim) -> PseudoJet + +Trims a jet by removing subjets with transverse momentum below a specified fraction. + +Arguments: +- jet: PseudoJet instance representing the jet to trim +- clusterseq: ClusterSequence containing jet history +- trim: Trim instance specifying trimming parameters + +Returns: +- PseudoJet: Trimmed jet composed of retained subjets +""" + function jetTrim(jet::PseudoJet, clusterseq::ClusterSequence, trim::Trim) rad = trim.trimRadius; mtd = trim.reclusterMethod