Skip to content

Commit 7813ed5

Browse files
committed
Add test for cluster_detector_hits
1 parent 4f2e3e4 commit 7813ed5

File tree

2 files changed

+39
-21
lines changed

2 files changed

+39
-21
lines changed

src/ChargeClustering/ChargeClustering.jl

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
# # This file is a part of SolidStateDetectors.jl, licensed under the MIT License (MIT).
22

3-
# breaking changes in Clustering v0.14 -> v0.15
4-
@inline _get_clusters(clusters::Clustering.DbscanResult) = clusters.clusters
5-
@inline _get_clusters(clusters::Vector{Clustering.DbscanCluster}) = clusters
6-
73
function cluster_detector_hits(
8-
detno::AbstractVector{<:Integer},
9-
edep::AbstractVector{TT},
10-
pos::AbstractVector{<:StaticVector{3,PT}},
11-
cluster_radius::RealQuantity
12-
) where {TT<:RealQuantity, PT <: RealQuantity}
13-
Table = TypedTables.Table
14-
unsorted = Table(detno = detno, edep = edep, pos = pos)
4+
detno::AbstractVector{<:Integer},
5+
edep::AbstractVector{TT},
6+
pos::AbstractVector{<:Union{<:StaticVector{3,PT}, <:CartesianPoint{PT}}},
7+
cluster_radius::RealQuantity
8+
) where {TT <: RealQuantity, PT <: RealQuantity}
9+
10+
unsorted = TypedTables.Table(detno = detno, edep = edep, pos = pos)
1511
sorting_idxs = sortperm(unsorted.detno)
1612
sorted = unsorted[sorting_idxs]
17-
grouped = Table(consgroupedview(sorted.detno, TypedTables.columns(sorted)))
13+
grouped = TypedTables.Table(consgroupedview(sorted.detno, TypedTables.columns(sorted)))
1814

1915
r_detno = similar(detno, 0)
2016
r_edep = similar(edep, 0)
@@ -24,25 +20,26 @@ function cluster_detector_hits(
2420
ustripped_cradius = ustrip(posunit, cluster_radius)
2521

2622
for d_hits_nt in grouped
27-
d_hits = Table(d_hits_nt)
23+
d_hits = TypedTables.Table(d_hits_nt)
2824
d_detno = first(d_hits.detno)
2925
@assert all(isequal(d_detno), d_hits.detno)
3026
if length(d_hits) > 3
31-
clusters = Clustering.dbscan(ustrip.(flatview(d_hits.pos)), ustripped_cradius, leafsize = 20, min_neighbors = 1, min_cluster_size = 1)
32-
for c in _get_clusters(clusters)
27+
28+
clusters = Clustering.dbscan(hcat((ustrip.(getindex.(d_hits.pos,i)) for i in 1:3)...)',
29+
ustripped_cradius, leafsize = 20, min_neighbors = 1, min_cluster_size = 1).clusters
30+
for c in clusters
3331
idxs = vcat(c.boundary_indices, c.core_indices)
3432
@assert length(idxs) == c.size
3533
c_hits = view(d_hits, idxs)
3634

3735
push!(r_detno, d_detno)
38-
esum_u = sum(c_hits.edep)
39-
push!(r_edep, esum_u)
40-
esum = ustrip(esum_u)
41-
if esum 0
36+
esum = sum(c_hits.edep)
37+
push!(r_edep, esum)
38+
if esum zero(TT)
4239
push!(r_pos, barycenter(c_hits.pos))
4340
else
44-
weights = ustrip.(c_hits.edep) .* inv(esum)
45-
push!(r_pos, barycenter(c_hits.pos, weights))
41+
weights = ustrip.(Unitful.NoUnits, c_hits.edep .* inv(esum))
42+
push!(r_pos, barycenter(c_hits.pos, StatsBase.Weights(weights)))
4643
end
4744
end
4845
else

test/test_geant4.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
using Test
44

55
using SolidStateDetectors
6+
using ArraysOfArrays
67
using RadiationDetectorSignals
8+
using StaticArrays
79
using TypedTables
810
using Unitful
911

@@ -66,11 +68,30 @@ end
6668
@test evts isa Table
6769
@test length(evts) == 100
6870

71+
# Cluster events by radius
72+
clustered_evts = @test_nowarn SolidStateDetectors.cluster_detector_hits(evts, 10u"µm")
73+
@test length(clustered_evts) == length(evts)
74+
@test length(flatview(clustered_evts.pos)) <= length(flatview(evts.pos))
75+
@test eltype(first(clustered_evts.pos)) <: CartesianPoint
76+
6977
# Generate waveforms
7078
simulate!(sim, refinement_limits = [0.2,0.1,0.05,0.03,0.02])
7179
wf = simulate_waveforms(evts, sim, Δt = 1u"ns", max_nsteps = 2000)
7280
@test wf isa Table
7381
@test :waveform in columnnames(wf)
7482
@test length(wf) == length(evts) * sum(.!ismissing.(sim.weighting_potentials))
7583

84+
# Try the same method using StaticVectors as eltype of pos
85+
evts_static = Table(evts; pos = VectorOfVectors(broadcast.(p -> SVector{3}(p.x, p.y, p.z), evts.pos)))
86+
clustered_evts_static = @test_nowarn SolidStateDetectors.cluster_detector_hits(evts_static, 10u"µm")
87+
@test length(clustered_evts_static) == length(evts_static)
88+
@test length(flatview(clustered_evts_static.pos)) <= length(flatview(evts_static.pos))
89+
@test eltype(first(clustered_evts_static.pos)) <: StaticVector{3}
90+
91+
# Generate waveforms using StaticVectors as eltype of pos
92+
wf_static = simulate_waveforms(evts_static, sim, Δt = 1u"ns", max_nsteps = 2000)
93+
@test wf_static isa Table
94+
@test :waveform in columnnames(wf_static)
95+
@test length(wf_static) == length(evts_static) * sum(.!ismissing.(sim.weighting_potentials))
96+
7697
end

0 commit comments

Comments
 (0)